Skip to main content

veilid_core/logging/veilid_tracing/
log_output.rs

1use tracing_subscriber::Registry;
2
3use super::*;
4
5use std::path::{Path, PathBuf};
6
7#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
8pub enum LogOutputKind {
9    StdOut,
10    StdErr,
11    File,
12    Api,
13    Layer(String),
14}
15
16/// A log output to be included in the `log_outputs` parameter of `VeilidLog::try_init`
17///
18/// Example: (debug logs to the terminal, and informational logs to the api tracing layer)
19/// ```rust,no_run
20/// # use veilid_core::*;
21/// let log_outputs = [
22///     LogOutput::stdout(true).with_common_log_level(VeilidConfigLogLevel::Debug),
23///     LogOutput::api().with_common_log_level(VeilidConfigLogLevel::Info)
24/// ];
25/// ```
26/// Example: (no logs to the terminal)
27/// ```
28/// # use veilid_core::*;
29/// let log_outputs = [LogOutput::stdout(true)];
30///
31/// let logs = VeilidTracing::try_init(log_outputs).expect("logs failed to initialize");
32/// // ...
33/// logs.try_apply_facility_level("#common", VeilidConfigLogLevel::Debug).expect("should set log level");
34/// ```
35#[must_use]
36pub struct LogOutput {
37    pub(super) kind: LogOutputKind,
38    pub(super) color: bool,
39    pub(super) path: PathBuf,
40    pub(super) append: bool,
41    pub(super) directives: Vec<VeilidLogDirective>,
42    pub(super) layer: Option<LogOutputLayer>,
43}
44
45pub type LogOutputLayer =
46    Box<dyn tracing_subscriber::layer::Layer<Registry> + Send + Sync + 'static>;
47
48impl LogOutput {
49    /// Creates a log writing to standard output
50    pub fn stdout(color: bool) -> Self {
51        Self {
52            kind: LogOutputKind::StdOut,
53            color,
54            path: PathBuf::new(),
55            append: false,
56            directives: vec![],
57            layer: None,
58        }
59    }
60
61    /// Creates a log writing to standard error
62    pub fn stderr(color: bool) -> Self {
63        Self {
64            kind: LogOutputKind::StdErr,
65            color,
66            path: PathBuf::new(),
67            append: false,
68            directives: vec![],
69            layer: None,
70        }
71    }
72
73    /// Creates a log writing to a file on disk
74    pub fn file<P: AsRef<Path>>(path: P, append: bool) -> Self {
75        Self {
76            kind: LogOutputKind::File,
77            color: false,
78            path: path.as_ref().to_owned(),
79            append,
80            directives: vec![],
81            layer: None,
82        }
83    }
84
85    /// Create a log that sends log output to `VeilidUpdate::Log` events
86    pub fn api() -> Self {
87        Self {
88            kind: LogOutputKind::Api,
89            color: false,
90            path: PathBuf::new(),
91            append: false,
92            directives: vec![],
93            layer: None,
94        }
95    }
96
97    /// Creates a log that accepts an arbitrary `tracing` layer
98    pub fn layer<L>(name: String, layer: LogOutputLayer) -> Self {
99        Self {
100            kind: LogOutputKind::Layer(name),
101            color: false,
102            path: PathBuf::new(),
103            append: false,
104            directives: vec![],
105            layer: Some(layer),
106        }
107    }
108
109    /// Convenience function that applies a default log level to the 'veilid::common' Veilid log tags
110    pub fn with_common_log_level(mut self, level: VeilidConfigLogLevel) -> Self {
111        self.directives
112            .push(VeilidLogDirective::try_facility_level("veilid::common", Some(level)).unwrap());
113        self
114    }
115
116    /// Change which log facilities are enabled by default on this log output.
117    /// This can also be changed after the VeilidLog is initialized.
118    pub fn try_with_directives<C: TryIntoIterVeilidLogDirective>(
119        mut self,
120        directives: C,
121    ) -> VeilidAPIResult<Self> {
122        let mut directives = directives.try_into_iter()?.collect();
123        self.directives.append(&mut directives);
124        Ok(self)
125    }
126}