pub struct WebLogger {
filter: log::LevelFilter,
}
impl WebLogger {
pub fn init(filter: log::LevelFilter) -> Result<(), log::SetLoggerError> {
log::set_max_level(filter);
log::set_boxed_logger(Box::new(Self::new(filter)))
}
pub fn new(filter: log::LevelFilter) -> Self {
Self { filter }
}
}
impl log::Log for WebLogger {
fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
const CRATES_AT_INFO_LEVEL: &[&str] = &[
"naga",
"wgpu_core",
"wgpu_hal",
];
if CRATES_AT_INFO_LEVEL
.iter()
.any(|crate_name| metadata.target().starts_with(crate_name))
{
return metadata.level() <= log::LevelFilter::Info;
}
metadata.level() <= self.filter
}
fn log(&self, record: &log::Record<'_>) {
#![expect(clippy::match_same_arms)]
if !self.enabled(record.metadata()) {
return;
}
let msg = if let (Some(file), Some(line)) = (record.file(), record.line()) {
let file = shorten_file_path(file);
format!("[{}] {file}:{line}: {}", record.target(), record.args())
} else {
format!("[{}] {}", record.target(), record.args())
};
match record.level() {
log::Level::Trace => console::debug(&msg),
log::Level::Debug => console::debug(&msg),
log::Level::Info => console::info(&msg),
log::Level::Warn => console::warn(&msg),
log::Level::Error => console::warn(&format!("ERROR: {msg}")),
}
}
fn flush(&self) {}
}
mod console {
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
pub fn trace(s: &str);
#[wasm_bindgen(js_namespace = console)]
pub fn debug(s: &str);
#[wasm_bindgen(js_namespace = console)]
pub fn info(s: &str);
#[wasm_bindgen(js_namespace = console)]
pub fn warn(s: &str);
}
}
#[allow(clippy::allow_attributes, dead_code)] fn shorten_file_path(file_path: &str) -> &str {
if let Some(i) = file_path.rfind("/src/") {
if let Some(prev_slash) = file_path[..i].rfind('/') {
&file_path[prev_slash + 1..]
} else {
file_path
}
} else {
file_path
}
}
#[test]
fn test_shorten_file_path() {
for (before, after) in [
(
"/Users/emilk/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.24.1/src/runtime/runtime.rs",
"tokio-1.24.1/src/runtime/runtime.rs",
),
("crates/rerun/src/main.rs", "rerun/src/main.rs"),
(
"/rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/ops/function.rs",
"core/src/ops/function.rs",
),
("/weird/path/file.rs", "/weird/path/file.rs"),
] {
assert_eq!(shorten_file_path(before), after);
}
}