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