tracing_distributed/
trace.rs1use crate::telemetry_layer::TraceCtxRegistry;
2use std::time::SystemTime;
3use tracing_subscriber::registry::LookupSpan;
4
5pub fn register_dist_tracing_root<SpanId, TraceId>(
7 trace_id: TraceId,
8 remote_parent_span: Option<SpanId>,
9) -> Result<(), TraceCtxError>
10where
11 SpanId: 'static + Clone + Send + Sync,
12 TraceId: 'static + Clone + Send + Sync,
13{
14 let span = tracing::Span::current();
15 span.with_subscriber(|(current_span_id, dispatch)| {
16 if let Some(trace_ctx_registry) =
17 dispatch.downcast_ref::<TraceCtxRegistry<SpanId, TraceId>>()
18 {
19 trace_ctx_registry.record_trace_ctx(
20 trace_id,
21 remote_parent_span,
22 current_span_id.clone(),
23 );
24 Ok(())
25 } else {
26 Err(TraceCtxError::TelemetryLayerNotRegistered)
27 }
28 })
29 .ok_or(TraceCtxError::NoEnabledSpan)?
30}
31
32pub fn current_dist_trace_ctx<SpanId, TraceId>() -> Result<(TraceId, SpanId), TraceCtxError>
36where
37 SpanId: 'static + Clone + Send + Sync,
38 TraceId: 'static + Clone + Send + Sync,
39{
40 let span = tracing::Span::current();
41 span.with_subscriber(|(current_span_id, dispatch)| {
42 let trace_ctx_registry = dispatch
43 .downcast_ref::<TraceCtxRegistry<SpanId, TraceId>>()
44 .ok_or(TraceCtxError::TelemetryLayerNotRegistered)?;
45
46 let registry = dispatch
47 .downcast_ref::<tracing_subscriber::Registry>()
48 .ok_or(TraceCtxError::RegistrySubscriberNotRegistered)?;
49
50 let iter = itertools::unfold(Some(current_span_id.clone()), |st| match st {
51 Some(target_id) => {
52 let res = registry
54 .span(target_id)
55 .expect("span data not found during eval_ctx for current_trace_ctx");
56 *st = res.parent().map(|x| x.id());
57 Some(res)
58 }
59 None => None,
60 });
61
62 trace_ctx_registry
63 .eval_ctx(iter)
64 .map(|x| {
65 (
66 x.trace_id,
67 trace_ctx_registry.promote_span_id(current_span_id.clone()),
68 )
69 })
70 .ok_or(TraceCtxError::NoParentNodeHasTraceCtx)
71 })
72 .ok_or(TraceCtxError::NoEnabledSpan)?
73}
74
75#[derive(PartialEq, Eq, Hash, Clone, Debug)]
78#[non_exhaustive]
79pub enum TraceCtxError {
80 TelemetryLayerNotRegistered,
82 RegistrySubscriberNotRegistered,
84 NoEnabledSpan,
86 NoParentNodeHasTraceCtx,
88}
89
90impl std::fmt::Display for TraceCtxError {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 use TraceCtxError::*;
93 write!(f, "{}",
94 match self {
95 TelemetryLayerNotRegistered => "`TelemetryLayer` is not a registered subscriber of the current Span",
96 RegistrySubscriberNotRegistered => "no `tracing_subscriber::Registry` is a registered subscriber of the current Span",
97 NoEnabledSpan => "the span is not enabled with an associated subscriber",
98 NoParentNodeHasTraceCtx => "unable to evaluate trace context; assert `register_dist_tracing_root` is called in some parent span",
99 })
100 }
101}
102
103impl std::error::Error for TraceCtxError {}
104
105#[derive(Debug, Clone)]
107pub struct Span<Visitor, SpanId, TraceId> {
108 pub id: SpanId,
110 pub trace_id: TraceId,
112 pub parent_id: Option<SpanId>,
114 pub initialized_at: SystemTime,
116 pub completed_at: SystemTime,
118 pub meta: &'static tracing::Metadata<'static>,
120 pub service_name: &'static str,
122 pub values: Visitor,
124}
125
126#[derive(Clone, Debug)]
128pub struct Event<Visitor, SpanId, TraceId> {
129 pub trace_id: TraceId,
131 pub parent_id: Option<SpanId>,
133 pub initialized_at: SystemTime,
135 pub meta: &'static tracing::Metadata<'static>,
137 pub service_name: &'static str,
139 pub values: Visitor,
141}