mt_debug_counters/
logging.rs1use 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 if name.ends_with(COUNTER_SUFFIX) {
35 continue;
36 }
37
38 let (value, avg_counter) = get_counter_value(&name);
39
40 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}