init_tracing_opentelemetry/
tracing_subscriber_ext.rs1use opentelemetry::trace::TracerProvider;
2#[cfg(feature = "metrics")]
3use opentelemetry_sdk::metrics::SdkMeterProvider;
4use opentelemetry_sdk::{
5 trace::{SdkTracerProvider, Tracer},
6 Resource,
7};
8use tracing::{level_filters::LevelFilter, Subscriber};
9#[cfg(feature = "metrics")]
10use tracing_opentelemetry::MetricsLayer;
11use tracing_opentelemetry::OpenTelemetryLayer;
12use tracing_subscriber::{filter::EnvFilter, layer::SubscriberExt, registry::LookupSpan, Layer};
13
14use crate::{
15 config::TracingConfig,
16 init_propagator, otlp,
18 otlp::OtelGuard,
19 resource::DetectResource,
20 Error,
21};
22
23#[must_use]
24#[deprecated(
25 since = "0.31.0",
26 note = "Use `TracingConfig::default().build_layer()` instead"
27)]
28pub fn build_logger_text<S>() -> Box<dyn Layer<S> + Send + Sync + 'static>
31where
32 S: Subscriber + for<'a> LookupSpan<'a>,
33{
34 TracingConfig::default()
35 .build_layer()
36 .expect("Failed to build logger layer")
37}
38
39#[must_use]
40#[deprecated = "replaced by the configurable build_level_filter_layer(\"\")"]
41pub fn build_loglevel_filter_layer() -> EnvFilter {
42 build_level_filter_layer("").unwrap_or_default()
43}
44
45pub fn build_level_filter_layer(log_directives: &str) -> Result<EnvFilter, Error> {
62 let dirs = if log_directives.is_empty() {
63 std::env::var("RUST_LOG")
64 .or_else(|_| std::env::var("OTEL_LOG_LEVEL"))
65 .unwrap_or_else(|_| "info".to_string())
66 } else {
67 log_directives.to_string()
68 };
69 let directive_to_allow_otel_trace = "otel::tracing=trace".parse()?;
70
71 Ok(EnvFilter::builder()
72 .with_default_directive(LevelFilter::INFO.into())
73 .parse_lossy(dirs)
74 .add_directive(directive_to_allow_otel_trace))
75}
76
77pub fn regiter_otel_layers<S>(
78 subscriber: S,
79) -> Result<(impl Subscriber + for<'span> LookupSpan<'span>, OtelGuard), Error>
80where
81 S: Subscriber + for<'a> LookupSpan<'a>,
82{
83 register_otel_layers_with_resource(subscriber, DetectResource::default().build())
84}
85
86pub fn register_otel_layers_with_resource<S>(
87 subscriber: S,
88 otel_rsrc: Resource,
89) -> Result<(impl Subscriber + for<'span> LookupSpan<'span>, OtelGuard), Error>
90where
91 S: Subscriber + for<'a> LookupSpan<'a>,
92{
93 #[cfg(feature = "metrics")]
94 let (metrics_layer, meter_provider) = build_metrics_layer_with_resource(otel_rsrc.clone())?;
95 let (trace_layer, tracer_provider) = build_tracer_layer_with_resource(otel_rsrc)?;
96 let subscriber = subscriber.with(trace_layer);
97 #[cfg(feature = "metrics")]
98 let subscriber = subscriber.with(metrics_layer);
99 Ok((
100 subscriber,
101 OtelGuard {
102 #[cfg(feature = "metrics")]
103 meter_provider,
104 tracer_provider,
105 },
106 ))
107}
108
109pub fn build_tracer_layer<S>() -> Result<(OpenTelemetryLayer<S, Tracer>, SdkTracerProvider), Error>
111where
112 S: Subscriber + for<'span> LookupSpan<'span>,
113{
114 build_tracer_layer_with_resource(
115 DetectResource::default()
116 .build(),
119 )
120}
121
122pub fn build_tracer_layer_with_resource<S>(
123 otel_rsrc: Resource,
124) -> Result<(OpenTelemetryLayer<S, Tracer>, SdkTracerProvider), Error>
125where
126 S: Subscriber + for<'span> LookupSpan<'span>,
127{
128 let tracer_provider = otlp::traces::init_tracerprovider(otel_rsrc, otlp::traces::identity)?;
129 init_propagator()?;
139 let layer = tracing_opentelemetry::layer()
140 .with_error_records_to_exceptions(true)
141 .with_tracer(tracer_provider.tracer(""));
142 opentelemetry::global::set_tracer_provider(tracer_provider.clone());
143 Ok((layer, tracer_provider))
144}
145
146#[cfg(feature = "metrics")]
147pub fn build_metrics_layer<S>(
148) -> Result<(MetricsLayer<S, SdkMeterProvider>, SdkMeterProvider), Error>
149where
150 S: Subscriber + for<'span> LookupSpan<'span>,
151{
152 build_metrics_layer_with_resource(DetectResource::default().build())
153}
154
155#[cfg(feature = "metrics")]
156pub fn build_metrics_layer_with_resource<S>(
157 otel_rsrc: Resource,
158) -> Result<(MetricsLayer<S, SdkMeterProvider>, SdkMeterProvider), Error>
159where
160 S: Subscriber + for<'a> LookupSpan<'a>,
161{
162 let meter_provider = otlp::metrics::init_meterprovider(otel_rsrc, otlp::metrics::identity)?;
163 let layer = MetricsLayer::new(meter_provider.clone());
164 opentelemetry::global::set_meter_provider(meter_provider.clone());
165 Ok((layer, meter_provider))
166}
167
168#[deprecated(
173 since = "0.31.0",
174 note = "Use `TracingConfig::production()...` instead"
175)]
176pub fn init_subscribers() -> Result<OtelGuard, Error> {
177 let guard = TracingConfig::production().init_subscriber()?;
178 match guard.otel_guard {
179 Some(otel_guard) => {
180 if let Some(default_guard) = guard.default_guard {
183 std::mem::forget(default_guard);
184 }
185 Ok(otel_guard)
186 }
187 None => Err(std::io::Error::new(
188 std::io::ErrorKind::Unsupported,
189 "OpenTelemetry is disabled but OtelGuard was requested",
190 )
191 .into()),
192 }
193}
194
195#[deprecated(
200 since = "0.31.0",
201 note = "Use `TracingConfig::production().with_log_directives(log_directives)...` instead"
202)]
203pub fn init_subscribers_and_loglevel(log_directives: &str) -> Result<OtelGuard, Error> {
204 let guard = TracingConfig::production()
205 .with_log_directives(log_directives)
206 .init_subscriber()?;
207 match guard.otel_guard {
208 Some(otel_guard) => {
209 if let Some(default_guard) = guard.default_guard {
212 std::mem::forget(default_guard);
213 }
214 Ok(otel_guard)
215 }
216 None => Err(std::io::Error::new(
217 std::io::ErrorKind::Unsupported,
218 "OpenTelemetry is disabled but OtelGuard was requested",
219 )
220 .into()),
221 }
222}