|
1 | 1 | use crate::trace::{noop::NoopTracerProvider, SpanContext, Status}; |
2 | | -use crate::InstrumentationScope; |
| 2 | +use crate::{otel_error, otel_info, InstrumentationScope}; |
3 | 3 | use crate::{trace, trace::TracerProvider, Context, KeyValue}; |
4 | 4 | use std::borrow::Cow; |
5 | 5 | use std::fmt; |
6 | | -use std::mem; |
7 | 6 | use std::sync::{Arc, OnceLock, RwLock}; |
8 | 7 | use std::time::SystemTime; |
9 | 8 |
|
@@ -373,10 +372,14 @@ fn global_tracer_provider() -> &'static RwLock<GlobalTracerProvider> { |
373 | 372 | /// [`TracerProvider`]: crate::trace::TracerProvider |
374 | 373 | /// [`GlobalTracerProvider`]: crate::global::GlobalTracerProvider |
375 | 374 | pub fn tracer_provider() -> GlobalTracerProvider { |
376 | | - global_tracer_provider() |
377 | | - .read() |
378 | | - .expect("GLOBAL_TRACER_PROVIDER RwLock poisoned") |
379 | | - .clone() |
| 375 | + // Try to get the global tracer provider. If the RwLock is poisoned, we'll log an error and return a NoopTracerProvider. |
| 376 | + let global_provider = global_tracer_provider().read(); |
| 377 | + if let Ok(provider) = global_provider { |
| 378 | + provider.clone() |
| 379 | + } else { |
| 380 | + otel_error!(name: "TracerProvider.GlobalGetFailed", message = "Getting global tracer provider failed. Traces created using global::tracer() or global::tracer_with_scope() will not function. Report this issue in OpenTelemetry repo."); |
| 381 | + GlobalTracerProvider::new(NoopTracerProvider::new()) |
| 382 | + } |
380 | 383 | } |
381 | 384 |
|
382 | 385 | /// Creates a named instance of [`Tracer`] via the configured [`GlobalTracerProvider`]. |
@@ -419,22 +422,19 @@ pub fn tracer_with_scope(scope: InstrumentationScope) -> BoxedTracer { |
419 | 422 |
|
420 | 423 | /// Sets the given [`TracerProvider`] instance as the current global provider. |
421 | 424 | /// |
422 | | -/// It returns the [`TracerProvider`] instance that was previously mounted as global provider |
423 | | -/// (e.g. [`NoopTracerProvider`] if a provider had not been set before). |
424 | | -/// |
425 | 425 | /// Libraries should NOT call this function. It is intended for applications/executables. |
426 | 426 | /// [`TracerProvider`]: crate::trace::TracerProvider |
427 | | -pub fn set_tracer_provider<P, T, S>(new_provider: P) -> GlobalTracerProvider |
| 427 | +pub fn set_tracer_provider<P, T, S>(new_provider: P) |
428 | 428 | where |
429 | 429 | S: trace::Span + Send + Sync + 'static, |
430 | 430 | T: trace::Tracer<Span = S> + Send + Sync + 'static, |
431 | 431 | P: trace::TracerProvider<Tracer = T> + Send + Sync + 'static, |
432 | 432 | { |
433 | | - let mut tracer_provider = global_tracer_provider() |
434 | | - .write() |
435 | | - .expect("GLOBAL_TRACER_PROVIDER RwLock poisoned"); |
436 | | - mem::replace( |
437 | | - &mut *tracer_provider, |
438 | | - GlobalTracerProvider::new(new_provider), |
439 | | - ) |
| 433 | + let mut global_provider = global_tracer_provider().write(); |
| 434 | + if let Ok(ref mut provider) = global_provider { |
| 435 | + **provider = GlobalTracerProvider::new(new_provider); |
| 436 | + otel_info!(name: "TracerProvider.GlobalSet", message = "Global tracer provider is set. Traces can now be created using global::tracer() or global::tracer_with_scope()."); |
| 437 | + } else { |
| 438 | + otel_error!(name: "TracerProvider.GlobalSetFailed", message = "Setting global tracer provider failed. Traces created using global::tracer() or global::tracer_with_scope() will not function. Report this issue in OpenTelemetry repo."); |
| 439 | + } |
440 | 440 | } |
0 commit comments