#[cfg(feature = "tracing-opentelemetry")]
use std::time::Duration;
#[cfg(feature = "tracing-opentelemetry")]
use opentelemetry_otlp::WithExportConfig;
#[cfg(feature = "tracing-opentelemetry")]
use tracing::info;
#[cfg(feature = "tracing-opentelemetry")]
pub fn init_jaeger(
service_name: &str,
otlp_endpoint: &str,
sampling_rate: f64,
) -> Result<impl Drop, Box<dyn std::error::Error>> {
info!(
service_name = service_name,
otlp_endpoint = otlp_endpoint,
sampling_rate = sampling_rate,
"Initializing OpenTelemetry with Jaeger exporter"
);
let otlp_exporter = opentelemetry_otlp::new_exporter()
.http()
.with_endpoint(otlp_endpoint)
.with_timeout(Duration::from_secs(10))
.with_headers(std::collections::HashMap::new());
let _tracer = opentelemetry_otlp::new_pipeline()
.tracing()
.with_exporter(otlp_exporter)
.with_trace_config(
opentelemetry_sdk::trace::Config::default()
.with_sampler(opentelemetry_sdk::trace::Sampler::TraceIdRatioBased(sampling_rate))
.with_resource(opentelemetry_sdk::Resource::new(vec![
opentelemetry::KeyValue::new("service.name", service_name.to_string()),
])),
)
.install_batch(opentelemetry_sdk::runtime::Tokio)?;
info!("OpenTelemetry initialized successfully");
Ok(JaegerGuard {})
}
#[cfg(feature = "tracing-opentelemetry")]
pub struct JaegerGuard {}
#[cfg(feature = "tracing-opentelemetry")]
impl Drop for JaegerGuard {
fn drop(&mut self) {
info!("Flushing OpenTelemetry traces");
opentelemetry::global::shutdown_tracer_provider();
}
}
#[cfg(all(test, feature = "tracing-opentelemetry"))]
mod tests {
#[test]
fn test_sampling_rate_validation() {
let valid_rates = vec![0.0, 0.1, 0.5, 1.0];
for rate in valid_rates {
assert!((0.0..=1.0).contains(&rate), "Rate {} should be valid", rate);
}
let invalid_rates = vec![-0.1, 1.1, 2.0];
for rate in invalid_rates {
assert!(!(0.0..=1.0).contains(&rate), "Rate {} should be invalid", rate);
}
}
}