kamu_logging/
lib.rs

1#[cfg(all(feature = "systemd", feature = "wasm32"))]
2compile_error!("Feature \"systemd\" can't be combined with \"wasm32\".");
3
4#[cfg(all(feature = "with-actix-web", feature = "wasm32"))]
5compile_error!("Feature \"with-actix-web\" can't be combined with \"wasm32\".");
6
7#[cfg(not(any(feature = "systemd", feature = "wasm32")))]
8compile_error!("At least feature \"systemd\" or \"wasm32\" must be enabled.");
9
10/// basic re-exports
11pub use tracing::{debug, error, info, trace, warn};
12
13#[cfg(all(debug_assertions, feature = "systemd"))]
14const TRACING_FILTER: &str = "debug";
15#[cfg(all(not(debug_assertions), feature = "systemd"))]
16const TRACING_FILTER: &str = "info";
17
18#[cfg(feature = "wasm32")]
19static WASM32_LOG_INIT: std::sync::OnceLock<()> = std::sync::OnceLock::new();
20
21#[cfg(feature = "wasm32")]
22#[derive(thiserror::Error, Debug)]
23pub enum Error {
24    #[error("{0}")]
25    IO(#[from] std::io::Error),
26    #[error("{0}")]
27    TracingGlobal(#[from] tracing::subscriber::SetGlobalDefaultError),
28}
29
30#[cfg(feature = "systemd")]
31#[derive(thiserror::Error, Debug)]
32pub enum Error {
33    #[error("{0}")]
34    IO(#[from] std::io::Error),
35    #[error("{0}")]
36    TracingGlobal(#[from] tracing::subscriber::SetGlobalDefaultError),
37    #[error("{0}")]
38    TracingLog(#[from] tracing_log::log::SetLoggerError),
39}
40
41pub fn init() -> std::result::Result<(), Error> {
42    #[cfg(feature = "systemd")]
43    init_systemd()?;
44    #[cfg(feature = "wasm32")]
45    init_wasm32();
46
47    tracing::info!("Logging initialized");
48
49    Ok(())
50}
51
52#[cfg(feature = "systemd")]
53fn init_systemd() -> std::result::Result<(), Error> {
54    tracing_log::LogTracer::init()?;
55    let filter_layer = tracing_subscriber::EnvFilter::try_from_default_env()
56        .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(TRACING_FILTER));
57    let subscriber = tracing_subscriber::layer::SubscriberExt::with(
58        tracing_subscriber::registry(),
59        filter_layer,
60    );
61
62    if console::Term::stdout().is_term() {
63        let fmt_layer = tracing_subscriber::fmt::layer()
64            .with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE)
65            .with_ansi(true)
66            .with_line_number(true)
67            .with_thread_ids(true);
68        tracing::subscriber::set_global_default(tracing_subscriber::layer::SubscriberExt::with(
69            subscriber, fmt_layer,
70        ))?;
71    } else {
72        let journald_layer = tracing_journald::layer()?;
73        let fmt_layer = tracing_subscriber::fmt::layer()
74            .with_ansi(false)
75            .with_writer(std::io::stderr);
76        let subscriber_with_journald =
77            tracing_subscriber::layer::SubscriberExt::with(subscriber, journald_layer);
78        tracing::subscriber::set_global_default(tracing_subscriber::layer::SubscriberExt::with(
79            subscriber_with_journald,
80            fmt_layer,
81        ))?;
82    }
83
84    Ok(())
85}
86
87#[cfg(feature = "wasm32")]
88fn init_wasm32() {
89    let _ = WASM32_LOG_INIT.get_or_init(|| {
90        console_error_panic_hook::set_once();
91        let _ = wasm_tracing::try_set_as_global_default();
92    });
93}
94
95#[cfg(feature = "with-actix-web")]
96pub fn get_actix_web_logger()
97-> tracing_actix_web::TracingLogger<tracing_actix_web::DefaultRootSpanBuilder> {
98    tracing_actix_web::TracingLogger::default()
99}