Skip to content

Commit 5f0b8e5

Browse files
committed
fix: fix trace id in logs when nested in tracing span with set_parent
1 parent 9dc727e commit 5f0b8e5

File tree

1 file changed

+68
-14
lines changed
  • opentelemetry-appender-tracing/src

1 file changed

+68
-14
lines changed

opentelemetry-appender-tracing/src/layer.rs

+68-14
Original file line numberDiff line numberDiff line change
@@ -246,21 +246,24 @@ where
246246

247247
#[cfg(feature = "experimental_use_tracing_span_context")]
248248
if let Some(span) = _ctx.event_span(event) {
249+
use opentelemetry::trace::TraceContextExt;
249250
use tracing_opentelemetry::OtelData;
250-
let opt_span_id = span
251-
.extensions()
252-
.get::<OtelData>()
253-
.and_then(|otd| otd.builder.span_id);
254-
255-
let opt_trace_id = span.scope().last().and_then(|root_span| {
256-
root_span
257-
.extensions()
258-
.get::<OtelData>()
259-
.and_then(|otd| otd.builder.trace_id)
260-
});
261-
262-
if let Some((trace_id, span_id)) = opt_trace_id.zip(opt_span_id) {
263-
log_record.set_trace_context(trace_id, span_id, None);
251+
if let Some(otd) = span.extensions().get::<OtelData>() {
252+
if let Some(span_id) = otd.builder.span_id {
253+
let opt_trace_id = if otd.parent_cx.has_active_span() {
254+
Some(otd.parent_cx.span().span_context().trace_id())
255+
} else {
256+
span.scope().last().and_then(|root_span| {
257+
root_span
258+
.extensions()
259+
.get::<OtelData>()
260+
.and_then(|otd| otd.builder.trace_id)
261+
})
262+
};
263+
if let Some(trace_id) = opt_trace_id {
264+
log_record.set_trace_context(trace_id, span_id, None);
265+
}
266+
}
264267
}
265268
}
266269

@@ -611,7 +614,9 @@ mod tests {
611614
#[cfg(feature = "experimental_use_tracing_span_context")]
612615
#[test]
613616
fn tracing_appender_inside_tracing_crate_context() {
617+
use opentelemetry::{trace::SpanContext, Context, SpanId, TraceId};
614618
use opentelemetry_sdk::trace::InMemorySpanExporterBuilder;
619+
use tracing_opentelemetry::OpenTelemetrySpanExt;
615620

616621
// Arrange
617622
let exporter: InMemoryLogExporter = InMemoryLogExporter::default();
@@ -667,6 +672,55 @@ mod tests {
667672
assert_eq!(trace_ctx1.trace_id, trace_id);
668673
assert_eq!(trace_ctx0.span_id, outer_span_id);
669674
assert_eq!(trace_ctx1.span_id, inner_span_id);
675+
676+
// Set context from remote.
677+
let remote_trace_id = TraceId::from_u128(233);
678+
let remote_span_id = SpanId::from_u64(2333);
679+
let remote_span_context = SpanContext::new(
680+
remote_trace_id,
681+
remote_span_id,
682+
TraceFlags::SAMPLED,
683+
true,
684+
Default::default(),
685+
);
686+
687+
// Act again.
688+
tracing::error_span!("outer-span").in_scope(|| {
689+
let span = tracing::Span::current();
690+
let parent_context = Context::current().with_remote_span_context(remote_span_context);
691+
span.set_parent(parent_context);
692+
693+
error!("first-event");
694+
695+
tracing::error_span!("inner-span").in_scope(|| {
696+
error!("second-event");
697+
});
698+
});
699+
700+
assert!(logger_provider.force_flush().is_ok());
701+
702+
let logs = exporter.get_emitted_logs().expect("No emitted logs");
703+
assert_eq!(logs.len(), 4, "Expected 4 logs, got: {logs:?}");
704+
let logs = &logs[2..];
705+
706+
let spans = span_exporter.get_finished_spans().unwrap();
707+
assert_eq!(spans.len(), 4);
708+
let spans = &spans[2..];
709+
710+
let trace_id = spans[0].span_context.trace_id();
711+
assert_eq!(trace_id, remote_trace_id);
712+
assert_eq!(trace_id, spans[1].span_context.trace_id());
713+
let inner_span_id = spans[0].span_context.span_id();
714+
let outer_span_id = spans[1].span_context.span_id();
715+
assert_eq!(outer_span_id, spans[0].parent_span_id);
716+
717+
let trace_ctx0 = logs[0].record.trace_context().unwrap();
718+
let trace_ctx1 = logs[1].record.trace_context().unwrap();
719+
720+
assert_eq!(trace_ctx0.trace_id, trace_id);
721+
assert_eq!(trace_ctx1.trace_id, trace_id);
722+
assert_eq!(trace_ctx0.span_id, outer_span_id);
723+
assert_eq!(trace_ctx1.span_id, inner_span_id);
670724
}
671725

672726
#[test]

0 commit comments

Comments
 (0)