use ::log::{Log, Metadata, Record};
use crate::event::{Breadcrumb, Event};
use crate::level::Level;
fn from_log_level(level: ::log::Level) -> Level {
match level {
::log::Level::Error => Level::Error,
::log::Level::Warn => Level::Warning,
::log::Level::Info => Level::Info,
::log::Level::Debug => Level::Debug,
::log::Level::Trace => Level::Debug,
}
}
pub struct ErrsightLogger {
event_level: Level,
breadcrumb_level: Level,
backing: Option<Box<dyn Log>>,
}
impl ErrsightLogger {
pub fn builder() -> ErrsightLoggerBuilder {
ErrsightLoggerBuilder {
event_level: Level::Error,
breadcrumb_level: Level::Info,
backing: None,
max_level: ::log::LevelFilter::Info,
}
}
}
impl Log for ErrsightLogger {
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
match &self.backing {
Some(b) => b.enabled(metadata),
None => true,
}
}
fn log(&self, record: &Record<'_>) {
if let Some(b) = &self.backing {
if b.enabled(record.metadata()) {
b.log(record);
}
}
let level = from_log_level(record.level());
let message = format!("{}", record.args());
if level >= self.event_level {
let mut event = Event::new(level, message);
event.set_metadata("logger.target", record.target());
if let Some(module) = record.module_path() {
event.set_metadata("logger.module", module);
}
if let (Some(file), Some(line)) = (record.file(), record.line()) {
event.set_metadata("logger.location", format!("{file}:{line}"));
}
crate::capture_event(event);
} else if level >= self.breadcrumb_level {
let crumb = Breadcrumb::new(record.target(), message).level(level);
crate::add_breadcrumb(crumb);
}
}
fn flush(&self) {
if let Some(b) = &self.backing {
b.flush();
}
}
}
pub struct ErrsightLoggerBuilder {
event_level: Level,
breadcrumb_level: Level,
backing: Option<Box<dyn Log>>,
max_level: ::log::LevelFilter,
}
impl ErrsightLoggerBuilder {
pub fn event_level(mut self, level: Level) -> Self {
self.event_level = level;
self
}
pub fn breadcrumb_level(mut self, level: Level) -> Self {
self.breadcrumb_level = level;
self
}
pub fn backing(mut self, logger: Box<dyn Log>) -> Self {
self.backing = Some(logger);
self
}
pub fn max_level(mut self, filter: ::log::LevelFilter) -> Self {
self.max_level = filter;
self
}
pub fn build(self) -> ErrsightLogger {
ErrsightLogger {
event_level: self.event_level,
breadcrumb_level: self.breadcrumb_level,
backing: self.backing,
}
}
pub fn install(self) -> Result<(), ::log::SetLoggerError> {
let max = self.max_level;
let logger = self.build();
::log::set_boxed_logger(Box::new(logger))?;
::log::set_max_level(max);
Ok(())
}
}