Skip to main content

aether_telemetry/
trace_context.rs

1use opentelemetry::propagation::Extractor;
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
6#[serde(untagged, rename_all = "camelCase", deny_unknown_fields)]
7pub enum AgentTraceContext {
8    /// Continue the trace beneath a remote W3C parent span.
9    Parent {
10        /// W3C traceparent header: version, trace ID, parent span ID, and trace flags.
11        traceparent: String,
12        /// Optional W3C tracestate header carrying vendor-specific trace state.
13        #[serde(default, skip_serializing_if = "Option::is_none")]
14        tracestate: Option<String>,
15    },
16    /// Start root spans in the supplied trace without attaching a parent span.
17    Root {
18        /// W3C trace ID: 32 lowercase hexadecimal characters and not all zeros.
19        #[serde(rename = "traceId")]
20        #[schemars(rename = "traceId")]
21        trace_id: String,
22    },
23}
24
25impl Extractor for AgentTraceContext {
26    fn get(&self, key: &str) -> Option<&str> {
27        match (self, key) {
28            (Self::Parent { traceparent, .. }, "traceparent") => Some(traceparent),
29            (Self::Parent { tracestate, .. }, "tracestate") => tracestate.as_deref(),
30            _ => None,
31        }
32    }
33
34    fn keys(&self) -> Vec<&str> {
35        match self {
36            Self::Parent { tracestate: Some(_), .. } => vec!["traceparent", "tracestate"],
37            Self::Parent { tracestate: None, .. } => vec!["traceparent"],
38            Self::Root { .. } => Vec::new(),
39        }
40    }
41}