use crate::config::TracingConfig;
use opentelemetry::trace::TracerProvider as _;
use opentelemetry_otlp::WithExportConfig as _;
use opentelemetry_sdk::propagation::TraceContextPropagator;
use opentelemetry_sdk::trace::{Sampler, SdkTracerProvider};
pub fn init_otel_pipeline(
config: &TracingConfig,
instance_id: &str,
) -> Result<(SdkTracerProvider, opentelemetry_sdk::trace::Tracer), Box<dyn std::error::Error>> {
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
let sampler = if config.sample_rate >= 1.0 {
Sampler::AlwaysOn
} else if config.sample_rate <= 0.0 {
Sampler::AlwaysOff
} else {
Sampler::TraceIdRatioBased(config.sample_rate)
};
let exporter = opentelemetry_otlp::SpanExporter::builder()
.with_tonic()
.with_endpoint(&config.otlp_endpoint)
.build()?;
let provider = SdkTracerProvider::builder()
.with_batch_exporter(exporter)
.with_sampler(sampler)
.with_resource(
opentelemetry_sdk::Resource::builder()
.with_service_name(config.service_name.clone())
.with_attribute(opentelemetry::KeyValue::new(
"service.instance.id",
instance_id.to_string(),
))
.build(),
)
.build();
let tracer = provider.tracer("orion");
opentelemetry::global::set_tracer_provider(provider.clone());
Ok((provider, tracer))
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn pipeline_builds_offline_for_every_sampler_regime() {
for sample_rate in [0.0, 0.5, 1.0] {
let config = TracingConfig {
enabled: true,
otlp_endpoint: "http://127.0.0.1:1".to_string(),
sample_rate,
..Default::default()
};
let (provider, _tracer) = init_otel_pipeline(&config, "test-instance")
.expect("offline pipeline construction must succeed");
let _ = provider.shutdown();
}
}
}