opentelemetry/logs/
logger.rs

1use std::{borrow::Cow, sync::Arc};
2
3use crate::{logs::LogRecord, InstrumentationLibrary, InstrumentationLibraryBuilder, KeyValue};
4
5#[cfg(feature = "logs_level_enabled")]
6use super::Severity;
7
8/// The interface for emitting [`LogRecord`]s.
9
10pub trait Logger {
11    /// Specifies the `LogRecord` type associated with this logger.
12    type LogRecord: LogRecord;
13
14    /// Creates a new log record builder.
15    fn create_log_record(&self) -> Self::LogRecord;
16
17    /// Emit a [`LogRecord`]. If there is active current thread's [`Context`],
18    ///  the logger will set the record's `TraceContext` to the active trace context,
19    ///
20    /// [`Context`]: crate::Context
21    fn emit(&self, record: Self::LogRecord);
22
23    #[cfg(feature = "logs_level_enabled")]
24    /// Check if the given log level is enabled.
25    fn event_enabled(&self, level: Severity, target: &str) -> bool;
26}
27
28/// Interfaces that can create [`Logger`] instances.
29pub trait LoggerProvider {
30    /// The [`Logger`] type that this provider will return.
31    type Logger: Logger;
32
33    /// Deprecated, use [`LoggerProvider::logger_builder()`]
34    ///
35    /// Returns a new versioned logger with a given name.
36    ///
37    /// The `name` should be the application name or the name of the library
38    /// providing instrumentation. If the name is empty, then an
39    /// implementation-defined default name may be used instead.
40    /// Create a new versioned `Logger` instance.
41    #[deprecated(since = "0.23.0", note = "Please use logger_builder() instead")]
42    fn versioned_logger(
43        &self,
44        name: impl Into<Cow<'static, str>>,
45        version: Option<Cow<'static, str>>,
46        schema_url: Option<Cow<'static, str>>,
47        attributes: Option<Vec<KeyValue>>,
48    ) -> Self::Logger {
49        let mut builder = self.logger_builder(name);
50        if let Some(v) = version {
51            builder = builder.with_version(v);
52        }
53        if let Some(s) = schema_url {
54            builder = builder.with_schema_url(s);
55        }
56        if let Some(a) = attributes {
57            builder = builder.with_attributes(a);
58        }
59        builder.build()
60    }
61
62    /// Returns a new builder for creating a [`Logger`] instance
63    ///
64    /// The `name` should be the application name or the name of the library
65    /// providing instrumentation. If the name is empty, then an
66    /// implementation-defined default name may be used instead.
67    ///
68    /// # Examples
69    ///
70    /// ```
71    /// use opentelemetry::InstrumentationLibrary;
72    /// use crate::opentelemetry::logs::LoggerProvider;
73    /// use opentelemetry_sdk::logs::LoggerProvider as SdkLoggerProvider;
74    ///
75    /// let provider = SdkLoggerProvider::builder().build();
76    ///
77    /// // logger used in applications/binaries
78    /// let logger = provider.logger_builder("my_app").build();
79    ///
80    /// // logger used in libraries/crates that optionally includes version and schema url
81    /// let logger = provider.logger_builder("my_library")
82    ///     .with_version(env!("CARGO_PKG_VERSION"))
83    ///     .with_schema_url("https://opentelemetry.io/schema/1.0.0")
84    ///     .build();
85    /// ```
86    fn logger_builder(&self, name: impl Into<Cow<'static, str>>) -> LoggerBuilder<'_, Self> {
87        LoggerBuilder {
88            provider: self,
89            library_builder: InstrumentationLibrary::builder(name),
90        }
91    }
92
93    /// Returns a new versioned logger with the given instrumentation library.
94    ///
95    /// # Examples
96    ///
97    /// ```
98    /// use opentelemetry::InstrumentationLibrary;
99    /// use crate::opentelemetry::logs::LoggerProvider;
100    /// use opentelemetry_sdk::logs::LoggerProvider as SdkLoggerProvider;
101    ///
102    /// let provider = SdkLoggerProvider::builder().build();
103    ///
104    /// // logger used in applications/binaries
105    /// let logger = provider.logger("my_app");
106    ///
107    /// // logger used in libraries/crates that optionally includes version and schema url
108    /// let library = std::sync::Arc::new(
109    ///     InstrumentationLibrary::builder(env!("CARGO_PKG_NAME"))
110    ///         .with_version(env!("CARGO_PKG_VERSION"))
111    ///         .with_schema_url("https://opentelemetry.io/schema/1.0.0")
112    ///         .build(),
113    /// );
114    /// let logger = provider.library_logger(library);
115    /// ```
116    fn library_logger(&self, library: Arc<InstrumentationLibrary>) -> Self::Logger;
117
118    /// Returns a new logger with the given name.
119    ///
120    /// The `name` should be the application name or the name of the library
121    /// providing instrumentation. If the name is empty, then an
122    /// implementation-defined default name may be used instead.
123    fn logger(&self, name: impl Into<Cow<'static, str>>) -> Self::Logger {
124        self.logger_builder(name).build()
125    }
126}
127
128#[derive(Debug)]
129pub struct LoggerBuilder<'a, T: LoggerProvider + ?Sized> {
130    provider: &'a T,
131    library_builder: InstrumentationLibraryBuilder,
132}
133
134impl<'a, T: LoggerProvider + ?Sized> LoggerBuilder<'a, T> {
135    pub fn with_version(mut self, version: impl Into<Cow<'static, str>>) -> Self {
136        self.library_builder = self.library_builder.with_version(version);
137        self
138    }
139
140    pub fn with_schema_url(mut self, schema_url: impl Into<Cow<'static, str>>) -> Self {
141        self.library_builder = self.library_builder.with_schema_url(schema_url);
142        self
143    }
144
145    pub fn with_attributes<I>(mut self, attributes: I) -> Self
146    where
147        I: IntoIterator<Item = KeyValue>,
148    {
149        self.library_builder = self.library_builder.with_attributes(attributes);
150        self
151    }
152
153    pub fn build(self) -> T::Logger {
154        self.provider
155            .library_logger(Arc::new(self.library_builder.build()))
156    }
157}