use axum::http::HeaderMap;
use crate::observability::lean_telemetry::{new_span_id, new_trace_id, parse_traceparent};
pub struct TraceContext {
pub trace_id: [u8; 16],
pub span_id: [u8; 8],
pub parent_span_id: [u8; 8],
}
pub fn extract_trace_context(headers: &HeaderMap) -> TraceContext {
let (trace_id, parent_span_id) = headers
.get("traceparent")
.and_then(|h| parse_traceparent(h.as_bytes()))
.map(|t| (t.trace_id, t.span_id))
.unwrap_or_else(|| (new_trace_id(), [0u8; 8]));
TraceContext {
trace_id,
span_id: new_span_id(),
parent_span_id,
}
}
impl TraceContext {
pub fn to_traceparent(&self) -> String {
format!(
"00-{}-{}-01",
crate::observability::lean_telemetry::hex_encode(&self.trace_id),
crate::observability::lean_telemetry::hex_encode(&self.span_id),
)
}
pub fn from_traceparent(s: &str) -> Option<TraceContext> {
let parsed = crate::observability::lean_telemetry::parse_traceparent(s.as_bytes())?;
Some(TraceContext {
trace_id: parsed.trace_id,
span_id: crate::observability::lean_telemetry::new_span_id(),
parent_span_id: parsed.span_id,
})
}
pub fn new_root() -> TraceContext {
TraceContext {
trace_id: crate::observability::lean_telemetry::new_trace_id(),
span_id: crate::observability::lean_telemetry::new_span_id(),
parent_span_id: [0u8; 8],
}
}
}