From 8c0a02916519872c3d6073de16c950d10da0b2f4 Mon Sep 17 00:00:00 2001 From: folex <0xdxdy@gmail.com> Date: Mon, 26 Oct 2020 13:06:55 +0300 Subject: [PATCH] Pass log level & target to host log_utf8_string (#8) --- crates/main/src/lib.rs | 4 ++- crates/main/src/logger.rs | 53 ++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/crates/main/src/lib.rs b/crates/main/src/lib.rs index 6ff74fc..dc20b08 100644 --- a/crates/main/src/lib.rs +++ b/crates/main/src/lib.rs @@ -54,7 +54,9 @@ pub(crate) fn log>(msg: S) { // logs will be printed only if debug feature is enabled #[cfg(feature = "debug")] { + let level = log::Level::Info as i32; + let target = 0i64; let msg = msg.as_ref(); - logger::log_utf8_string(msg.as_ptr() as i32, msg.len() as i32); + logger::log_utf8_string(level, target, msg.as_ptr() as i32, msg.len() as i32); } } diff --git a/crates/main/src/logger.rs b/crates/main/src/logger.rs index 0c275fe..77fa4cf 100644 --- a/crates/main/src/logger.rs +++ b/crates/main/src/logger.rs @@ -64,6 +64,8 @@ //! [`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; + /// The Wasm Logger. /// /// This struct implements the [`Log`] trait from the [`log`] crate, which allows it to act as a @@ -78,6 +80,7 @@ /// [`init()`]: struct.WasmLogger.html#method.init pub struct WasmLogger { level: log::Level, + target_map: HashMap<&'static str, i64>, } #[allow(dead_code)] @@ -98,12 +101,21 @@ impl WasmLogger { /// # } /// ``` pub fn init_with_level(level: log::Level) -> Result<(), log::SetLoggerError> { - let logger = WasmLogger { level }; + let logger = WasmLogger { + level, + 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; + } + /// Initializes the global logger with a [`WasmLogger`] instance, sets /// `max_log_level` to `Level::Info`. /// @@ -137,14 +149,14 @@ impl log::Log for WasmLogger { return; } - let log_msg = format!( - "{:<5} [{}] {}\n", - record.level().to_string(), - record.module_path().unwrap_or_default(), - record.args() - ); + let level = record.metadata().level() as i32; + let target = *self + .target_map + .get(record.metadata().target()) + .unwrap_or(&0); + let msg = record.args().to_string(); - log_utf8_string(log_msg.as_ptr() as _, log_msg.len() as _); + log_utf8_string(level, target, msg.as_ptr() as _, msg.len() as _); } // in our case flushing is performed by the VM itself @@ -153,17 +165,18 @@ impl log::Log for WasmLogger { } #[cfg(target_arch = "wasm32")] -pub fn log_utf8_string(ptr: i32, size: i32) { - unsafe { log_utf8_string_impl(ptr, size) }; +pub fn log_utf8_string(level: i32, target: i64, msg_ptr: i32, msg_size: i32) { + unsafe { log_utf8_string_impl(level, target, msg_ptr, msg_size) }; } #[cfg(not(target_arch = "wasm32"))] -pub fn log_utf8_string(ptr: i32, size: i32) { +pub fn log_utf8_string(level: i32, target: i64, msg_ptr: i32, msg_size: i32) { use std::str::from_utf8_unchecked; use core::slice::from_raw_parts; - let msg = unsafe { from_utf8_unchecked(from_raw_parts(ptr as _, size as _)) }; - println!("{}", msg); + let level = level_from_i32(level); + let msg = unsafe { from_utf8_unchecked(from_raw_parts(msg_ptr as _, msg_size as _)) }; + println!("[{}] {} {}", level, target, msg); } /// log_utf8_string should be provided directly by a host. @@ -172,5 +185,17 @@ pub fn log_utf8_string(ptr: i32, size: i32) { extern "C" { // Writes a byte string of size bytes that starts from ptr to a logger #[link_name = "log_utf8_string"] - fn log_utf8_string_impl(ptr: i32, size: i32); + fn log_utf8_string_impl(level: i32, target: i64, msg_ptr: i32, msg_size: i32); +} + +#[allow(dead_code)] +fn level_from_i32(level: i32) -> log::Level { + match level { + 1 => log::Level::Error, + 2 => log::Level::Warn, + 3 => log::Level::Info, + 4 => log::Level::Debug, + 5 => log::Level::Trace, + _ => log::Level::max(), + } }