fix: resolve OpenTelemetry tracing architecture issues #1197
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.
Problem
The current tracing implementation has several architectural issues that cause duplicate span exports and violate OpenTelemetry design principles:
LlmOpsHttpExporterinstance added to trace pipeline multiple times incli_eval.py, causing spans to be exported 2x on start and 4x on endLlmOpsHttpExporter._should_drop_span()implements filtering logic (WHAT to send) in the exporter (should only handle HOW to send)trace_idset in multiple places after exporter creation, causing potential concurrency issuesentrypoint == "agent.json"checks create fragile dependenciesSolution
Separation of Concerns: Move filtering from exporters to processor boundary layer
Key Changes
1. Created
FilteringSpanExporterWrapperuipath-agents-python2. Cleaned Up
LlmOpsHttpExporteris_low_codeparameter_should_drop_span()methodexport()andupsert_span()3. Fixed Duplicate Exports in
cli_eval.py4. Fixed
trace_idMutations5. Removed
agent.jsonHacksBenefits
✅ Correct Architecture: Processors filter (WHAT), exporters export (HOW)
✅ No Duplicates: Each span exported exactly once
✅ Immutable State: No post-construction mutations
✅ Loose Coupling: Removed hardcoded filename checks
✅ Extensible:
FilteringSpanExporterreusable for any filtering needsTesting
Files Changed
src/uipath/tracing/_otel_exporters.py- AddedFilteringSpanExporter, cleaned upLlmOpsHttpExportersrc/uipath/_cli/cli_eval.py- Fixed duplicate exports and trace_id mutationssrc/uipath/_cli/cli_run.py- Removed agent.json hacksrc/uipath/_cli/_evals/_progress_reporter.py- Removed trace_id mutationsrc/uipath/tracing/__init__.py- Exported newFilteringSpanExporterclass