Skip to main content

log_instrument/
lib.rs

1pub use log_instrument_macros::*;
2use std::collections::HashMap;
3use std::fmt::Write;
4use std::sync::Mutex;
5use std::sync::OnceLock;
6
7type InnerPath = Mutex<HashMap<std::thread::ThreadId, Vec<&'static str>>>;
8static PATH: OnceLock<InnerPath> = OnceLock::new();
9fn init_path() -> InnerPath {
10    Mutex::new(HashMap::new())
11}
12
13pub struct __Instrument;
14
15impl __Instrument {
16    pub fn new(s: &'static str) -> __Instrument {
17        // Get log
18        let mut guard = PATH.get_or_init(init_path).lock().unwrap();
19        let id = std::thread::current().id();
20        let prefix = if let Some(spans) = guard.get_mut(&id) {
21            let out = spans.iter().fold(String::new(), |mut s, x| {
22                let _ = write!(s, "::{x}");
23                s
24            });
25            spans.push(s);
26            out
27        } else {
28            guard.insert(id, vec![s]);
29            String::new()
30        };
31
32        // Write log
33        log::trace!("{id:?}{prefix}>>{s}");
34
35        // Return exit struct
36        __Instrument
37    }
38}
39impl std::ops::Drop for __Instrument {
40    fn drop(&mut self) {
41        // Get log
42        let mut guard = PATH.get_or_init(init_path).lock().unwrap();
43        let id = std::thread::current().id();
44        let spans = guard.get_mut(&id).unwrap();
45        let s = spans.pop().unwrap();
46        let out = spans.iter().fold(String::new(), |mut s, x| {
47            let _ = write!(s, "::{x}");
48            s
49        });
50        log::trace!("{id:?}{out}<<{s}");
51    }
52}