use super::record::LogRecord;
use crate::reporter::{CollectItem, DynReport, Report};
use std::sync::Arc;
use tokio::sync::OnceCell;
static GLOBAL_LOGGER: OnceCell<Logger> = OnceCell::const_new();
pub fn set_global_logger(logger: Logger) {
if GLOBAL_LOGGER.set(logger).is_err() {
panic!("global logger has set")
}
}
pub fn global_logger() -> &'static Logger {
GLOBAL_LOGGER.get().expect("global logger haven't set")
}
pub fn log(record: LogRecord) {
global_logger().log(record);
}
struct Inner {
service_name: String,
instance_name: String,
reporter: Box<DynReport>,
}
#[derive(Clone)]
pub struct Logger {
inner: Arc<Inner>,
}
impl Logger {
pub fn new(
service_name: impl Into<String>,
instance_name: impl Into<String>,
reporter: impl Report + Send + Sync + 'static,
) -> Self {
Self {
inner: Arc::new(Inner {
service_name: service_name.into(),
instance_name: instance_name.into(),
reporter: Box::new(reporter),
}),
}
}
pub fn service_name(&self) -> &str {
&self.inner.service_name
}
pub fn instance_name(&self) -> &str {
&self.inner.instance_name
}
pub fn log(&self, record: LogRecord) {
let data = record.convert_to_log_data(
self.service_name().to_owned(),
self.instance_name().to_owned(),
);
self.inner.reporter.report(CollectItem::Log(Box::new(data)));
}
}