dm_database_sqllog2db/config/
logging.rs1use crate::error::{ConfigError, Error, Result};
2use serde::Deserialize;
3
4pub const LOG_LEVELS: &[&str] = &["trace", "debug", "info", "warn", "error"];
5
6#[derive(Debug, Deserialize, Clone)]
7pub struct LoggingConfig {
8 #[serde(default = "default_file")]
9 pub file: String,
10 #[serde(default = "default_level")]
11 pub level: String,
12 #[serde(default = "default_retention_days")]
13 pub retention_days: usize,
14}
15
16fn default_file() -> String {
17 "logs/sqllog2db.log".to_string()
18}
19
20fn default_level() -> String {
21 "info".to_string()
22}
23
24fn default_retention_days() -> usize {
25 7
26}
27
28impl Default for LoggingConfig {
29 fn default() -> Self {
30 Self {
31 file: "logs/sqllog2db.log".to_string(),
32 level: "info".to_string(),
33 retention_days: 7,
34 }
35 }
36}
37
38impl LoggingConfig {
39 pub fn validate(&self) -> Result<()> {
40 if self.file.trim().is_empty() {
41 return Err(Error::Config(ConfigError::InvalidValue {
42 field: "logging.file".to_string(),
43 value: self.file.clone(),
44 reason: "Log file path cannot be empty".to_string(),
45 }));
46 }
47 if !LOG_LEVELS
48 .iter()
49 .any(|&l| l.eq_ignore_ascii_case(&self.level))
50 {
51 return Err(Error::Config(ConfigError::InvalidLogLevel {
52 level: self.level.clone(),
53 valid_levels: LOG_LEVELS.iter().map(|s| (*s).to_string()).collect(),
54 }));
55 }
56 if self.retention_days == 0 || self.retention_days > 365 {
57 return Err(Error::Config(ConfigError::InvalidValue {
58 field: "logging.retention_days".to_string(),
59 value: self.retention_days.to_string(),
60 reason: "Retention days must be between 1 and 365".to_string(),
61 }));
62 }
63 Ok(())
64 }
65}