#![doc = include_str!("../README.md")]
mod ui;
use std::sync::LazyLock;
use std::sync::Mutex;
use hashbrown::HashMap;
pub use ui::logger_ui;
pub use ui::LoggerUi;
use log::SetLoggerError;
const LEVELS: [log::Level; log::Level::Trace as usize] = [
log::Level::Error,
log::Level::Warn,
log::Level::Info,
log::Level::Debug,
log::Level::Trace,
];
pub struct EguiLogger;
pub struct Builder {
max_level: log::LevelFilter,
}
impl Default for Builder {
fn default() -> Self {
Self {
max_level: log::LevelFilter::Debug,
}
}
}
impl Builder {
pub fn build(self) -> EguiLogger {
EguiLogger
}
pub fn max_level(mut self, max_level: log::LevelFilter) -> Self {
self.max_level = max_level;
self
}
pub fn init(self) -> Result<(), SetLoggerError> {
log::set_logger(&EguiLogger).map(|()| log::set_max_level(self.max_level))
}
}
impl log::Log for EguiLogger {
fn enabled(&self, metadata: &log::Metadata) -> bool {
metadata.level() <= log::STATIC_MAX_LEVEL
}
fn log(&self, record: &log::Record) {
if self.enabled(record.metadata()) {
if let Ok(ref mut logger) = LOGGER.lock() {
logger.logs.push(Record {
level: record.level(),
message: record.args().to_string(),
target: record.target().to_string(),
time: chrono::Local::now(),
});
if !logger.categories.contains_key(record.target()) {
logger.categories.insert(record.target().to_string(), true);
logger.max_category_length =
logger.max_category_length.max(record.target().len());
}
}
}
}
fn flush(&self) {}
}
#[deprecated(
since = "0.5.0",
note = "Please use `egui_logger::builder().init()` instead"
)]
pub fn init() -> Result<(), SetLoggerError> {
builder().init()
}
#[deprecated(
since = "0.5.0",
note = "Please use `egui_logger::builder().max_level(max_level).init()` instead"
)]
pub fn init_with_max_level(max_level: log::LevelFilter) -> Result<(), SetLoggerError> {
builder().max_level(max_level).init()
}
struct Record {
level: log::Level,
message: String,
target: String,
time: chrono::DateTime<chrono::Local>,
}
struct Logger {
logs: Vec<Record>,
categories: HashMap<String, bool>,
max_category_length: usize,
start_time: chrono::DateTime<chrono::Local>,
}
static LOGGER: LazyLock<Mutex<Logger>> = LazyLock::new(|| {
Mutex::new(Logger {
logs: Vec::new(),
categories: HashMap::new(),
max_category_length: 0,
start_time: chrono::Local::now(),
})
});
pub fn builder() -> Builder {
Builder::default()
}