Skip to main content

log_full/
builder.rs

1//! 日志构建器模块
2//! 
3//! 提供灵活的日志配置构建功能
4
5use crate::error::{LogError, LogResult};
6use crate::init::init_log_inner_with_config;
7use crate::quickwit::QuickwitConfig;
8use std::path::Path;
9
10/// 日志构建器
11pub struct Builder {
12    pub(crate) level: log::LevelFilter,
13    pub(crate) log_file: String,
14    pub(crate) log_file_max: u32,
15    pub(crate) use_console: bool,
16    pub(crate) use_async: bool,
17    pub(crate) plugin: Option<Box<dyn std::io::Write + Send + Sync + 'static>>,
18    pub(crate) filter: Option<Box<dyn crate::CustomFilter>>,
19    pub(crate) show_process_id: bool,
20    pub(crate) show_thread_info: bool,
21    pub(crate) show_module_path: bool,
22    pub(crate) highlight_keywords: Vec<String>,
23    pub(crate) quickwit_config: Option<QuickwitConfig>,
24}
25
26impl Builder {
27    #[inline]
28    pub fn new() -> Self {
29        Self {
30            level: log::LevelFilter::Info,
31            log_file: String::new(),
32            log_file_max: 10 * 1024 * 1024,
33            use_console: true,
34            use_async: true,
35            plugin: None,
36            filter: None,
37            show_process_id: true,
38            show_thread_info: true,
39            show_module_path: true,
40            highlight_keywords: Vec::new(),
41            quickwit_config: None,
42        }
43    }
44
45    /// 验证配置的有效性
46    pub fn validate(&self) -> LogResult<()> {
47        if self.log_file_max == 0 {
48            return Err(LogError::config("Max file size cannot be zero"));
49        }
50        
51        if !self.log_file.is_empty() {
52            if let Some(parent) = Path::new(&self.log_file).parent() {
53                if !parent.exists() {
54                    return Err(LogError::file_operation(
55                        self.log_file.clone(),
56                        "Parent directory does not exist"
57                    ));
58                }
59            }
60        }
61        
62        Ok(())
63    }
64
65    #[inline]
66    pub fn builder(self) -> LogResult<()> {
67        self.validate()?;
68        init_log_inner_with_config(self.level, self.log_file, self.log_file_max,
69            self.use_console, self.use_async, self.plugin, self.filter,
70            self.show_process_id, self.show_thread_info, self.show_module_path,
71            self.highlight_keywords, self.quickwit_config)
72    }
73
74    #[inline]
75    pub fn level(mut self, level: log::LevelFilter) -> Self {
76        self.level = level;
77        self
78    }
79
80    #[inline]
81    pub fn log_file(mut self, log_file: String) -> Self {
82        self.log_file = log_file;
83        self
84    }
85
86    #[inline]
87    pub fn log_file_max(mut self, log_file_max: u32) -> Self {
88        self.log_file_max = log_file_max;
89        self
90    }
91
92    #[inline]
93    pub fn use_console(mut self, use_console: bool) -> Self {
94        self.use_console = use_console;
95        self
96    }
97
98    #[inline]
99    pub fn use_async(mut self, use_async: bool) -> Self {
100        self.use_async = use_async;
101        self
102    }
103
104    #[inline]
105    pub fn level_str(mut self, level: &str) -> LogResult<Self> {
106        self.level = crate::utils::parse_level(level)?;
107        Ok(self)
108    }
109
110    #[inline]
111    pub fn log_file_max_str(mut self, log_file_max: &str) -> LogResult<Self> {
112        self.log_file_max = crate::utils::parse_size(log_file_max)?;
113        Ok(self)
114    }
115
116    pub fn plugin<T: std::io::Write + Send + Sync + 'static>(mut self, plugin: T) -> Self {
117        self.plugin = Some(Box::new(plugin));
118        self
119    }
120
121    pub fn filter(mut self, filter: impl crate::CustomFilter) -> Self {
122        self.filter = Some(Box::new(filter));
123        self
124    }
125
126    /// 设置是否显示进程ID
127    #[inline]
128    pub fn show_process_id(mut self, show: bool) -> Self {
129        self.show_process_id = show;
130        self
131    }
132
133    /// 设置是否显示线程信息
134    #[inline]
135    pub fn show_thread_info(mut self, show: bool) -> Self {
136        self.show_thread_info = show;
137        self
138    }
139
140    /// 设置是否显示模块路径
141    #[inline]
142    pub fn show_module_path(mut self, show: bool) -> Self {
143        self.show_module_path = show;
144        self
145    }
146
147    /// 设置需要高亮显示的关键词
148    #[inline]
149    pub fn highlight_keywords(mut self, keywords: Vec<String>) -> Self {
150        self.highlight_keywords = keywords;
151        self
152    }
153
154    /// 添加单个关键词到高亮列表
155    #[inline]
156    pub fn add_highlight_keyword(mut self, keyword: String) -> Self {
157        self.highlight_keywords.push(keyword);
158        self
159    }
160
161    /// 设置 Quickwit 配置
162    #[inline]
163    pub fn quickwit(mut self, config: QuickwitConfig) -> Self {
164        self.quickwit_config = Some(config);
165        self
166    }
167
168    /// 设置 Quickwit URL 和索引 ID
169    #[inline]
170    pub fn quickwit_simple(mut self, url: String, index_id: String) -> Self {
171        self.quickwit_config = Some(QuickwitConfig::new(url, index_id));
172        self
173    }
174
175    /// 禁用 Quickwit
176    #[inline]
177    pub fn disable_quickwit(mut self) -> Self {
178        self.quickwit_config = None;
179        self
180    }
181}
182
183impl Default for Builder {
184    fn default() -> Self {
185        Self::new()
186    }
187}