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}