Skip to main content

xcom_rs/
logging.rs

1use std::str::FromStr;
2use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
3
4/// Log format options
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum LogFormat {
7    Json,
8    Text,
9}
10
11impl FromStr for LogFormat {
12    type Err = String;
13
14    fn from_str(s: &str) -> Result<Self, Self::Err> {
15        match s.to_lowercase().as_str() {
16            "json" => Ok(LogFormat::Json),
17            "text" => Ok(LogFormat::Text),
18            _ => Err(format!(
19                "Invalid log format '{}'. Valid values: json, text",
20                s
21            )),
22        }
23    }
24}
25
26/// Initialize logging with the specified format and trace ID
27pub fn init_logging(format: LogFormat, trace_id: Option<String>) {
28    let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
29
30    match format {
31        LogFormat::Json => {
32            let fmt_layer = fmt::layer()
33                .json()
34                .with_current_span(true)
35                .with_span_list(false)
36                .with_writer(std::io::stderr);
37
38            tracing_subscriber::registry()
39                .with(filter)
40                .with(fmt_layer)
41                .init();
42        }
43        LogFormat::Text => {
44            let fmt_layer = fmt::layer().with_writer(std::io::stderr).with_target(false);
45
46            tracing_subscriber::registry()
47                .with(filter)
48                .with(fmt_layer)
49                .init();
50        }
51    }
52
53    // Log the trace ID if provided
54    if let Some(tid) = trace_id {
55        tracing::info!(traceId = %tid, "Request started");
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62    use std::str::FromStr;
63
64    #[test]
65    fn test_log_format_from_str() {
66        assert_eq!(LogFormat::from_str("json").unwrap(), LogFormat::Json);
67        assert_eq!(LogFormat::from_str("JSON").unwrap(), LogFormat::Json);
68        assert_eq!(LogFormat::from_str("text").unwrap(), LogFormat::Text);
69        assert_eq!(LogFormat::from_str("TEXT").unwrap(), LogFormat::Text);
70        assert!(LogFormat::from_str("anything").is_err());
71        assert!(LogFormat::from_str("invalid").is_err());
72    }
73}