ntp_daemon/
tracing.rs

1use crate::config::{
2    format::{LogFormat, LogFormatFields},
3    Config,
4};
5use tracing::info;
6use tracing_subscriber::{filter::Filtered, EnvFilter, Registry};
7
8pub type ReloadHandle = tracing_subscriber::reload::Handle<
9    Filtered<
10        tracing_subscriber::fmt::Layer<Registry, LogFormatFields, LogFormat>,
11        EnvFilter,
12        Registry,
13    >,
14    Registry,
15>;
16
17pub struct TracingState {
18    pub reload_handle: ReloadHandle,
19}
20
21/// Setup tracing. Since we know the settings of some subscribers only once
22/// the full configuration has been loaded, this returns an FnOnce to complete
23/// setup when the config is available.
24pub fn init(
25    filter: EnvFilter,
26    format: LogFormat,
27) -> impl FnOnce(&mut Config, bool, bool) -> Result<TracingState, tracing_subscriber::reload::Error>
28{
29    // Setup a tracing subscriber with the bare minimum for now, so that errors
30    // in loading the configuration can be properly logged.
31    use tracing_subscriber::prelude::*;
32    let layer = tracing_subscriber::fmt::layer()
33        .fmt_fields(format.get_format_fields())
34        .event_format(format)
35        .with_filter(filter);
36    let (fmt_layer, fmt_handle) = tracing_subscriber::reload::Layer::new(layer);
37
38    let registry = tracing_subscriber::registry().with(fmt_layer);
39    registry.init();
40
41    // Final setup needs the full configuration
42    #[allow(clippy::let_unit_value)]
43    move |config, has_log_override, has_format_override| -> _ {
44        if has_format_override {
45            info!("Log format override from command line arguments is active");
46        } else {
47            fmt_handle.modify(|l| {
48                *l.inner_mut() = tracing_subscriber::fmt::layer()
49                    .fmt_fields(config.log_format.get_format_fields())
50                    .event_format(config.log_format.clone());
51            })?;
52        }
53
54        if let Some(log_filter) = config.log_filter.take() {
55            if has_log_override {
56                info!("Log filter override from command line arguments is active");
57            } else {
58                fmt_handle.modify(|l| *l.filter_mut() = log_filter)?;
59            }
60        }
61
62        let state = TracingState {
63            reload_handle: fmt_handle,
64        };
65
66        Ok(state)
67    }
68}