Pass log level & target to host log_utf8_string (#8)

This commit is contained in:
folex 2020-10-26 13:06:55 +03:00 committed by GitHub
parent 4d6c4f6b86
commit 8c0a029165
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 15 deletions

View File

@ -54,7 +54,9 @@ pub(crate) fn log<S: AsRef<str>>(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);
}
}

View File

@ -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(),
}
}