sh_layer1/observability/
logging.rs1use crate::observability::config::LogFormat;
4use tracing::Level;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum LogLevel {
9 Trace,
10 Debug,
11 Info,
12 Warn,
13 Error,
14}
15
16impl From<LogLevel> for Level {
17 fn from(level: LogLevel) -> Self {
18 match level {
19 LogLevel::Trace => Level::TRACE,
20 LogLevel::Debug => Level::DEBUG,
21 LogLevel::Info => Level::INFO,
22 LogLevel::Warn => Level::WARN,
23 LogLevel::Error => Level::ERROR,
24 }
25 }
26}
27
28impl From<Level> for LogLevel {
29 fn from(level: Level) -> Self {
30 match level {
31 Level::TRACE => LogLevel::Trace,
32 Level::DEBUG => LogLevel::Debug,
33 Level::INFO => LogLevel::Info,
34 Level::WARN => LogLevel::Warn,
35 Level::ERROR => LogLevel::Error,
36 }
37 }
38}
39
40pub fn log(level: LogLevel, message: &str, attributes: &[(&str, &str)]) {
42 let level: Level = level.into();
43
44 match level {
45 Level::TRACE => tracing::trace!(message, ?attributes),
46 Level::DEBUG => tracing::debug!(message, ?attributes),
47 Level::INFO => tracing::info!(message, ?attributes),
48 Level::WARN => tracing::warn!(message, ?attributes),
49 Level::ERROR => tracing::error!(message, ?attributes),
50 }
51}
52
53pub fn init_subscriber(log_format: LogFormat) -> Result<(), String> {
55 use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
56
57 let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
58
59 match log_format {
60 LogFormat::Pretty => {
61 tracing_subscriber::registry()
62 .with(env_filter)
63 .with(tracing_subscriber::fmt::layer().pretty())
64 .try_init()
65 .map_err(|e| format!("Failed to init subscriber: {}", e))?;
66 }
67 LogFormat::Json => {
68 tracing_subscriber::registry()
69 .with(env_filter)
70 .with(tracing_subscriber::fmt::layer().json())
71 .try_init()
72 .map_err(|e| format!("Failed to init subscriber: {}", e))?;
73 }
74 }
75
76 Ok(())
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_log_level_conversion() {
85 assert_eq!(Level::from(LogLevel::Trace), Level::TRACE);
86 assert_eq!(Level::from(LogLevel::Debug), Level::DEBUG);
87 assert_eq!(Level::from(LogLevel::Info), Level::INFO);
88 assert_eq!(Level::from(LogLevel::Warn), Level::WARN);
89 assert_eq!(Level::from(LogLevel::Error), Level::ERROR);
90 }
91
92 #[test]
93 fn test_log_level_reverse_conversion() {
94 assert_eq!(LogLevel::from(Level::TRACE), LogLevel::Trace);
95 assert_eq!(LogLevel::from(Level::DEBUG), LogLevel::Debug);
96 assert_eq!(LogLevel::from(Level::INFO), LogLevel::Info);
97 assert_eq!(LogLevel::from(Level::WARN), LogLevel::Warn);
98 assert_eq!(LogLevel::from(Level::ERROR), LogLevel::Error);
99 }
100
101 #[test]
102 fn test_log_function() {
103 log(LogLevel::Info, "test message", &[("key", "value")]);
105 log(LogLevel::Debug, "another message", &[]);
106 }
107}