Struct GenLogger

Source
pub struct GenLogger<T: Write + Sync + Send + 'static> {
    pub log_formatter: LogFormatter,
    /* private fields */
}
Expand description

Implements a generic logger for use with different types of writers

§Simple Example

Instantiates a STDERR logger with default message and timestamp format

use log::{info,LevelFilter};
use poly_logger::GenLogger;

let mut logger = GenLogger::new(LevelFilter::Info, std::io::stderr());
logger.init().unwrap();
info!("This is an INFO message");

§Customized Example

Instantiates a STDOUT logger with custom timestamp format and message format

use log::{info,LevelFilter};
use poly_logger::GenLogger;

let mut logger = GenLogger::new(LevelFilter::Info, std::io::stdout());
logger.timestamp_format("%X%.6f")
      .msg_format("[{timestamp} {file}:{line}] - {level} - {args}");
logger.init().unwrap();
info!("This is a custom INFO message");
// Output is something like: 
// [20:52:57.909459 examples/stdout.rs:14] - INFO - This is a custom INFO message

Fields§

§log_formatter: LogFormatter

Implementations§

Source§

impl<T> GenLogger<T>
where T: Write + Sync + Send + 'static,

Source

pub fn new(level_filter: LevelFilter, writer: T) -> Self

Instantiate a new GenLogger with the given log level filter and a Writer instance

Examples found in repository?
examples/gen_stderr.rs (line 6)
5fn main() {
6    let logger = GenLogger::new(LevelFilter::Info, std::io::stderr());
7    logger.init().unwrap();
8
9    trace!("This is an TRACE message");
10    debug!("This is a DEBUG message");
11    info!("This is an INFO message");
12    warn!("This is a WARN message");
13    error!("This is an ERROR message");
14}
Source

pub fn init(self) -> Result<(), SetLoggerError>

Initializes the log interface using this GenLogger as a boxed logger. This moves self so is the last method to call on this object.

Examples found in repository?
examples/stderr_simple.rs (line 7)
5fn main() {
6    let logger = StderrLogger::new(LevelFilter::Info);
7    logger.init().unwrap();
8
9    trace!("This is an TRACE message");
10    debug!("This is a DEBUG message");
11    info!("This is an INFO message");
12    warn!("This is a WARN message");
13    error!("This is an ERROR message");
14}
More examples
Hide additional examples
examples/gen_stderr.rs (line 7)
5fn main() {
6    let logger = GenLogger::new(LevelFilter::Info, std::io::stderr());
7    logger.init().unwrap();
8
9    trace!("This is an TRACE message");
10    debug!("This is a DEBUG message");
11    info!("This is an INFO message");
12    warn!("This is a WARN message");
13    error!("This is an ERROR message");
14}
examples/invalid_fmt.rs (line 8)
5fn main() {
6    let mut logger = StderrLogger::new(LevelFilter::Info);
7    logger.msg_format("{foo} [{timestamp} {file}:{line}] - {baz}");
8    logger.init().unwrap();
9
10    trace!("This is an TRACE message");
11    debug!("This is a DEBUG message");
12    info!("This is an INFO message");
13    warn!("This is a WARN message");
14    error!("This is an ERROR message");
15}
examples/stderr.rs (line 10)
5fn main() {
6    let mut logger = StderrLogger::new(LevelFilter::Info);
7
8    logger.timestamp_format("%X%.6f")
9          .msg_format("[{timestamp} {file}:{line}] - {level} - {args}");
10    logger.init().unwrap();
11
12    trace!("This is an TRACE message");
13    debug!("This is a DEBUG message");
14    info!("This is an INFO message");
15    warn!("This is a WARN message");
16    error!("This is an ERROR message");
17}
examples/stdout.rs (line 10)
5fn main() {
6    let mut logger = StdoutLogger::new(LevelFilter::Info);
7
8    logger.timestamp_format("%F %X%.3f %Z")
9          .msg_format("{level} [{timestamp} {file}:{line}] - {args}");
10    logger.init().unwrap();
11
12    trace!("This is an TRACE message");
13    debug!("This is a DEBUG message");
14    info!("This is an INFO message");
15    warn!("This is a WARN message");
16    error!("This is an ERROR message");
17}
Source

pub fn timestamp_format(&mut self, format: &'static str) -> &mut Self

Sets the timestamp format to use in our log messages.

The format string may be any valid format from the chrono::format::strftime module.

If format is set to “” the timestamp will not be calculated/formatted, which is more efficient if if timestamp is not part of the message format.

The default timestamp format of ‘%+’ (ISO 8601 / RFC 3339 date & time format) will be used if you do not call timestamp_format() on your logger.

Examples found in repository?
examples/stderr.rs (line 8)
5fn main() {
6    let mut logger = StderrLogger::new(LevelFilter::Info);
7
8    logger.timestamp_format("%X%.6f")
9          .msg_format("[{timestamp} {file}:{line}] - {level} - {args}");
10    logger.init().unwrap();
11
12    trace!("This is an TRACE message");
13    debug!("This is a DEBUG message");
14    info!("This is an INFO message");
15    warn!("This is a WARN message");
16    error!("This is an ERROR message");
17}
More examples
Hide additional examples
examples/stdout.rs (line 8)
5fn main() {
6    let mut logger = StdoutLogger::new(LevelFilter::Info);
7
8    logger.timestamp_format("%F %X%.3f %Z")
9          .msg_format("{level} [{timestamp} {file}:{line}] - {args}");
10    logger.init().unwrap();
11
12    trace!("This is an TRACE message");
13    debug!("This is a DEBUG message");
14    info!("This is an INFO message");
15    warn!("This is a WARN message");
16    error!("This is an ERROR message");
17}
examples/poly.rs (line 14)
5fn main() {
6    // Create some logger instances and run all through
7    // the PolyLogger
8    
9    // Default format 
10    let tl0 = StderrLogger::new(LevelFilter::Info);
11
12    // Custom format
13    let mut tl1 = StderrLogger::new(LevelFilter::Warn);
14    tl1.timestamp_format("%a %b %e %T %Y")
15       .msg_format("Custom: [{timestamp}] {level} [{file}:{line}] - {args}");
16
17    // Simpler format
18    let mut tl2 = StderrLogger::new(LevelFilter::Info);
19    tl2.msg_format("Simple1: {level} [{timestamp}] {args}")
20       .timestamp_format("%T");
21
22    // Even simpler
23    let mut tl3 = StderrLogger::new(LevelFilter::Debug);
24    tl3.msg_format("Simple2: {level} - {args}")
25       .timestamp_format("");
26
27    // Raw format to stdout
28    let mut tl4 = StdoutLogger::new(LevelFilter::Trace);
29    tl4.msg_format("{args}")
30       .timestamp_format("");
31
32    // File logger
33    let filename = "/tmp/file_logger.log";
34    let mut fl0 = FileLogger::new(LevelFilter::Info);
35    fl0.msg_format("Simple1: {level} [{timestamp}] {args}")
36       .timestamp_format("%T")
37       .filename(filename);
38    println!("Logging to {}", filename);
39    
40    // Create the poly logger and add our logger instances
41    let mut pl = PolyLogger::new();
42    pl.add(tl0);
43    pl.add(tl1);
44    pl.add(tl2);
45    pl.add(tl3);
46    pl.add(tl4);
47    pl.add(fl0.create());
48    pl.init().unwrap();
49
50    trace!("This is an TRACE message");
51    eprintln!("------------------------------");
52    debug!("This is a DEBUG message");
53    eprintln!("------------------------------");
54    info!("This is an INFO message");
55    eprintln!("------------------------------");
56    warn!("This is a WARN message");
57    eprintln!("------------------------------");
58    error!("This is an ERROR message");
59}
Source

pub fn msg_format(&mut self, format: &'static str) -> &mut Self

Sets the format for message written by our logger

The format can use any combination of the following placeholders

  • {timestamp} - Date/time stamp of this message
  • {level} - The log::Level for this message
  • {file} - The Rust source file where the log message was generated
  • {line} - The line in the Rust source file where the log message was generated
  • {args} - The log message itself

Note that the names of the placeholders come from the corresponding definitions in log::Record.

This method relies on the strfmt crate which gives us flexibility at the expense of being somewhat expensive. It’s our best option as of late 2020 though.

The default format is: [{timestamp}] {level} [{file}:{line}] {args}

Examples found in repository?
examples/invalid_fmt.rs (line 7)
5fn main() {
6    let mut logger = StderrLogger::new(LevelFilter::Info);
7    logger.msg_format("{foo} [{timestamp} {file}:{line}] - {baz}");
8    logger.init().unwrap();
9
10    trace!("This is an TRACE message");
11    debug!("This is a DEBUG message");
12    info!("This is an INFO message");
13    warn!("This is a WARN message");
14    error!("This is an ERROR message");
15}
More examples
Hide additional examples
examples/stderr.rs (line 9)
5fn main() {
6    let mut logger = StderrLogger::new(LevelFilter::Info);
7
8    logger.timestamp_format("%X%.6f")
9          .msg_format("[{timestamp} {file}:{line}] - {level} - {args}");
10    logger.init().unwrap();
11
12    trace!("This is an TRACE message");
13    debug!("This is a DEBUG message");
14    info!("This is an INFO message");
15    warn!("This is a WARN message");
16    error!("This is an ERROR message");
17}
examples/stdout.rs (line 9)
5fn main() {
6    let mut logger = StdoutLogger::new(LevelFilter::Info);
7
8    logger.timestamp_format("%F %X%.3f %Z")
9          .msg_format("{level} [{timestamp} {file}:{line}] - {args}");
10    logger.init().unwrap();
11
12    trace!("This is an TRACE message");
13    debug!("This is a DEBUG message");
14    info!("This is an INFO message");
15    warn!("This is a WARN message");
16    error!("This is an ERROR message");
17}
examples/doc_poly.rs (line 6)
4fn main() {
5    let mut stderr_log = StderrLogger::new(LevelFilter::Debug);
6    stderr_log.msg_format("{args}");
7
8    let mut file_log = FileLogger::new(LevelFilter::Info);
9    file_log.filename("./test.log");
10
11    let mut poly_log = PolyLogger::new();
12    poly_log.add(file_log.create()); // create() returns the GenLogger
13    poly_log.add(stderr_log);
14    poly_log.init().unwrap();
15
16    info!("This goes to both loggers");
17    debug!("This only goes to stderr");
18}
examples/poly2.rs (line 8)
5fn main() {
6    // Create a few terminal loggers
7    let mut tl0 = StderrLogger::new(LevelFilter::Debug);
8    tl0.msg_format("TL0: {timestamp} - {level} - {args}");
9
10    let mut tl1 = StderrLogger::new(LevelFilter::Info);
11    tl1.msg_format("TL1: {timestamp} - {level} - {args}");
12
13    let mut tl2 = StderrLogger::new(LevelFilter::Warn);
14    tl2.msg_format("TL2: {timestamp} - {level} - {args}");
15
16    // Put one one terminal logger into one poly_logger
17    let mut pl0 = PolyLogger::new();
18    pl0.add(tl0);
19
20    // Put other terminal loggers into another poly_logger
21    let mut pl1 = PolyLogger::new();
22    pl1.add(tl1);
23    pl1.add(tl2);
24
25    // Put second poly_logger into the first poly_logger
26    // which is the one we actually register with the 
27    // log system via init().
28    // Not sure if this would ever make sense, but hey...
29    pl0.add(pl1);
30    pl0.init().unwrap();
31
32    trace!("This is an TRACE message");
33    eprintln!("------------------------------");
34    debug!("This is a DEBUG message");
35    eprintln!("------------------------------");
36    info!("This is an INFO message");
37    eprintln!("------------------------------");
38    warn!("This is a WARN message");
39    eprintln!("------------------------------");
40    error!("This is an ERROR message");
41}
examples/poly.rs (line 15)
5fn main() {
6    // Create some logger instances and run all through
7    // the PolyLogger
8    
9    // Default format 
10    let tl0 = StderrLogger::new(LevelFilter::Info);
11
12    // Custom format
13    let mut tl1 = StderrLogger::new(LevelFilter::Warn);
14    tl1.timestamp_format("%a %b %e %T %Y")
15       .msg_format("Custom: [{timestamp}] {level} [{file}:{line}] - {args}");
16
17    // Simpler format
18    let mut tl2 = StderrLogger::new(LevelFilter::Info);
19    tl2.msg_format("Simple1: {level} [{timestamp}] {args}")
20       .timestamp_format("%T");
21
22    // Even simpler
23    let mut tl3 = StderrLogger::new(LevelFilter::Debug);
24    tl3.msg_format("Simple2: {level} - {args}")
25       .timestamp_format("");
26
27    // Raw format to stdout
28    let mut tl4 = StdoutLogger::new(LevelFilter::Trace);
29    tl4.msg_format("{args}")
30       .timestamp_format("");
31
32    // File logger
33    let filename = "/tmp/file_logger.log";
34    let mut fl0 = FileLogger::new(LevelFilter::Info);
35    fl0.msg_format("Simple1: {level} [{timestamp}] {args}")
36       .timestamp_format("%T")
37       .filename(filename);
38    println!("Logging to {}", filename);
39    
40    // Create the poly logger and add our logger instances
41    let mut pl = PolyLogger::new();
42    pl.add(tl0);
43    pl.add(tl1);
44    pl.add(tl2);
45    pl.add(tl3);
46    pl.add(tl4);
47    pl.add(fl0.create());
48    pl.init().unwrap();
49
50    trace!("This is an TRACE message");
51    eprintln!("------------------------------");
52    debug!("This is a DEBUG message");
53    eprintln!("------------------------------");
54    info!("This is an INFO message");
55    eprintln!("------------------------------");
56    warn!("This is a WARN message");
57    eprintln!("------------------------------");
58    error!("This is an ERROR message");
59}

Trait Implementations§

Source§

impl<T> Log for GenLogger<T>
where T: Write + Sync + Send + 'static,

Source§

fn enabled(&self, metadata: &Metadata<'_>) -> bool

Determines if a log message with the specified metadata would be logged. Read more
Source§

fn log(&self, record: &Record<'_>)

Logs the Record. Read more
Source§

fn flush(&self)

Flushes any buffered records.

Auto Trait Implementations§

§

impl<T> !Freeze for GenLogger<T>

§

impl<T> RefUnwindSafe for GenLogger<T>

§

impl<T> Send for GenLogger<T>

§

impl<T> Sync for GenLogger<T>

§

impl<T> Unpin for GenLogger<T>
where T: Unpin,

§

impl<T> UnwindSafe for GenLogger<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.