Skip to content

Commit 73c0c10

Browse files
authored
opentelemetry: Assign default ids if missing (#1029)
## Motivation It is currently possible to create a span graph which includes a span that has both an invalid parent otel context _and_ a missing trace id by assigning an invalid extracted parent context to a non-root span. Constructing this particular graph will currently cause a panic. ## Solution Explicitly assign invalid trace / span ids when sampling using the otel SDK if the span builder does not contain these values.
1 parent 89418ee commit 73c0c10

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

tracing-opentelemetry/src/tracer.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,18 @@ impl PreSampledTracer for api::NoopTracer {
5656

5757
impl PreSampledTracer for sdk::Tracer {
5858
fn sampled_span_context(&self, builder: &mut api::SpanBuilder) -> api::SpanContext {
59-
let span_id = builder.span_id.expect("Builders must have id");
59+
let span_id = builder
60+
.span_id
61+
.unwrap_or_else(|| self.provider().config().id_generator.new_span_id());
6062
let (trace_id, trace_flags) = builder
6163
.parent_context
6264
.as_ref()
6365
.filter(|parent_context| parent_context.is_valid())
6466
.map(|parent_context| (parent_context.trace_id(), parent_context.trace_flags()))
6567
.unwrap_or_else(|| {
66-
let trace_id = builder.trace_id.expect("trace_id should exist");
68+
let trace_id = builder
69+
.trace_id
70+
.unwrap_or_else(|| self.provider().config().id_generator.new_trace_id());
6771

6872
// ensure sampling decision is recorded so all span contexts have consistent flags
6973
let sampling_decision = if let Some(result) = builder.sampling_result.as_ref() {
@@ -111,3 +115,21 @@ impl PreSampledTracer for sdk::Tracer {
111115
self.provider().config().id_generator.new_span_id()
112116
}
113117
}
118+
119+
#[cfg(test)]
120+
mod tests {
121+
use super::*;
122+
use opentelemetry::api::{Provider, SpanBuilder};
123+
use opentelemetry::sdk;
124+
125+
#[test]
126+
fn assigns_default_ids_if_missing() {
127+
let tracer = sdk::Provider::default().get_tracer("test");
128+
let mut builder = SpanBuilder::from_name("empty".to_string());
129+
builder.trace_id = None;
130+
builder.span_id = None;
131+
let span_context = tracer.sampled_span_context(&mut builder);
132+
133+
assert!(span_context.is_valid());
134+
}
135+
}

0 commit comments

Comments
 (0)