Skip to content

fix: use get_span_context() to handle NonRecordingSpan#258

Merged
nikhilNava merged 1 commit into
mainfrom
fix/nonrecording-span-context
May 27, 2026
Merged

fix: use get_span_context() to handle NonRecordingSpan#258
nikhilNava merged 1 commit into
mainfrom
fix/nonrecording-span-context

Conversation

@nikhilNava
Copy link
Copy Markdown
Contributor

Summary

When the token resolver returns None on the first turn, the TracerProvider produces a NonRecordingSpan. The .context attribute only exists on concrete ReadableSpan implementations, causing AttributeError crashes on the first agent message.

Changes

Replace all span.context accesses with the public get_span_context() interface method, which is available on all Span types including NonRecordingSpan. Also guard the .name access in _end() with getattr() since NonRecordingSpan lacks that attribute as well.

Files modified:

  • opentelemetry_scope.py: use get_span_context() in span start/end logging
  • enriched_span.py: delegate context property via get_span_context()
  • agent365_exporter.py: use get_span_context() in _map_span()
  • Test mocks updated: set get_span_context() return value on all mock spans
  • New test file: test_nonrecording_span.py with 6 targeted tests

Source

Ported from: microsoft/opentelemetry-distro-python#168

Testing

All 227 observability core tests pass.

Copilot AI review requested due to automatic review settings May 27, 2026 17:06
@nikhilNava nikhilNava requested a review from a team as a code owner May 27, 2026 17:06
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

When the token resolver returns None on the first turn, the TracerProvider
produces a NonRecordingSpan. The .context attribute only exists on concrete
ReadableSpan implementations, causing AttributeError crashes on the first
agent message.

Replace all span.context accesses with the public get_span_context()
interface method, which is available on all Span types including
NonRecordingSpan. Also guard the .name access in _end() with getattr()
since NonRecordingSpan lacks that attribute as well.

Changes:
- opentelemetry_scope.py: use get_span_context() in span start/end logging
- enriched_span.py: delegate context property via get_span_context()
- agent365_exporter.py: use get_span_context() in _map_span()
- Update test mocks to set get_span_context() return value
- Add test_nonrecording_span.py with 6 targeted tests

Ported from: microsoft/opentelemetry-distro-python#168

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@nikhilNava nikhilNava force-pushed the fix/nonrecording-span-context branch from 5d2f274 to aa8dcc6 Compare May 27, 2026 17:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the observability pipeline against NonRecordingSpan instances by switching span-context access from the .context attribute (not present on NonRecordingSpan) to the get_span_context() API, preventing first-turn AttributeError crashes.

Changes:

  • Replace .context usage with get_span_context() in span logging, span wrappers, and exporter mapping.
  • Guard span .name access during scope shutdown to handle spans that don’t expose name.
  • Update span mocks and add a dedicated test module covering NonRecordingSpan scenarios.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/observability/core/test_nonrecording_span.py Adds targeted tests to ensure NonRecordingSpan does not crash scope lifecycle, span wrapping, or exporter mapping.
tests/observability/core/test_agent365_exporter.py Updates mock spans to provide get_span_context() for exporter tests.
tests/observability/core/exporters/test_payload_chunking.py Updates mock spans to provide get_span_context() for payload chunking tests.
tests/observability/core/exporters/test_enriching_span_processor.py Updates mock spans to provide get_span_context() for processor tests.
tests/observability/core/exporters/test_enriched_span.py Updates mock spans to provide get_span_context() for enriched span tests.
libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/opentelemetry_scope.py Uses get_span_context() for logging span IDs and guards span name access in _end().
libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/exporters/enriched_span.py Makes EnrichedReadableSpan.context delegate via get_span_context().
libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/exporters/agent365_exporter.py Uses get_span_context() in _map_span() to extract trace/span IDs.

Comment thread tests/observability/core/test_nonrecording_span.py
Comment thread tests/observability/core/test_nonrecording_span.py
Comment thread tests/observability/core/test_nonrecording_span.py
Comment thread tests/observability/core/test_nonrecording_span.py
@nikhilNava nikhilNava enabled auto-merge (squash) May 27, 2026 17:37
@nikhilNava nikhilNava merged commit a42b56d into main May 27, 2026
9 checks passed
@nikhilNava nikhilNava deleted the fix/nonrecording-span-context branch May 27, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants