stackable_telemetry/tracing/settings/
file_log.rs

1//! File Log Subscriber Settings.
2
3use std::path::PathBuf;
4
5/// Re-export to save the end crate from an extra import.
6pub use tracing_appender::rolling::Rotation;
7
8use super::{Settings, SettingsToggle};
9
10/// Configure specific settings for the File Log subscriber.
11#[derive(Debug, Default, PartialEq)]
12pub enum FileLogSettings {
13    /// File Log subscriber disabled.
14    #[default]
15    Disabled,
16
17    /// File Log subscriber enabled.
18    Enabled {
19        /// Common subscriber settings that apply to the File Log Subscriber.
20        common_settings: Settings,
21
22        /// Path to directory for log files.
23        file_log_dir: PathBuf,
24
25        /// Log rotation frequency.
26        rotation_period: Rotation,
27
28        /// Suffix for log filenames.
29        filename_suffix: String,
30
31        /// Keep the last `n` files on disk.
32        max_log_files: Option<usize>,
33    },
34}
35
36impl SettingsToggle for FileLogSettings {
37    fn is_enabled(&self) -> bool {
38        match self {
39            FileLogSettings::Disabled => false,
40            FileLogSettings::Enabled { .. } => true,
41        }
42    }
43}
44
45/// For building [`FileLogSettings`].
46///
47/// <div class="warning">
48/// Do not use directly, instead use the [`Settings::builder`] associated function.
49/// </div>
50pub struct FileLogSettingsBuilder {
51    pub(crate) common_settings: Settings,
52    pub(crate) file_log_dir: PathBuf,
53    pub(crate) rotation_period: Rotation,
54    pub(crate) filename_suffix: String,
55    pub(crate) max_log_files: Option<usize>,
56}
57
58impl FileLogSettingsBuilder {
59    /// Set file rotation period.
60    pub fn with_rotation_period(mut self, rotation_period: impl Into<Rotation>) -> Self {
61        self.rotation_period = rotation_period.into();
62        self
63    }
64
65    /// Set maximum number of log files to keep.
66    pub fn with_max_files(mut self, max_log_files: impl Into<Option<usize>>) -> Self {
67        self.max_log_files = max_log_files.into();
68        self
69    }
70
71    /// Consumes self and returns a valid [`FileLogSettings`] instance.
72    pub fn build(self) -> FileLogSettings {
73        FileLogSettings::Enabled {
74            common_settings: self.common_settings,
75            file_log_dir: self.file_log_dir,
76            rotation_period: self.rotation_period,
77            filename_suffix: self.filename_suffix,
78            max_log_files: self.max_log_files,
79        }
80    }
81}
82
83impl<T> From<Option<T>> for FileLogSettings
84where
85    T: Into<FileLogSettings>,
86{
87    fn from(settings: Option<T>) -> Self {
88        match settings {
89            Some(settings) => settings.into(),
90            None => FileLogSettings::default(),
91        }
92    }
93}
94
95#[cfg(test)]
96mod test {
97    use tracing::level_filters::LevelFilter;
98
99    use super::*;
100
101    #[test]
102    fn builds_settings() {
103        let expected = FileLogSettings::Enabled {
104            common_settings: Settings {
105                environment_variable: "hello",
106                default_level: LevelFilter::DEBUG,
107            },
108            file_log_dir: PathBuf::from("/logs"),
109            rotation_period: Rotation::HOURLY,
110            filename_suffix: "tracing-rs.log".to_owned(),
111            max_log_files: Some(6),
112        };
113        let result = Settings::builder()
114            .with_environment_variable("hello")
115            .with_default_level(LevelFilter::DEBUG)
116            .file_log_settings_builder(PathBuf::from("/logs"), "tracing-rs.log")
117            .with_rotation_period(Rotation::HOURLY)
118            .with_max_files(6)
119            .build();
120
121        assert_eq!(expected, result);
122    }
123}