es_entity/context/
tracing.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct TracingContext {
5    pub trace_id: String,
6    pub span_id: String,
7    pub trace_flags: u8,
8    /// W3C traceparent header for easy propagation
9    pub traceparent: String,
10}
11
12impl TracingContext {
13    #[cfg(feature = "tracing-context")]
14    pub fn current() -> Option<Self> {
15        use opentelemetry::trace::TraceContextExt;
16        use tracing_opentelemetry::OpenTelemetrySpanExt;
17
18        let current = tracing::Span::current();
19        let context = current.context();
20
21        let span = context.span();
22        let span_context = span.span_context();
23        if !span_context.is_valid() {
24            return None;
25        }
26
27        let trace_id = span_context.trace_id();
28        let span_id = span_context.span_id();
29        let trace_flags =
30            (span_context.trace_flags() & opentelemetry::trace::TraceFlags::SAMPLED).to_u8();
31        let traceparent = format!("00-{}-{}-{:02x}", trace_id, span_id, trace_flags);
32
33        Some(TracingContext {
34            trace_id: trace_id.to_string(),
35            span_id: span_id.to_string(),
36            trace_flags,
37            traceparent,
38        })
39    }
40
41    #[cfg(feature = "tracing-context")]
42    pub fn inject_as_parent(&self) {
43        use opentelemetry::propagation::TextMapPropagator;
44        use opentelemetry_sdk::propagation::TraceContextPropagator;
45        use tracing_opentelemetry::OpenTelemetrySpanExt;
46
47        let mut carrier = std::collections::HashMap::new();
48
49        carrier.insert("traceparent".to_string(), self.traceparent.clone());
50
51        let propagator = TraceContextPropagator::new();
52        let extracted_context = propagator.extract(&carrier);
53        let _ = tracing::Span::current().set_parent(extracted_context);
54    }
55}