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
//! Custom logger module.
//!
//! A custom logger implementation over [`log`] crate
//! that uses stdout to print logs.
//!
//! Note that `log` crate should be set with `"sdt"` feature.
//!
//! ``` toml
//! # Cargo.toml
//! [dependencies]
//! log = {version = "0.4.20", features = ["std"]}
//! ```
extern crate log;
use super::time::get_formatted_time;
use log::{LevelFilter, Log, Metadata, Record};
/// A custom logger struct that uses stdout to print logs.
///
/// # Example
///
/// ``` rust
/// extern crate log;
/// use crate::logger::logger::Logger;
/// fn main() {
/// Logger::init(Some(log::LevelFilter::Debug));
/// log::debug!("This is a debug message");
/// }
/// ```
pub struct Logger {
/// The default level of the logger.
default_level: LevelFilter,
}
impl Logger {
/// Static method to initialize the logger
/// with an optional logging level.
pub fn init(level: Option<LevelFilter>) {
// If the level is not specified, use `Trace` as default level.
let record_level = level.unwrap_or(LevelFilter::Trace);
log::set_max_level(record_level);
let logger = Logger {
default_level: record_level,
};
// Set the logger as the global logger.
// Note that `log` crate should be set with "sdt" feature.
// See Cargo.toml for more details.
log::set_boxed_logger(Box::new(logger)).unwrap();
}
}
impl Log for Logger {
/// Check if current message level is enabled for logging.
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= self.default_level
}
/// Log the message.
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
let level_str = {
{
record.level().to_string().to_uppercase()
}
};
let time_str = get_formatted_time();
let message = format!("{} [{}]\t {}", time_str, level_str, record.args());
println!("{}", message);
}
}
/// Flush the logger.
/// As stdout is used, no need to flush, so this method is empty.
fn flush(&self) {}
}