tracing_opentelemetry_ext/
tonic.rs1use opentelemetry::propagation::{Injector, TextMapPropagator};
2use opentelemetry::sdk::propagation::TraceContextPropagator;
3use std::str::FromStr;
4use tonic::metadata::{AsciiMetadataKey, AsciiMetadataValue, MetadataMap};
5use tonic::service::Interceptor;
6use tracing::Span;
7use tracing_opentelemetry::OpenTelemetrySpanExt;
8
9#[derive(Clone)]
10pub struct TonicTraceInterceptor;
11
12impl Interceptor for TonicTraceInterceptor {
13 fn call(&mut self, mut req: tonic::Request<()>) -> tonic::Result<tonic::Request<()>> {
14 let ctx = Span::current().context();
15 TraceContextPropagator::new().inject_context(&ctx, &mut TonicMetadataInjector(req.metadata_mut()));
16 Ok(req)
17 }
18}
19
20struct TonicMetadataInjector<'a>(&'a mut MetadataMap);
21
22impl Injector for TonicMetadataInjector<'_> {
23 fn set(&mut self, key: &str, value: String) {
24 if let (Ok(key), Ok(value)) = (AsciiMetadataKey::from_str(key), AsciiMetadataValue::try_from(&value)) {
25 self.0.insert(key, value);
26 }
27 }
28}