Add distributed tracing via OpenTelemetry#217
Merged
Merged
Conversation
Contributor
QualOps Code Quality AnalysisStatus: ✅ PASSED - No issues found Summary
No issues found in the analyzed code. 📊 Full ReportPowered by QualOps |
7d82a42 to
5b19b4e
Compare
Every message hop across agents now shares a single trace_id, giving end-to-end visibility into multi-agent interactions. Tracing is opt-in and zero-cost when not configured.
…() and provider clobber - Replace _tracer sentinel with swappable _NoOpBackend / _OtelBackend so handlers subscribed before setup_tracing() are correctly traced once it is called (closure reads _backend at message time, not subscription time) - setup_tracing() no longer overwrites a user-configured TracerProvider; it adopts the existing one when the current provider is not the default ProxyTracerProvider (fixes silent overwrite when env var is set) - Replace `import eggai` for version lookup with importlib.metadata.version() to eliminate the fragile circular import - All OTel imports are contained in _OtelBackend methods; channel.py and make_tracing_wrapper have no direct opentelemetry imports - Skip wrapping sync handlers in make_tracing_wrapper (they cannot propagate OTel context across await points and have incompatible call conventions)
rocky-jaiswal
approved these changes
Apr 14, 2026
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.
Every message hop across agents now shares a single trace_id, giving end-to-end visibility into multi-agent interactions. Tracing is opt-in and zero-cost when not configured.
Description
Adds distributed tracing support to the EggAI SDK using OpenTelemetry. A
traceparentfield (W3C Trace Context) is propagated through every message, linking producer and consumer spans across agents and transport backends into a single end-to-end trace. Every message hop across agents shares a singletrace_id, giving end-to-end visibility into multi-agent interactions.Tracing uses a swappable backend (
_NoOpBackend/_OtelBackend) sosetup_tracing()can be called at any point — handlers subscribed before it is called are immediately traced once it fires. When theotelextra is not installed, handlers are never wrapped and there is zero overhead.Type of Change
Changes Made
sdk/eggai/tracing.pywithsetup_tracing(), swappable_NoOpBackend/_OtelBackend,make_tracing_wrapper()for consumer spans, and auto-activation whenOTEL_EXPORTER_OTLP_ENDPOINTis settraceparent: str | Nonefield toBaseMessagefor W3C Trace Context propagationChannel.publish()to inject/continue trace context into outgoing messages as a PRODUCER span via the active backendoteloptional extra topyproject.toml(pip install eggai[otel]) with OTLP gRPC, OTLP HTTP, and console exporterssdk/tests/test_tracing.pywith test coverage for no-op, producer spans, consumer spans, trace continuation, and multi-hop trace propagationTesting
make test)Manual Testing Steps
pip install eggai[otel]OTEL_EXPORTER_OTLP_ENDPOINT(or callsetup_tracing(exporter="console")at startup)trace_idin your tracing backend (Jaeger, Tempo, etc.)setup_tracing()— confirm no errors and no performance changeChangelog
sdk/CHANGELOG.mdunder[Unreleased]section (required for code changes)Checklist
make lintpasses)make formatapplied)Additional Notes
make_tracing_wrapperdetects OTel is absent at import time and returns handlers unwrapped; no closures allocated, no per-message costsetup_tracing()swaps the backend in-place; handlers already subscribed begin producing real spans immediately, no re-subscription neededTracerProvideris already configured (e.g. by the application),setup_tracing()adopts it rather than overwriting itOTEL_EXPORTER_OTLP_ENDPOINT/OTEL_EXPORTER_OTLP_PROTOCOLenv vars (silently skips if theotelextra is not installed)