#![forbid(unsafe_code)]
#![warn(clippy::perf)]
#![warn(clippy::pedantic)]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::missing_errors_doc)]
#![doc = include_str!("../README.md")]
mod error;
pub use error::Error;
use opentelemetry::propagation::TextMapPropagator;
use opentelemetry::sdk::propagation::{
BaggagePropagator, TextMapCompositePropagator, TraceContextPropagator,
};
use opentelemetry::trace::TraceError;
#[cfg(feature = "jaeger")]
pub mod jaeger;
#[cfg(feature = "otlp")]
pub mod otlp;
#[cfg(feature = "tracer")]
pub mod resource;
#[cfg(feature = "tracer")]
pub mod stdio;
#[cfg(feature = "tracing_subscriber_ext")]
pub mod tracing_subscriber_ext;
pub fn init_propagator() -> Result<(), TraceError> {
let value_from_env =
std::env::var("OTEL_PROPAGATORS").unwrap_or_else(|_| "tracecontext,baggage".to_string());
let propagators: Vec<(Box<dyn TextMapPropagator + Send + Sync>, String)> = value_from_env
.split(',')
.map(|s| {
let name = s.trim().to_lowercase();
propagator_from_string(&name).map(|o| o.map(|b| (b, name)))
})
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.flatten()
.collect();
if !propagators.is_empty() {
let (propagators_impl, propagators_name): (Vec<_>, Vec<_>) =
propagators.into_iter().unzip();
tracing::debug!(target: "otel::setup", OTEL_PROPAGATORS = propagators_name.join(","));
let composite_propagator = TextMapCompositePropagator::new(propagators_impl);
opentelemetry::global::set_text_map_propagator(composite_propagator);
}
Ok(())
}
#[allow(clippy::box_default)]
fn propagator_from_string(
v: &str,
) -> Result<Option<Box<dyn TextMapPropagator + Send + Sync>>, TraceError> {
match v {
"tracecontext" => Ok(Some(Box::new(TraceContextPropagator::new()))),
"baggage" => Ok(Some(Box::new(BaggagePropagator::new()))),
#[cfg(feature = "zipkin")]
"b3" => Ok(Some(Box::new(
opentelemetry_zipkin::Propagator::with_encoding(
opentelemetry_zipkin::B3Encoding::SingleHeader,
),
))),
#[cfg(not(feature = "zipkin"))]
"b3" => Err(TraceError::from(
"unsupported propagators form env OTEL_PROPAGATORS: 'b3', try to enable compile feature 'zipkin'"
)),
#[cfg(feature = "zipkin")]
"b3multi" => Ok(Some(Box::new(
opentelemetry_zipkin::Propagator::with_encoding(
opentelemetry_zipkin::B3Encoding::MultipleHeader,
),
))),
#[cfg(not(feature = "zipkin"))]
"b3multi" => Err(TraceError::from(
"unsupported propagators form env OTEL_PROPAGATORS: 'b3multi', try to enable compile feature 'zipkin'"
)),
#[cfg(feature = "jaeger")]
"jaeger" => Ok(Some(Box::new(
opentelemetry_jaeger::Propagator::default()
))),
#[cfg(not(feature = "jaeger"))]
"jaeger" => Err(TraceError::from(
"unsupported propagators form env OTEL_PROPAGATORS: 'jaeger', try to enable compile feature 'jaeger'"
)),
#[cfg(feature = "xray")]
"xray" => Ok(Some(Box::new(
opentelemetry_aws::trace::XrayPropagator::default(),
))),
#[cfg(not(feature = "xray"))]
"xray" => Err(TraceError::from(
"unsupported propagators form env OTEL_PROPAGATORS: 'xray', try to enable compile feature 'xray'"
)),
"none" => Ok(None),
unknown => Err(TraceError::from(format!(
"unsupported propagators form env OTEL_PROPAGATORS: '{unknown}'"
))),
}
}
#[cfg(test)]
#[cfg(feature = "tracer")]
mod tests {
use assert2::let_assert;
#[test]
fn init_tracing_failed_on_invalid_propagator() {
let_assert!(Err(_) = super::propagator_from_string("xxxxxx"));
}
}