Skip to main content

runi_log/
lib.rs

1mod format;
2
3use format::UniFormatter;
4use tracing_subscriber::{EnvFilter, fmt, prelude::*};
5
6pub use tracing::Span;
7pub use tracing::{Level, instrument, span};
8pub use tracing::{debug, error, info, trace, warn};
9
10/// Initialize logging with sensible defaults.
11///
12/// - Log level from `RUNI_LOG` env var (default: `info`)
13/// - Uni-style format: `timestamp LEVEL [target] message - (file:line)`
14/// - Colored output for terminals, JSON for non-terminals
15pub fn init() {
16    init_with_env("RUNI_LOG");
17}
18
19/// Initialize logging with a custom env var name for the filter.
20pub fn init_with_env(env_var: &str) {
21    let filter = EnvFilter::try_from_env(env_var).unwrap_or_else(|_| EnvFilter::new("info"));
22
23    let is_terminal = std::io::IsTerminal::is_terminal(&std::io::stderr());
24
25    if is_terminal {
26        tracing_subscriber::registry()
27            .with(filter)
28            .with(fmt::layer().event_format(UniFormatter::new(true)))
29            .init();
30    } else {
31        tracing_subscriber::registry()
32            .with(filter)
33            .with(
34                fmt::layer()
35                    .json()
36                    .with_target(true)
37                    .with_file(true)
38                    .with_line_number(true),
39            )
40            .init();
41    }
42}
43
44/// Initialize logging with a specific level string (e.g., "debug", "warn").
45pub fn init_with_level(level: &str) {
46    let filter = EnvFilter::new(level);
47    tracing_subscriber::registry()
48        .with(filter)
49        .with(fmt::layer().event_format(UniFormatter::new(true)))
50        .init();
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn log_macros_compile() {
59        trace!("trace message");
60        debug!("debug message");
61        info!("info message");
62        warn!("warn message");
63        error!("error message");
64    }
65
66    #[test]
67    fn log_with_fields() {
68        info!(host = "localhost", port = 8080, "server starting");
69        debug!(elapsed_ms = 42, "request completed");
70    }
71
72    #[test]
73    fn span_creation() {
74        let _span = span!(Level::INFO, "my_span", id = 42);
75    }
76}