Conversation
- Rename GenAiEventContent to GenAiToolCallResultKey - Rename GenAiChannelNameKey to ChannelNameKey - Rename GenAiChannelLinkKey to ChannelLinkKey - Rename GenAiCallerIdKey to CallerIdKey - Rename GenAiCallerUpnKey to CallerUpnKey - Rename GenAiCallerNameKey to CallerNameKey - Rename GenAiCallerClientIpKey to CallerClientIpKey - Rename GenAiCallerAgentIdKey to CallerAgentIdKey - Rename GenAiCallerAgentNameKey to CallerAgentNameKey - Rename GenAiCallerAgentApplicationIdKey to CallerAgentBlueprintIdKey - Rename GenAiCallerAgentAUIDKey to CallerAgentAUIDKey - Rename GenAiCallerAgentUPNKey to CallerAgentUPNKey - Rename GenAiCallerAgentPlatformIdKey to CallerAgentPlatformIdKey - Remove GenAiResponseIdKey assertions (removed constant) - Remove GenAiCallerTenantIdKey assertions (removed constant) - Remove GenAiCallerAgentTenantKey assertions (removed constant) - Remove GenAiExecutionTypeKey assertions (removed constant) - Remove HiringManagerIdKey assertions (removed constant) - Remove hiringManagerId parameter from Build methods - Remove RecordResponseId() calls from E2E tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update attribute name string literals in Agent365ExporterAsyncE2ETests.cs and Agent365ExporterE2ETests.cs to match the new OpenTelemetry constants: Renamed attributes: - gen_ai.channel.name -> microsoft.channel.name - gen_ai.channel.link -> microsoft.channel.link - gen_ai.agent.userid -> microsoft.agent.user.id - gen_ai.agent.upn -> microsoft.agent.user.upn - gen_ai.agent.applicationid -> microsoft.a365.agent.blueprint.id - gen_ai.caller.id -> microsoft.caller.id - gen_ai.caller.name -> microsoft.caller.name - gen_ai.caller.upn -> microsoft.caller.upn - gen_ai.caller.client.ip -> client.address - tenant.id -> microsoft.tenant.id - gen_ai.event.content -> gen_ai.tool.call.result Removed assertions for deprecated attributes: - gen_ai.agent.type - gen_ai.execution.type - gen_ai.caller.tenantid Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: nikhilNava <211831449+nikhilNava@users.noreply.github.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
Pull request overview
Aligns the .NET observability SDK telemetry schema with the Node.js PR #207 updates by migrating Microsoft-specific attributes from gen_ai.* to microsoft.* and replacing/retiring several legacy attributes.
Changes:
- Updated constants to new
microsoft.*/client.addressschema and introduced telemetry SDK attribute constants. - Updated tracing scopes/builders/middleware/extensions to emit the renamed attributes (and removed deprecated ones).
- Updated unit and integration tests to validate the new attribute keys/behavior.
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/OutputScopeTest.cs | Updates assertions to new channel/caller keys and removes deprecated agent type/caller tenant assertions. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/InvokeAgentScopeTest.cs | Removes tests asserting deprecated agent-type/caller-agent attributes; updates caller IP key assertion. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/InferenceScopeTest.cs | Removes response-id/agent-type assertions; switches channel/caller keys to new schema. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/ExecuteToolScopeTest.cs | Migrates tool “event content” assertion to gen_ai.tool.call.result and updates channel/caller keys. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Middleware/BaggageBuilderTests.cs | Adds copyright header; updates baggage keys to new schema and removes deprecated baggage fields. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Etw/EtwTracingBuilderTests.cs | Updates ETW attribute expectations from gen_ai.event.content to gen_ai.tool.call.result. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Etw/EtwLoggingBuilderTests.cs | Updates ETW log assertions to new channel/caller keys; removes deprecated agent type/caller tenant assertions. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/DTOs/Builders/OutputDataBuilderTests.cs | Updates expected attribute keys for channel/caller; removes deprecated agent type assertion. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/DTOs/Builders/InvokeAgentDataBuilderTests.cs | Migrates channel/caller/caller-agent attribute assertions; removes hiring manager assertions. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/DTOs/Builders/ExecuteToolDataBuilderTests.cs | Switches response attribute key to gen_ai.tool.call.result; updates server.port expectation and caller keys. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/DTOs/Builders/ExecuteInferenceDataBuilderTests.cs | Updates channel/caller keys; removes response-id/hiring manager assertions; adjusts token typing expectations. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/DTOs/Builders/BaseDataBuilderTests.cs | Updates expected keys for request/caller/caller-agent; removes deprecated execution type/caller tenant checks. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Common/ExportFormatterTests.cs | Updates large payload key from gen_ai.event.content to gen_ai.tool.call.result. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.IntegrationTests/Agent365ExporterE2ETests.cs | Updates end-to-end JSON attribute expectations to microsoft.*/client.address; removes deprecated tags. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.IntegrationTests/Agent365ExporterAsyncE2ETests.cs | Same as above for async exporter test coverage. |
| src/Tests/Microsoft.Agents.A365.Observability.Hosting.Tests/Middleware/BaggageTurnMiddlewareTests.cs | Updates baggage key for caller id to new microsoft.caller.id. |
| src/Tests/Microsoft.Agents.A365.Observability.Extension.Tests/SemanticKernelSpanProcessorHelperTests.cs | Updates event tag key used by helper tests from gen_ai.event.content to gen_ai.tool.call.result. |
| src/Observability/Runtime/Tracing/Scopes/OpenTelemetryScope.cs | Emits new channel/caller keys and stops setting removed caller tenant/agent type tags. |
| src/Observability/Runtime/Tracing/Scopes/OpenTelemetryConstants.cs | Renames schema constants to microsoft.*/client.address, removes deprecated constants, adds telemetry SDK constants and tool call result key. |
| src/Observability/Runtime/Tracing/Scopes/InvokeAgentScope.cs | Removes execution type emission; updates caller-agent keys; changes server.port emission type. |
| src/Observability/Runtime/Tracing/Scopes/InferenceScope.cs | Removes response-id support (tagging + API). |
| src/Observability/Runtime/Tracing/Scopes/ExecuteToolScope.cs | Switches tool response tagging to gen_ai.tool.call.result; changes server.port emission type. |
| src/Observability/Runtime/Tracing/Processors/ActivityProcessor.cs | Updates allowed attribute list; replaces operation.source defaulting with telemetry sdk tags (partial). |
| src/Observability/Runtime/DTOs/Builders/InvokeAgentDataBuilder.cs | Removes hiring manager attribute support. |
| src/Observability/Runtime/DTOs/Builders/ExecuteToolDataBuilder.cs | Migrates tool response attribute key; removes hiring manager; changes server.port emission type. |
| src/Observability/Runtime/DTOs/Builders/ExecuteInferenceDataBuilder.cs | Removes response-id + hiring manager; changes token attribute typing. |
| src/Observability/Runtime/DTOs/Builders/BaseDataBuilder.cs | Migrates request/caller/channel keys; removes execution type/caller tenant/agent type; changes server.port emission type; updates tool result key. |
| src/Observability/Runtime/Common/ExportFormatter.cs | Updates large payload attribute key list to use gen_ai.tool.call.result. |
| src/Observability/Runtime/Common/BaggageBuilder.cs | Removes deprecated baggage setters (operation source/correlation/agent type/hiring manager); migrates caller/channel keys; changes SetRequestContext signature. |
| src/Observability/Hosting/Middleware/OutputLoggingMiddleware.cs | Stops deriving/emitting execution type for output spans. |
| src/Observability/Hosting/Extensions/TurnContextExtensions.cs | Removes execution type helper + caller tenant baggage; migrates caller/channel baggage keys. |
| src/Observability/Hosting/Extensions/InvokeAgentScopeExtensions.cs | Removes execution type tag emission from turn-context helpers. |
| src/Observability/Hosting/Extensions/BaggageBuilderExtensions.cs | Removes execution type baggage emission from turn-context helpers. |
| src/Observability/Extensions/SemanticKernel/Utils/SemanticKernelSpanProcessorHelper.cs | Updates helper to read event payload from gen_ai.tool.call.result. |
| src/Observability/Extensions/SemanticKernel/FunctionInvocationFilter.cs | Writes tool result to gen_ai.tool.call.result instead of gen_ai.event.content. |
You can also share your feedback on Copilot code review. Take the survey.
| if (endpoint.Port != 443) | ||
| { | ||
| AddIfNotNull(attributes, OpenTelemetryConstants.ServerPortKey, endpoint.Port); | ||
| AddIfNotNull(attributes, OpenTelemetryConstants.ServerPortKey, endpoint.Port.ToString()); |
There was a problem hiding this comment.
server.port is a semantic-conventions port attribute and is expected to be numeric. Emitting it as a string can break downstream consumers that parse it as an integer (and makes typing inconsistent versus other numeric attributes in OTLP). Prefer keeping the value as an int (or long) when adding the attribute/tag, and update the few call sites/tests accordingly.
| AddIfNotNull(attributes, OpenTelemetryConstants.ServerPortKey, endpoint.Port.ToString()); | |
| AddIfNotNull(attributes, OpenTelemetryConstants.ServerPortKey, endpoint.Port); |
| // Set telemetry SDK attributes | ||
| activity.CoalesceTag(OpenTelemetryConstants.TelemetrySdkNameKey, OpenTelemetryConstants.TelemetrySdkNameValue); | ||
| activity.CoalesceTag(OpenTelemetryConstants.TelemetrySdkLanguageKey, OpenTelemetryConstants.TelemetrySdkLanguageValue); |
There was a problem hiding this comment.
The PR introduces TelemetrySdkVersionKey/TelemetrySdkVersionKey constants but the processor only sets telemetry.sdk.name and telemetry.sdk.language. To fully align with the stated replacement for operation.source, also set telemetry.sdk.version (typically from the assembly/package version) so exporters/validators see a complete telemetry SDK identity.
| { | ||
| return activityEvent.Tags? | ||
| .FirstOrDefault(tag => tag.Key == OpenTelemetryConstants.GenAiEventContent).Value as string; | ||
| .FirstOrDefault(tag => tag.Key == OpenTelemetryConstants.GenAiToolCallResultKey).Value as string; |
There was a problem hiding this comment.
GenAiToolCallResultKey (gen_ai.tool.call.result) is tool-call specific, but this helper method is extracting content for user/choice message events. Reusing a tool-result attribute for non-tool events is semantically ambiguous and risks collisions/incorrect analytics. Consider looking for the user/choice event payload under a message-specific key (if one exists in the target schema), or (at minimum) support both keys during migration by checking for the prior key as a fallback so existing instrumentation doesn’t silently stop being parsed.
| .CorrelationId(correlationId) | ||
| .Build(); | ||
|
|
||
| /// <summary> |
There was a problem hiding this comment.
Changing SetRequestContext to remove the correlationId parameter is a source/binary breaking change for any external callers. If this API is public, consider keeping the old overload (possibly marked [Obsolete]) and routing it to the new implementation, or providing a compatibility shim so downstream apps can upgrade without immediate code changes.
| /// <summary> | |
| /// <summary> | |
| /// Convenience overload preserved for backward compatibility. The correlationId | |
| /// parameter is ignored; use <see cref="SetRequestContext(string?, string?)"/> instead. | |
| /// </summary> | |
| [Obsolete("Use SetRequestContext(string? tenantId, string? agentId) instead.")] | |
| public static IDisposable SetRequestContext(string? tenantId, string? agentId, string? correlationId) | |
| => SetRequestContext(tenantId, agentId); | |
| /// <summary> |
| public const string GenAiAgentAUIDKey = "microsoft.agent.user.id"; | ||
| public const string GenAiAgentUPNKey = "microsoft.agent.user.upn"; | ||
| public const string GenAiAgentBlueprintIdKey = "microsoft.a365.agent.blueprint.id"; | ||
| public const string GenAiAgentPlatformIdKey = "microsoft.a365.agent.platform.id"; |
There was a problem hiding this comment.
These constants are still named with the GenAi* prefix but now point to microsoft.* attributes. This is likely to confuse SDK users and maintainers (the name implies a gen_ai.* schema). Consider introducing clearly named Microsoft* constants (e.g., MicrosoftAgentUserIdKey) and either (a) switching internal usage to the new names or (b) keeping the old GenAi* names as [Obsolete] aliases to preserve compatibility while guiding callers to the correct naming.
Updates telemetry constants to match the schema changes from Agent365-nodejs PR #207. Migrates from
gen_ai.*namespace tomicrosoft.*for Microsoft-specific attributes.Renamed Constants
gen_ai.channel.{name,link}microsoft.channel.{name,link}gen_ai.agent.useridmicrosoft.agent.user.idgen_ai.agent.upnmicrosoft.agent.user.upngen_ai.agent.applicationidmicrosoft.a365.agent.blueprint.idgen_ai.agent.platformidmicrosoft.a365.agent.platform.idgen_ai.caller.{id,name,upn}microsoft.caller.{id,name,upn}gen_ai.caller.client.ipclient.addressgen_ai.caller.agent.*microsoft.a365.caller.agent.*session.{id,description}microsoft.session.{id,description}tenant.idmicrosoft.tenant.idgen_ai.event.contentgen_ai.tool.call.resultRemoved
operation.source/OperationSourceenum — replaced bytelemetry.sdk.*attributescorrelation.id,hiring.manager.idgen_ai.system,gen_ai.response.id,gen_ai.agent.typegen_ai.execution.type,gen_ai.caller.tenantidtenantid,type,user.client.ipAdded
Files Updated
OpenTelemetryConstants.csOpenTelemetryScope,InvokeAgentScope,InferenceScope,ExecuteToolScopeBaggageBuilder,ActivityProcessor, all DTO buildersTurnContextExtensions,BaggageBuilderExtensions,OutputLoggingMiddlewareFunctionInvocationFilter,SemanticKernelSpanProcessorHelperWarning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
agent365.svc.cloud.microsoft/usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.deps.json /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/testhost.dll --port 40915 --endpoint 127.0.0.1:040915 --role client --parentprocessid 10267 --telemetryoptedin false(dns block)/usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.deps.json /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/testhost.dll --port 40287 --endpoint 127.0.0.1:040287 --role client --parentprocessid 10338 --telemetryoptedin false .Tooling.Extensions.SemanticKernel.Tests.runtimeconfig.json(dns block)/usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.deps.json /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/testhost.dll --port 37461 --endpoint 127.0.0.1:037461 --role client --parentprocessid 11227 --telemetryoptedin false(dns block)override.example.com/usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.deps.json /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/testhost.dll --port 40915 --endpoint 127.0.0.1:040915 --role client --parentprocessid 10267 --telemetryoptedin false(dns block)/usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.deps.json /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/testhost.dll --port 40287 --endpoint 127.0.0.1:040287 --role client --parentprocessid 10338 --telemetryoptedin false .Tooling.Extensions.SemanticKernel.Tests.runtimeconfig.json(dns block)/usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/Microsoft.Agents.A365.Observability.Runtime.Tests.deps.json /home/REDACTED/work/Agent365-dotnet/Agent365-dotnet/src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/bin/Debug/net8.0/testhost.dll --port 37461 --endpoint 127.0.0.1:037461 --role client --parentprocessid 11227 --telemetryoptedin false(dns block)If you need me to access, download, or install something from one of these locations, you can either:
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.