use std::{
panic::{self, PanicHookInfo},
sync::Once,
};
use log::{LevelFilter, Log, Metadata, Record};
use crate::{
contract::wit::base_runtime_api as contract_wit, service::wit::base_runtime_api as service_wit,
};
static CONTRACT_LOGGER: ContractLogger = ContractLogger;
static SERVICE_LOGGER: ServiceLogger = ServiceLogger;
static INSTALL_LOGGER: Once = Once::new();
#[derive(Clone, Copy, Debug)]
pub struct ContractLogger;
impl ContractLogger {
pub fn install() {
INSTALL_LOGGER.call_once(|| {
log::set_logger(&CONTRACT_LOGGER).expect("Failed to initialize contract logger");
log::set_max_level(LevelFilter::Trace);
panic::set_hook(Box::new(log_panic));
});
}
}
impl Log for ContractLogger {
fn enabled(&self, _: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
contract_wit::log(&record.args().to_string(), record.level().into());
}
fn flush(&self) {}
}
#[derive(Clone, Copy, Debug)]
pub struct ServiceLogger;
impl ServiceLogger {
pub fn install() {
INSTALL_LOGGER.call_once(|| {
log::set_logger(&SERVICE_LOGGER).expect("Failed to initialize service logger");
log::set_max_level(LevelFilter::Trace);
panic::set_hook(Box::new(log_panic));
});
}
}
impl Log for ServiceLogger {
fn enabled(&self, _: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
service_wit::log(&record.args().to_string(), record.level().into());
}
fn flush(&self) {}
}
fn log_panic(info: &PanicHookInfo<'_>) {
log::error!("{info}");
}