|
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