Skip to main content

snix_tracing/propagate/
tonic.rs

1#[cfg(feature = "otlp")]
2struct MetadataInjector<'a>(&'a mut tonic::metadata::MetadataMap);
3
4#[cfg(feature = "otlp")]
5impl opentelemetry::propagation::Injector for MetadataInjector<'_> {
6    fn set(&mut self, key: &str, value: String) {
7        use tonic::metadata::{MetadataKey, MetadataValue};
8        use tracing::warn;
9
10        match MetadataKey::from_bytes(key.as_bytes()) {
11            Ok(key) => match MetadataValue::try_from(&value) {
12                Ok(value) => {
13                    self.0.insert(key, value);
14                }
15                Err(error) => warn!(value, error = format!("{error:#}"), "parse metadata value"),
16            },
17            Err(error) => warn!(key, error = format!("{error:#}"), "parse metadata key"),
18        }
19    }
20}
21
22/// Trace context propagation: send the trace context by injecting it into the metadata of the given
23/// request. This only injects the current span if the otlp feature is also enabled.
24#[allow(unused_mut)]
25pub fn send_trace<T>(mut request: tonic::Request<T>) -> Result<tonic::Request<T>, tonic::Status> {
26    #[cfg(feature = "otlp")]
27    {
28        use tracing_opentelemetry::OpenTelemetrySpanExt;
29        opentelemetry::global::get_text_map_propagator(|propagator| {
30            let context = tracing::Span::current().context();
31            propagator.inject_context(&context, &mut MetadataInjector(request.metadata_mut()))
32        });
33    }
34    Ok(request)
35}