opentelemetry_api/global/
logs.rs1use std::{
2 borrow::Cow,
3 fmt, mem,
4 sync::{Arc, RwLock},
5};
6
7use once_cell::sync::Lazy;
8
9use crate::{
10 logs::{Logger, LoggerProvider, NoopLoggerProvider},
11 InstrumentationLibrary,
12};
13
14pub trait ObjectSafeLoggerProvider {
19 fn boxed_logger(
25 &self,
26 library: Arc<InstrumentationLibrary>,
27 ) -> Box<dyn Logger + Send + Sync + 'static>;
28}
29
30impl<L, P> ObjectSafeLoggerProvider for P
31where
32 L: Logger + Send + Sync + 'static,
33 P: LoggerProvider<Logger = L>,
34{
35 fn boxed_logger(
36 &self,
37 library: Arc<InstrumentationLibrary>,
38 ) -> Box<dyn Logger + Send + Sync + 'static> {
39 Box::new(self.library_logger(library))
40 }
41}
42
43pub struct BoxedLogger(Box<dyn Logger + Send + Sync + 'static>);
44
45impl fmt::Debug for BoxedLogger {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 f.write_str("BoxedLogger")
48 }
49}
50
51impl Logger for BoxedLogger {
52 fn emit(&self, record: crate::logs::LogRecord) {
53 self.0.emit(record)
54 }
55
56 #[cfg(feature = "logs_level_enabled")]
57 fn event_enabled(&self, level: crate::logs::Severity, target: &str) -> bool {
58 self.0.event_enabled(level, target)
59 }
60}
61
62#[derive(Clone)]
63pub struct GlobalLoggerProvider {
65 provider: Arc<dyn ObjectSafeLoggerProvider + Send + Sync>,
66}
67
68impl fmt::Debug for GlobalLoggerProvider {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 f.write_str("GlobalLoggerProvider")
71 }
72}
73
74impl GlobalLoggerProvider {
75 fn new<
76 L: Logger + Send + Sync + 'static,
77 P: LoggerProvider<Logger = L> + Send + Sync + 'static,
78 >(
79 provider: P,
80 ) -> Self {
81 GlobalLoggerProvider {
82 provider: Arc::new(provider),
83 }
84 }
85}
86
87impl LoggerProvider for GlobalLoggerProvider {
88 type Logger = BoxedLogger;
89
90 fn library_logger(&self, library: Arc<InstrumentationLibrary>) -> Self::Logger {
91 BoxedLogger(self.provider.boxed_logger(library))
92 }
93}
94
95static GLOBAL_LOGGER_PROVIDER: Lazy<RwLock<GlobalLoggerProvider>> =
96 Lazy::new(|| RwLock::new(GlobalLoggerProvider::new(NoopLoggerProvider::new())));
97
98pub fn logger_provider() -> GlobalLoggerProvider {
103 GLOBAL_LOGGER_PROVIDER
104 .read()
105 .expect("GLOBAL_LOGGER_PROVIDER RwLock poisoned")
106 .clone()
107}
108
109pub fn logger(name: Cow<'static, str>) -> BoxedLogger {
116 logger_provider().logger(name)
117}
118
119pub fn set_logger_provider<L, P>(new_provider: P) -> GlobalLoggerProvider
123where
124 L: Logger + Send + Sync + 'static,
125 P: LoggerProvider<Logger = L> + Send + Sync + 'static,
126{
127 let mut provider = GLOBAL_LOGGER_PROVIDER
128 .write()
129 .expect("GLOBAL_LOGGER_PROVIDER RwLock poisoned");
130 mem::replace(&mut *provider, GlobalLoggerProvider::new(new_provider))
131}
132
133pub fn shutdown_logger_provider() {
135 let _ = set_logger_provider(NoopLoggerProvider::new());
136}