Add OTel-compliant span status to ETW DTO logging path#259
Merged
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR brings the ETW DTO logging path (“Path B”) up to parity with the Activity-based path by emitting an OpenTelemetry-compliant span Status object (numeric code + message) and recording error.type when an exception is provided.
Changes:
- Introduces
SpanStatusCode,SpanStatus, andSpanStatusBuilderto centralize exception → OTel status +error.typemapping for DTO telemetry. - Threads an optional
Exception? error = nullthroughIA365EtwLogger/A365EtwLoggerand all*DataBuilder.Buildmethods, applying status ontoBaseData. - Extends DTO serialization (
BaseData.ToDictionaryandExportFormatter.FormatLogData) and adds targeted unit tests covering status emission and defaults.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/DTOs/Builders/SpanStatusBuilderTests.cs | Adds unit coverage for SpanStatusBuilder status + error.type mapping behavior. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/DTOs/Builders/InvokeAgentDataBuilderTests.cs | Validates builder behavior for unset vs error status when error is provided/omitted. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/DTOs/BaseDataTests.cs | Verifies BaseData default status values and ToDictionary() emitted shape. |
| src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Common/ExportFormatterStatusTests.cs | Ensures FormatLogData emits Status consistently (present, error, and missing-key default). |
| src/Observability/Runtime/Etw/IA365EtwLogger.cs | Extends logger interface APIs with optional error parameter and XML docs. |
| src/Observability/Runtime/Etw/A365EtwLogger.cs | Forwards optional error through ETW logger methods into DTO builders. |
| src/Observability/Runtime/DTOs/SpanStatusCode.cs | Adds OTLP-aligned numeric status code enum (Unset/Ok/Error). |
| src/Observability/Runtime/DTOs/SpanStatus.cs | Adds DTO representation of OTel status (Code + optional Message). |
| src/Observability/Runtime/DTOs/Builders/SpanStatusBuilder.cs | Implements exception → status mapping and error.type population to attributes. |
| src/Observability/Runtime/DTOs/Builders/OutputDataBuilder.cs | Threads optional error through and applies status on output DTO build. |
| src/Observability/Runtime/DTOs/Builders/InvokeAgentDataBuilder.cs | Threads optional error through and applies status on invoke-agent DTO build. |
| src/Observability/Runtime/DTOs/Builders/ExecuteToolDataBuilder.cs | Threads optional error through and applies status on execute-tool DTO build. |
| src/Observability/Runtime/DTOs/Builders/ExecuteInferenceDataBuilder.cs | Threads optional error through and applies status on inference DTO build. |
| src/Observability/Runtime/DTOs/Builders/BaseDataBuilder.cs | Adds shared ApplyStatus helper for consistent DTO status annotation. |
| src/Observability/Runtime/DTOs/Builders/ApplyGuardrailDataBuilder.cs | Threads optional error through and applies status on guardrail DTO build. |
| src/Observability/Runtime/DTOs/BaseData.cs | Adds StatusCode/StatusMessage and emits Status { code, message } in ToDictionary(). |
| src/Observability/Runtime/Common/ExportFormatter.cs | Emits Status in FormatLogData, defaulting to { code: 0, message: "" } when absent. |
| docs/superpowers/specs/2026-06-25-etw-span-status-design.md | Adds design spec for ETW DTO status, but currently contains implementation-path/type mismatches. |
| .github/copilot-instructions.md | Docs-only enhancement describing build/test commands and repo architecture conventions. |
Record span status (Unset/Error) and error.type on the ETW DTO-based telemetry path so error reporting matches the OTel semantic conventions already used by the Activity-based scope path. - Add SpanStatus struct, SpanStatusCode enum and SpanStatusBuilder (exception -> status + error.type) under DTOs, alongside the data model they describe (parallel to SpanKindConstants) - Add StatusCode/StatusMessage to BaseData and emit Status in ToDictionary - Thread optional Exception error param through all 5 data builders, A365EtwLogger and IA365EtwLogger - Emit Status in ExportFormatter.FormatLogData - Add unit tests for SpanStatusBuilder, BaseData, ExportFormatter and InvokeAgentDataBuilder status behavior Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
7380740 to
08baf09
Compare
juliomenendez
approved these changes
Jun 25, 2026
threddy
approved these changes
Jun 25, 2026
nikhilNava
added a commit
to microsoft/opentelemetry-distro-dotnet
that referenced
this pull request
Jun 26, 2026
* Add OTel-compliant span status to ETW DTO logging path
Records an OTel-spec-compliant span status (and error.type) on the ETW
DTO logging path (Path B), which previously dropped status entirely.
Brings it to parity with the Activity-based path (FormatSingle).
- New SpanStatusCode enum, SpanStatus struct, and SpanStatusBuilder
(central Exception -> status + error.type mapping, mirroring
OpenTelemetryScope.RecordError).
- BaseData: adds StatusCode/StatusMessage; ToDictionary emits Status.
- Optional Exception? error threaded through all 5 *DataBuilder.Build
methods (via shared ApplyStatus on BaseDataBuilder), A365EtwLogger,
and IA365EtwLogger.
- ExportFormatter.FormatLogData emits the Status object (defaults to
{ code: 0, message: "" } when absent).
Ports microsoft/Agent365-dotnet#259 into the distro repo.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Strip error.type on no-error path in SpanStatusBuilder
Addresses PR feedback: error.type is not part of the reserved-key filter
for extraAttributes, so a caller could pass it through and have it emitted
while status stayed Unset. FromError now removes any pre-existing error.type
attribute on the no-error path, ensuring error.type is never present without
an accompanying error status.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Nikhil Chitlur Navakiran (from Dev Box) <nikhilc@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Records an OTel-spec-compliant span status (and
error.type) on the ETW DTO logging path (Path B), which previously dropped status entirely. The Activity-based path (Path A) already emits status viaExportFormatter.FormatSingle; this brings Path B (A365EtwLogger->*DataBuilder->BaseData->ExportFormatter.FormatLogData) to parity.What changed
DTOs/) -SpanStatusCodeenum (Unset=0/Ok=1/Error=2, mapping directly onto OTLPStatus.StatusCode),SpanStatusstruct, andSpanStatusBuilder(centralException-> status +error.typemapping, mirroringOpenTelemetryScope.RecordError). Placed with the data model they describe, next toSpanKindConstants.BaseData- addsStatusCode/StatusMessage;ToDictionary()now emitsStatus { code, message }.Exception? error = nullthreaded through all 5*DataBuilder.Buildmethods (via a sharedApplyStatushelper onBaseDataBuilder), plusA365EtwLoggerandIA365EtwLogger.ExportFormatter.FormatLogData- emits theStatusobject (defaults to{ code: 0, message: "" }when absent).Emitted shape (errored span)
codeuses the numeric OTLP enum;error.typefollows OTel semantic conventions (HTTP status forRequestFailedException, otherwise the full type name). With no error,Statusdefaults toUnset(code: 0) anderror.typeis absent. The optionalerrorparameter keeps all existing call sites source-compatible.Testing
dotnet build src/Microsoft.Agents.A365.Sdk.sln- succeeds (0 warnings, 0 errors)dotnet test src/Microsoft.Agents.A365.Sdk.sln- all projects pass (345 Observability.Runtime tests, including newSpanStatusBuilderTests,ExportFormatterStatusTests, and addedBaseData/InvokeAgentDataBuilderstatus cases)Note
Also includes a docs-only enhancement to
.github/copilot-instructions.md(build/architecture guidance) from earlier in the same working session.Span generated from ETW DTO