trz_gateway_common/
tracing.rs

1//! Utils to enable [::tracing].
2
3use std::panic::Location;
4
5use nameth::NamedEnumValues as _;
6use nameth::nameth;
7use tracing::debug;
8use tracing::level_filters::LevelFilter;
9use tracing::subscriber::SetGlobalDefaultError;
10use tracing::warn;
11use tracing_subscriber::EnvFilter;
12
13/// Enables tracing and registers a [panic hook](std::panic::set_hook).
14pub fn enable_tracing() -> Result<(), EnableTracingError> {
15    let subscriber = tracing_subscriber::fmt()
16        .compact()
17        .with_file(cfg!(debug_assertions))
18        .with_line_number(cfg!(debug_assertions))
19        .with_target(false)
20        .with_max_level(LevelFilter::DEBUG)
21        .with_env_filter(EnvFilter::new("debug,tower=info,h2=info,hyper_util=info"))
22        .finish();
23    tracing::subscriber::set_global_default(subscriber)?;
24    debug!("Tracing enabled");
25
26    std::panic::set_hook(Box::new(|panic_info| {
27        let panic_payload: Option<&str> =
28            if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
29                Some(s)
30            } else if let Some(s) = panic_info.payload().downcast_ref::<String>() {
31                Some(s.as_str())
32            } else {
33                None
34            };
35        let location = panic_info
36            .location()
37            .map(Location::to_string)
38            .unwrap_or_else(|| "???".into());
39        if let Some(panic_payload) = panic_payload {
40            warn!("Panic: {panic_payload} at {location}");
41        } else {
42            warn!("Panic at {location}");
43        }
44    }));
45    Ok(())
46}
47
48/// Errors thrown by [enable_tracing] when trying to enable tracing multiple times.
49#[nameth]
50#[derive(thiserror::Error, Debug)]
51pub enum EnableTracingError {
52    #[error("[{n}] {0}", n = self.name())]
53    SetGlobalDefault(#[from] SetGlobalDefaultError),
54}
55
56#[cfg(debug_assertions)]
57pub mod test_utils {
58    use std::sync::Once;
59
60    pub fn enable_tracing_for_tests() {
61        static ONCE: Once = Once::new();
62        ONCE.call_once(|| super::enable_tracing().unwrap());
63    }
64}