Merge branch 'agents/dotnet-aspire-opentelemetry-explorer'

This commit is contained in:
David Kaya
2026-04-16 11:57:06 +02:00
5 changed files with 24 additions and 6 deletions
@@ -14,7 +14,7 @@ internal static class OpenTelemetrySetup
private static readonly string[] ActivitySourceNames = private static readonly string[] ActivitySourceNames =
[ [
"Microsoft.Agents.AI", "Experimental.Microsoft.Agents.AI",
"Microsoft.Agents.AI.Workflows", "Microsoft.Agents.AI.Workflows",
]; ];
@@ -87,8 +87,13 @@ internal sealed class CopilotAgentBundle : ProviderAgentBundle
name: definition.GetAgentName(), name: definition.GetAgentName(),
description: NormalizeOptionalString(definition.Config.Description)); description: NormalizeOptionalString(definition.Config.Description));
agents.Add(agent); AIAgent instrumentedAgent = new AIAgentBuilder(agent).UseOpenTelemetry().Build();
agents.Add(instrumentedAgent);
disposables.Add(agent); disposables.Add(agent);
if (instrumentedAgent is IDisposable instrumentedDisposable)
{
disposables.Add(new SyncDisposableAdapter(instrumentedDisposable));
}
} }
// The bundle owns the shared client — disposed after all agents. // The bundle owns the shared client — disposed after all agents.
@@ -328,4 +333,17 @@ internal sealed class CopilotAgentBundle : ProviderAgentBundle
{ {
return string.IsNullOrWhiteSpace(value) ? null : value.Trim(); return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
} }
/// <summary>
/// Adapts a synchronous <see cref="IDisposable"/> to <see cref="IAsyncDisposable"/>
/// so it can be tracked in the async disposal pipeline.
/// </summary>
private sealed class SyncDisposableAdapter(IDisposable inner) : IAsyncDisposable
{
public ValueTask DisposeAsync()
{
inner.Dispose();
return ValueTask.CompletedTask;
}
}
} }
@@ -112,7 +112,7 @@ internal sealed class WorkflowRunner
builder = builder.WithName(workflowDefinition.Name); builder = builder.WithName(workflowDefinition.Name);
} }
return builder.WithOutputFrom(routes[endNode.Id].Exit).Build(); return builder.WithOutputFrom(routes[endNode.Id].Exit).WithOpenTelemetry().Build();
} }
private WorkflowNodeRoute CreateNodeRoute( private WorkflowNodeRoute CreateNodeRoute(
@@ -27,7 +27,7 @@ public sealed class OpenTelemetrySetupTests
Assert.Equal(OtlpExportProtocol.Grpc, configuration.Protocol); Assert.Equal(OtlpExportProtocol.Grpc, configuration.Protocol);
Assert.Collection( Assert.Collection(
configuration.ActivitySourceNames, configuration.ActivitySourceNames,
source => Assert.Equal("Microsoft.Agents.AI", source), source => Assert.Equal("Experimental.Microsoft.Agents.AI", source),
source => Assert.Equal("Microsoft.Agents.AI.Workflows", source)); source => Assert.Equal("Microsoft.Agents.AI.Workflows", source));
} }
+2 -2
View File
@@ -614,8 +614,8 @@ function TelemetrySection({
placeholder={DEFAULT_OTEL_ENDPOINT} placeholder={DEFAULT_OTEL_ENDPOINT}
/> />
<p className="mt-1.5 text-[11px] text-[var(--color-text-muted)]"> <p className="mt-1.5 text-[11px] text-[var(--color-text-muted)]">
Use <span className="font-mono">bun run aspire</span> to launch the Aspire Dashboard locally at this default endpoint. The URL of any OTLP-compatible collector (e.g. Jaeger, Aspire Dashboard, Grafana Alloy).
Changes take effect on the next sidecar session. Changes take effect on the next session.
</p> </p>
</div> </div>
</div> </div>