use crate::{
model::LogEvent,
subscriber::processor::EventProcessor,
};
use log::{Level, Metadata as LogMetadata, Record};
use std::sync::Arc;
use tracing_core::{
callsite, field,
metadata::Kind,
subscriber::Interest,
Metadata,
};
struct LogCallsite;
impl callsite::Callsite for LogCallsite {
fn set_interest(&self, _interest: Interest) {}
fn metadata(&self) -> &Metadata<'_> {
static DUMMY_METADATA: Metadata<'static> = Metadata::new(
"log_event",
"log",
tracing_core::Level::TRACE,
None,
None,
None,
field::FieldSet::new(&[], callsite::Identifier(&LOG_CALLSITE)),
Kind::EVENT,
);
&DUMMY_METADATA
}
}
static LOG_CALLSITE: LogCallsite = LogCallsite;
pub(crate) struct LogHandler {
processor: Arc<EventProcessor>,
}
impl LogHandler {
pub(crate) fn new(processor: Arc<EventProcessor>) -> Self {
Self { processor }
}
fn build_log_event(&self, record: &Record<'_>) -> LogEvent {
let mut log_event = LogEvent::new(
match record.level() {
Level::Error => tracing_core::Level::ERROR,
Level::Warn => tracing_core::Level::WARN,
Level::Info => tracing_core::Level::INFO,
Level::Debug => tracing_core::Level::DEBUG,
Level::Trace => tracing_core::Level::TRACE,
},
record.target().to_string(),
record.target().to_string(), Some(format!("{}", record.args())),
);
if let Some(path) = record.module_path() {
let _ = log_event.fields.insert(
"module_path".to_string(),
crate::model::LogValue::String(path.to_string()),
);
}
if let Some(file) = record.file() {
let _ = log_event.fields.insert(
"file".to_string(),
crate::model::LogValue::String(file.to_string()),
);
}
if let Some(line) = record.line() {
let _ = log_event
.fields
.insert("line".to_string(), crate::model::LogValue::Int(line as i64));
}
log_event
}
}
impl log::Log for LogHandler {
fn enabled(&self, metadata: &LogMetadata) -> bool {
metadata.level() <= log::max_level()
}
fn log(&self, record: &Record) {
if record.level() > log::max_level() {
return;
}
let log_event = self.build_log_event(record);
let level = log_event.level;
let metadata = Metadata::new(
"log event", record.target(),
level,
record.file(),
record.line(),
record.module_path(),
field::FieldSet::new(&["message"], callsite::Identifier(&LOG_CALLSITE)),
Kind::EVENT,
);
self.processor.process_event(log_event, &metadata);
}
fn flush(&self) {
}
}