mt_debug_counters/
logging.rs

1use crate::counter::{get_counter_value, COUNTER_SUFFIX, __COUNTERS_LIST};
2use bytesize::ByteSize;
3use json::{object, JsonValue};
4use std::fs::File;
5use std::io::Write;
6use std::path::Path;
7use std::thread::sleep;
8use std::time::{Duration, Instant};
9
10pub fn enable_counters_logging(
11    file: impl AsRef<Path>,
12    interval: Duration,
13    callback: impl Fn(&mut JsonValue) + Send + 'static,
14) {
15    let mut file = File::create(file).unwrap();
16    let time = Instant::now();
17
18    std::thread::spawn(move || {
19        let mut keys = Vec::new();
20        loop {
21            sleep(interval);
22            {
23                keys.clear();
24                let list = __COUNTERS_LIST.lock();
25                keys.extend(list.keys().cloned());
26            }
27
28            let mut json_values = object! {};
29
30            json_values["_time"] = time.elapsed().as_secs_f64().into();
31
32            for name in &keys {
33                // Skip average counters
34                if name.ends_with(COUNTER_SUFFIX) {
35                    continue;
36                }
37
38                let (value, avg_counter) = get_counter_value(&name);
39
40                // Average, use floating point
41                if avg_counter > 0 {
42                    let avg_value = (value as f64) / (avg_counter as f64);
43                    let values: [JsonValue; 3] = [
44                        avg_value.into(),
45                        avg_counter.into(),
46                        format!("{}", ByteSize(avg_value as u64)).into(),
47                    ];
48                    json_values[name] = values.as_ref().into();
49                } else {
50                    let values: [JsonValue; 2] = [
51                        value.into(),
52                        format!("{}", ByteSize(value.abs() as u64)).into(),
53                    ];
54                    json_values[name] = values.as_ref().into();
55                }
56            }
57
58            callback(&mut json_values);
59
60            let _ = writeln!(file, "{}", json_values);
61        }
62    });
63}