-
Notifications
You must be signed in to change notification settings - Fork 399
Description
Summary
The UnifiedTrace module for GraphQL does not call Contrib::Analytics.set_measured(span) on the graphql.execute span, which prevents RED (Rate, Errors, Duration) metrics from being generated. This makes it impossible to use standard Datadog monitoring features like the Service Page operations list and trace.graphql.* metrics.
Expected Behavior
When using with_unified_tracer: true, the graphql.execute span should:
- Appear as a top-level operation in the Datadog Service Page
- Generate
trace.graphql.execute.*metrics (hits, errors, duration) - Be usable for monitors and SLOs based on these metrics
Actual Behavior
- The
graphql.executespan appears correctly in traces with proper resource names - However, it does not appear in the Service Page operations list
- No
trace.graphql.*metrics are generated - Cannot create monitors/SLOs based on GraphQL operation performance
Root Cause Analysis
Comparing UnifiedTrace with other integrations that correctly appear as top-level operations:
Sidekiq ServerTracer (source):
span.set_tag(
Datadog::Tracing::Metadata::Ext::TAG_KIND,
Datadog::Tracing::Metadata::Ext::SpanKind::TAG_CONSUMER
)
# Measure service stats
Contrib::Analytics.set_measured(span) # ✅ PresentRack Middleware (source):
request_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
# Measure service stats
Contrib::Analytics.set_measured(request_span) # ✅ PresentGraphQL UnifiedTrace (source):
# In execute_query method:
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
# ❌ Missing: Contrib::Analytics.set_measured(span)The comment on line 86-87 states:
# Ensure this span can be aggregated by in the Datadog App, and generates RED metrics.
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)However, setting TAG_KIND = TAG_SERVER alone is not sufficient to generate RED metrics. The _dd.measured = 1 tag (set by set_measured()) is required.
Suggested Fix
In unified_trace.rb, add the set_measured() call in the execute_query method's before lambda:
def execute_query(*args, query:, **kwargs)
trace(
proc { super },
'execute',
operation_resource(query.selected_operation),
lambda { |span|
span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_SERVER)
# Add this line to enable RED metrics generation
Contrib::Analytics.set_measured(span)
span.set_tag('graphql.source', query.query_string)
# ... rest of the method
},
# ...
)
endEnvironment
- dd-trace-rb version: 2.x (tested with latest)
- Ruby version: 3.2.2
- GraphQL version: 2.x
- Configuration:
Datadog.configure do |c|
c.tracing.instrument :graphql, with_unified_tracer: true
endAdditional Context
This issue is particularly impactful for applications where GraphQL is the primary API layer, as it prevents effective monitoring of API performance without falling back to the less feature-rich legacy tracer.
Contribution
I'm happy to submit a PR implementing the suggested fix if the proposed approach is confirmed to be correct.