proflogger/
profiler.rs

1use std::time::Instant;
2
3/// Starts a timer when created which logs the elapsed lifetime when it is dropped.
4///
5/// While this can be created and used manually, the [`proflogger_proc::profile`] macro from proflogger-proc is the more ergonomic method of use.
6pub struct AutoLogger {
7    name: &'static str,
8    start: Instant,
9    level: log::Level,
10}
11
12impl AutoLogger {
13    #[must_use]
14    pub fn new(name: &'static str, level: log::Level) -> Self {
15        Self {
16            name,
17            start: Instant::now(),
18            level,
19        }
20    }
21}
22
23impl Drop for AutoLogger {
24    fn drop(&mut self) {
25        log::log!(
26            self.level,
27            "{}: {}",
28            self.name,
29            self.start.elapsed().as_secs_f64()
30        );
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use crate as proflogger;
37    use proflogger::profile;
38
39    #[test]
40    fn test_macro() {
41        // These tests have to be tested manually for now.
42        // First, setting RUST_LOG=trace should show all functions print profiles.
43        // Setting RUST_LOG=warn should show only function2.
44        // Running cargo test --release should not show any.
45
46        env_logger::init();
47
48        #[profile]
49        fn test_profiled_function() {
50            let a = 0;
51            println!("{a}");
52        }
53
54        #[profile(Error)]
55        fn test_profiled_function2() {
56            let a = 0;
57            println!("{a}");
58        }
59
60        #[profile]
61        fn test_profiled_function3(a: i32) -> i32 {
62            println!("{a}");
63            a
64        }
65
66        #[profile]
67        pub fn test_profiled_function4<T>(a: T) -> T {
68            println!("0");
69            return a;
70        }
71
72        #[profile]
73        #[must_use]
74        fn test_profiled_function5(a: usize) -> usize {
75            (0..a).sum()
76        }
77
78        #[profile]
79        async fn test_profiled_function6(a: usize) -> usize {
80            async fn f(n: usize) {
81                log::error!("{n}");
82            }
83            f(a).await;
84
85            (0..a).sum()
86        }
87
88        test_profiled_function();
89        test_profiled_function2();
90        test_profiled_function3(0);
91        test_profiled_function4(0);
92        let _ = test_profiled_function5(1_000_000);
93        pollster::block_on(test_profiled_function6(10));
94    }
95}