Skip to main content

log_full/
config.rs

1//! 配置管理模块
2//! 
3//! 提供灵活的配置加载和管理功能
4
5use crate::error::{ LogResult};
6use std::collections::HashMap;
7use std::path::Path;
8
9/// 日志配置结构
10#[derive(Debug, Clone)]
11pub struct LogConfig {
12    /// 日志级别
13    pub level: String,
14    /// 输出文件路径
15    pub file_path: Option<String>,
16    /// 是否启用控制台输出
17    pub console_output: bool,
18    /// 是否启用详细模式
19    pub verbose: bool,
20    /// 日志格式
21    pub format: LogFormat,
22    /// 文件轮转配置
23    pub rotation: Option<RotationConfig>,
24    /// 关键词高亮配置
25    pub highlight: HighlightConfig,
26    /// 过滤器配置
27    pub filters: Vec<FilterConfig>,
28    /// 自定义字段
29    pub custom_fields: HashMap<String, String>,
30}
31
32/// 日志格式配置
33#[derive(Debug, Clone)]
34pub struct LogFormat {
35    /// 时间格式
36    pub time_format: String,
37    /// 是否显示文件名
38    pub show_file: bool,
39    /// 是否显示行号
40    pub show_line: bool,
41    /// 是否显示模块路径
42    pub show_module: bool,
43    /// 自定义格式模板
44    pub template: Option<String>,
45}
46
47/// 文件轮转配置
48#[derive(Debug, Clone)]
49pub struct RotationConfig {
50    /// 最大文件大小(字节)
51    pub max_size: u64,
52    /// 保留的文件数量
53    pub max_files: u32,
54    /// 是否启用压缩
55    pub compress: bool,
56}
57
58/// 关键词高亮配置
59#[derive(Debug, Clone)]
60pub struct HighlightConfig {
61    /// 是否启用高亮
62    pub enabled: bool,
63    /// 关键词列表
64    pub keywords: Vec<String>,
65    /// 高亮颜色映射
66    pub color_map: HashMap<String, String>,
67}
68
69/// 过滤器配置
70#[derive(Debug, Clone)]
71pub struct FilterConfig {
72    /// 过滤器类型
73    pub filter_type: FilterType,
74    /// 过滤规则
75    pub rule: String,
76    /// 是否启用
77    pub enabled: bool,
78}
79
80/// 过滤器类型
81#[derive(Debug, Clone)]
82pub enum FilterType {
83    /// 正则表达式过滤
84    Regex,
85    /// 关键词过滤
86    Keyword,
87    /// 级别过滤
88    Level,
89    /// 模块过滤
90    Module,
91}
92
93impl Default for LogConfig {
94    fn default() -> Self {
95        Self {
96            level: "info".to_string(),
97            file_path: None,
98            console_output: true,
99            verbose: false,
100            format: LogFormat::default(),
101            rotation: None,
102            highlight: HighlightConfig::default(),
103            filters: Vec::new(),
104            custom_fields: HashMap::new(),
105        }
106    }
107}
108
109impl Default for LogFormat {
110    fn default() -> Self {
111        Self {
112            time_format: "%Y-%m-%d %H:%M:%S".to_string(),
113            show_file: true,
114            show_line: true,
115            show_module: false,
116            template: None,
117        }
118    }
119}
120
121impl Default for HighlightConfig {
122    fn default() -> Self {
123        Self {
124            enabled: false,
125            keywords: Vec::new(),
126            color_map: HashMap::new(),
127        }
128    }
129}
130
131/// 配置构建器
132pub struct ConfigBuilder {
133    config: LogConfig,
134}
135
136impl ConfigBuilder {
137    /// 创建新的配置构建器
138    pub fn new() -> Self {
139        Self {
140            config: LogConfig::default(),
141        }
142    }
143    
144    /// 设置日志级别
145    pub fn level<S: Into<String>>(mut self, level: S) -> Self {
146        self.config.level = level.into();
147        self
148    }
149    
150    /// 设置输出文件
151    pub fn file<P: AsRef<Path>>(mut self, path: P) -> Self {
152        self.config.file_path = Some(path.as_ref().to_string_lossy().to_string());
153        self
154    }
155    
156    /// 启用/禁用控制台输出
157    pub fn console(mut self, enabled: bool) -> Self {
158        self.config.console_output = enabled;
159        self
160    }
161    
162    /// 启用/禁用详细模式
163    pub fn verbose(mut self, enabled: bool) -> Self {
164        self.config.verbose = enabled;
165        self
166    }
167    
168    /// 设置时间格式
169    pub fn time_format<S: Into<String>>(mut self, format: S) -> Self {
170        self.config.format.time_format = format.into();
171        self
172    }
173    
174    /// 启用文件轮转
175    pub fn rotation(mut self, max_size: u64, max_files: u32, compress: bool) -> Self {
176        self.config.rotation = Some(RotationConfig {
177            max_size,
178            max_files,
179            compress,
180        });
181        self
182    }
183    
184    /// 添加关键词高亮
185    pub fn highlight_keywords(mut self, keywords: Vec<String>) -> Self {
186        self.config.highlight.enabled = !keywords.is_empty();
187        self.config.highlight.keywords = keywords;
188        self
189    }
190    
191    /// 添加过滤器
192    pub fn add_filter(mut self, filter_type: FilterType, rule: String) -> Self {
193        self.config.filters.push(FilterConfig {
194            filter_type,
195            rule,
196            enabled: true,
197        });
198        self
199    }
200    
201    /// 添加自定义字段
202    pub fn custom_field<K: Into<String>, V: Into<String>>(mut self, key: K, value: V) -> Self {
203        self.config.custom_fields.insert(key.into(), value.into());
204        self
205    }
206    
207    /// 构建配置
208    pub fn build(self) -> LogConfig {
209        self.config
210    }
211}
212
213/// 配置加载器
214pub struct ConfigLoader;
215
216impl ConfigLoader {
217    /// 从文件加载配置(简化版本)
218    pub fn from_file<P: AsRef<Path>>(_path: P) -> LogResult<LogConfig> {
219        // 返回默认配置
220        Ok(LogConfig::default())
221    }
222    
223    /// 从环境变量加载配置(简化版本)
224    pub fn from_env() -> LogResult<LogConfig> {
225        // 返回默认配置
226        Ok(LogConfig::default())
227    }
228    
229    /// 保存配置到文件(简化版本)
230    pub fn save_to_file<P: AsRef<Path>>(_config: &LogConfig, _path: P) -> LogResult<()> {
231        // 简化实现,不执行实际保存
232        Ok(())
233    }
234}
235
236#[cfg(test)]
237mod tests {
238    use super::*;
239    
240    #[test]
241    fn test_config_builder() {
242        let config = ConfigBuilder::new()
243            .level("debug")
244            .file("/tmp/test.log")
245            .console(true)
246            .verbose(true)
247            .highlight_keywords(vec!["ERROR".to_string(), "WARN".to_string()])
248            .build();
249            
250        assert_eq!(config.level, "debug");
251        assert_eq!(config.file_path, Some("/tmp/test.log".to_string()));
252        assert!(config.console_output);
253        assert!(config.verbose);
254        assert!(config.highlight.enabled);
255        assert_eq!(config.highlight.keywords.len(), 2);
256    }
257}