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
#![crate_name = "logfmt_logger"]

use log::{set_boxed_logger, set_max_level, Log, Metadata, Record, SetLoggerError};

use crate::filter::{create_default_filter, Filter};
use crate::fmt::{create_default_format, Format};

pub mod filter;
pub mod fmt;

/// Sets global logger to default instance of `LogFmtLogger`
pub fn init() {
  LogFmtLogger::default().init().unwrap();
}

pub struct LogFmtLogger {
  format: Box<dyn Format + Send + Sync>,
  filter: Box<dyn Filter + Send + Sync>,
}

impl LogFmtLogger {
  /// Returns a `LogFmtLogger` instance with default configuration
  pub fn new() -> Self {
    LogFmtLogger::default()
  }

  /// Returns a `LogFmtLogger` instance with supplied filter
  ///
  /// # Arguments
  /// * `filter` - The log record filter.
  /// # Examples
  /// ```
  /// use logfmt_logger::LogFmtLogger;
  /// use logfmt_logger::filter::env::EnvFilter;
  ///
  /// let logger = LogFmtLogger::new()
  ///   .with_filter(EnvFilter::new("MY_ENV_NAME"));
  /// ```
  pub fn with_filter<F: 'static>(mut self, filter: F) -> Self
  where
    F: Filter + Send + Sync,
  {
    self.filter = Box::new(filter);
    self
  }

  /// Returns a `LogFmtLogger` instance with supplied formatter
  ///
  /// # Arguments
  /// * `format` - Log the log record formatter.
  /// # Examples
  /// ```
  /// use logfmt_logger::LogFmtLogger;
  /// use logfmt_logger::fmt::color::ColorFormat;
  ///
  /// let logger = LogFmtLogger::new()
  ///   .with_format(ColorFormat::new());
  /// ```
  pub fn with_format<F: 'static>(mut self, format: F) -> Self
  where
    F: Format + Send + Sync,
  {
    self.format = Box::new(format);
    self
  }

  /// Sets global logger to this.
  ///
  /// # Errors
  ///
  /// An error is returned if a logger has already been set.
  ///
  pub fn init(self) -> Result<(), SetLoggerError> {
    set_max_level(self.filter.filter());
    set_boxed_logger(Box::new(self))
  }
}

impl Log for LogFmtLogger {
  fn enabled(&self, metadata: &Metadata) -> bool {
    self.filter.enabled(metadata)
  }

  fn log(&self, record: &Record) {
    if !self.filter.matches(record) {
      return;
    }

    self.format.write(record).unwrap()
  }

  fn flush(&self) {}
}

impl Default for LogFmtLogger {
  fn default() -> Self {
    Self {
      filter: create_default_filter(),
      format: create_default_format(),
    }
  }
}

#[cfg(test)]
mod tests {
  use crate::LogFmtLogger;

  #[test]
  fn test_thing() {
    LogFmtLogger::new()
      .with_filter(crate::filter::nop::NopFilter::default())
      .init()
      .unwrap();

    log::info!("test");
    log::warn!("test");
    log::error!("test");
    log::debug!("test");
    log::trace!("test");
  }
}