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
10pub 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}