pumpkin_core/statistics/
statistic_logging.rs1use std::fmt::Debug;
5use std::fmt::Display;
6use std::fmt::Formatter;
7use std::io::stdout;
8use std::io::Write;
9use std::sync::OnceLock;
10use std::sync::RwLock;
11
12use convert_case::Case;
13use convert_case::Casing;
14
15pub struct StatisticOptions<'a> {
18 statistic_prefix: &'a str,
21 after_statistics: Option<&'a str>,
23 statistics_casing: Option<Case>,
25 statistics_writer: Box<dyn Write + Send + Sync>,
27}
28
29impl Debug for StatisticOptions<'_> {
30 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
31 f.debug_struct("StatisticOptions")
32 .field("statistic_prefix", &self.statistic_prefix)
33 .field("after_statistics", &self.after_statistics)
34 .field("statistics_casing", &self.statistics_casing)
35 .field("statistics_writer", &"<Writer>")
36 .finish()
37 }
38}
39
40static STATISTIC_OPTIONS: OnceLock<RwLock<StatisticOptions>> = OnceLock::new();
41
42pub fn configure_statistic_logging(
49 prefix: &'static str,
50 after: Option<&'static str>,
51 casing: Option<Case>,
52 writer: Option<Box<dyn Write + Send + Sync>>,
53) {
54 let _ = STATISTIC_OPTIONS.get_or_init(|| {
55 RwLock::from(StatisticOptions {
56 statistic_prefix: prefix,
57 after_statistics: after,
58 statistics_casing: casing,
59 statistics_writer: writer.unwrap_or(Box::new(stdout())),
60 })
61 });
62}
63
64pub fn log_statistic(name: impl Display, value: impl Display) {
67 if let Some(statistic_options_lock) = STATISTIC_OPTIONS.get() {
68 if let Ok(mut statistic_options) = statistic_options_lock.write() {
69 let name = if let Some(casing) = &statistic_options.statistics_casing {
70 name.to_string().to_case(*casing)
71 } else {
72 name.to_string()
73 };
74 let prefix = statistic_options.statistic_prefix;
75 let _ = writeln!(
76 statistic_options.statistics_writer,
77 "{prefix} {name}={value}"
78 );
79 }
80 }
81}
82
83pub fn log_statistic_postfix() {
89 if let Some(statistic_options_lock) = STATISTIC_OPTIONS.get() {
90 if let Ok(mut statistic_options) = statistic_options_lock.write() {
91 if let Some(post_fix) = statistic_options.after_statistics {
92 let _ = writeln!(statistic_options.statistics_writer, "{post_fix}");
93 }
94 }
95 }
96}
97
98pub fn should_log_statistics() -> bool {
101 STATISTIC_OPTIONS.get().is_some()
102}