improve logger

This commit is contained in:
vms 2020-10-29 14:08:16 +03:00
parent 8c0a029165
commit e4c1c43c42

View File

@ -19,7 +19,7 @@
//!
//! # Examples
//!
//! This example initializes [`WasmLogger`] if target arch is Wasm and [`simple_logger`] otherwise.
//! This example initializes [`WasmLogger`] with setting log level.
//! Macros from crate [`log`] are used as a logging facade.
//!
//! ```
@ -28,11 +28,10 @@
//! use simple_logger;
//!
//! fn main() {
//! if cfg!(target_arch = "wasm32") {
//! logger::WasmLogger::init_with_level(log::Level::Info).unwrap();
//! } else {
//! simple_logger::init_with_level(log::Level::Info).unwrap();
//! }
//! logger::WasmLogger::new()
//! .with_log_leve(log::Level::Info)
//! .build()
//! .unwrap();
//!
//! error!("This message will be logged.");
//! trace!("This message will not be logged.");
@ -40,100 +39,74 @@
//!
//! ```
//!
//! This example provides methods for [`WasmLogger`] initialization only for Wasm target without
//! specifying logger level:
//!
//! ```
//! use fluence::sdk::*;
//! use log::info;
//!
//! /// This method initializes WasmLogger and should be called at the start of the application.
//! #[no_mangle]
//! #[cfg(target_arch = "wasm32")]
//! fn init_logger() {
//! logger::WasmLogger::init().unwrap();
//! info!("If you can see this message that logger was successfully initialized.");
//! }
//!
//! ```
//!
//! [`WasmLogger`]: struct.WasmLogger.html
//! [`log`]: https://docs.rs/log
//! [`simple_logger`]: https://docs.rs/simple_logger
//! [`static_lazy`]: https://docs.rs/lazy_static
//! [`lazy_static::initialize()`]: https://docs.rs/lazy_static/1.3.0/lazy_static/fn.initialize.html
//! [`backend app debugging`]: https://fluence.dev/docs/debugging
use std::collections::HashMap;
pub type TargetMap = std::collections::HashMap<&'static str, i64>;
/// The Wasm Logger.
///
/// This struct implements the [`Log`] trait from the [`log`] crate, which allows it to act as a
/// logger.
///
/// For initialization of WasmLogger as a default logger please see [`init()`]
/// and [`init_with_level()`]
/// Builder pattern is used here for logger initialization. Please be aware that build must be called
/// to set the logger up.
///
/// [log-crate-url]: https://docs.rs/log/
/// [`Log`]: https://docs.rs/log/0.4.6/log/trait.Log.html
/// [`init_with_level()`]: struct.WasmLogger.html#method.init_with_level
/// [`init()`]: struct.WasmLogger.html#method.init
/// [`Log`]: https://docs.rs/log/0.4.11/log/trait.Log.html
pub struct WasmLogger {
level: log::Level,
target_map: HashMap<&'static str, i64>,
target_map: TargetMap,
}
#[allow(dead_code)]
// #[allow(dead_code)]
impl WasmLogger {
/// Initializes the global logger with a [`WasmLogger`] instance, sets
/// `max_log_level` to a given log level.
///
/// ```
/// # use fluence::sdk::*;
/// # use log::info;
/// #
/// # fn main() {
/// if cfg!(target_arch = "wasm32") {
/// logger::WasmLogger::init_with_level(log::Level::Error).unwrap();
/// }
/// error!("This message will be logged.");
/// info!("This message will not be logged.");
/// # }
/// ```
pub fn init_with_level(level: log::Level) -> Result<(), log::SetLoggerError> {
let logger = WasmLogger {
level,
/// Initializes the global logger with a [`WasmLogger`] instance with log level set to `Level::Info`.
/// It is a initial method in this builder chain, please note, that logger wouldn't work without
/// subsequent build() call.
pub fn new() -> Self {
Self {
level: log::Level::Info,
target_map: <_>::default(),
};
log::set_boxed_logger(Box::new(logger))?;
log::set_max_level(level.to_level_filter());
Ok(())
}
}
/// Sets mapping between logging targets and numbers
/// Used to efficiently enable & disable logs per target on the host
pub fn with_target_map(&mut self, map: HashMap<&'static str, i64>) {
self.target_map = map;
/// Set the log level.
pub fn with_log_level(mut self, level: log::Level) -> Self {
self.level = level;
self
}
/// Initializes the global logger with a [`WasmLogger`] instance, sets
/// `max_log_level` to `Level::Info`.
/// Set mapping between logging targets and numbers.
/// Used to efficiently enable & disable logs per target on the host.
pub fn with_target_map(mut self, map: TargetMap) -> Self {
self.map = map;
self
}
/// Build the real logger.
///
/// This method is a last one in this builder chain and MUST be called to set logger up.
/// Returns a error
///
/// ```
/// # use fluence::sdk::*;
/// # use fluence::logger;
/// # use log::info;
/// #
/// # fn main() {
/// if cfg!(target_arch = "wasm32") {
/// fluence::logger::WasmLogger::init().unwrap();
/// }
///
/// error!("This message will be logged.");
/// trace!("This message will not be logged.");
/// logger::WasmLogger::new()
/// .with_log_level(log::Level::Trace)
/// .with_target_map(<_>::default())
/// .build()
/// .unwrap();
/// # }
/// ```
pub fn init() -> Result<(), log::SetLoggerError> {
WasmLogger::init_with_level(log::Level::Info)
pub fn build(self) -> Result<(), log::SetLoggerError> {
let log_level = self.level;
log::set_boxed_logger(Box::new(self))?;
log::set_max_level(log_level.to_level_filter());
Ok(())
}
}
@ -150,16 +123,17 @@ impl log::Log for WasmLogger {
}
let level = record.metadata().level() as i32;
let default_target = 0;
let target = *self
.target_map
.get(record.metadata().target())
.unwrap_or(&0);
.unwrap_or(&default_target);
let msg = record.args().to_string();
log_utf8_string(level, target, msg.as_ptr() as _, msg.len() as _);
}
// in our case flushing is performed by the VM itself
// in our case flushing is performed by a host itself
#[inline]
fn flush(&self) {}
}