devtools_core/
bridge_layer.rs

1use std::str::FromStr;
2
3use tracing_subscriber::layer::Context;
4
5use crate::visitors::EventVisitor;
6
7pub struct BridgeLayer {
8    loggers: Vec<Box<dyn log::Log>>,
9}
10
11impl BridgeLayer {
12    #[must_use]
13    pub fn new(loggers: Vec<Box<dyn log::Log>>) -> Self {
14        Self { loggers }
15    }
16
17    pub fn add_logger(&mut self, logger: Box<dyn log::Log>) {
18        self.loggers.push(logger);
19    }
20}
21
22impl<S> tracing_subscriber::layer::Layer<S> for BridgeLayer
23where
24    S: tracing_core::Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
25{
26    fn on_event(&self, event: &tracing_core::Event<'_>, _ctx: Context<'_, S>) {
27        let metadata = event.metadata();
28
29        let mut visitor = EventVisitor::new(std::ptr::from_ref(metadata) as u64);
30        event.record(&mut visitor);
31        let (message, _fields) = visitor.result();
32
33        if let Some(message) = message {
34            for logger in &self.loggers {
35                logger.log(
36                    &log::Record::builder()
37                        .level(log::Level::from_str(metadata.level().as_str()).unwrap())
38                        .target(metadata.target())
39                        .file(metadata.file())
40                        .line(metadata.line())
41                        .module_path(metadata.module_path())
42                        .args(format_args!("{message}"))
43                        .build(),
44                );
45            }
46        }
47    }
48}