1use crate::error::{LoggerError, Result};
2use std::path::{Path, PathBuf};
3use tracing::Level;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum LogOutput {
8 Stdout,
10 File,
12 Both,
14}
15
16#[derive(Debug, Clone)]
18pub struct LoggerConfig {
19 pub level: Level,
21 pub output: LogOutput,
23 pub path: PathBuf,
25 pub max_size: u64,
27 pub max_files: Option<usize>,
29 pub app_name: String,
31}
32
33impl LoggerConfig {
34 pub fn new(
36 level: Level,
37 output: LogOutput,
38 path: impl AsRef<Path>,
39 max_size: u64,
40 max_files: Option<usize>,
41 app_name: impl Into<String>,
42 ) -> Self {
43 Self {
44 level,
45 output,
46 path: path.as_ref().to_path_buf(),
47 max_size,
48 max_files,
49 app_name: app_name.into(),
50 }
51 }
52
53 pub fn validate(&self) -> Result<()> {
55 if self.max_size == 0 {
56 return Err(LoggerError::ConfigError {
57 message: "max_size 必须大于 0".to_string(),
58 });
59 }
60
61 if let Some(max_files) = self.max_files {
62 if max_files == 0 {
63 return Err(LoggerError::ConfigError {
64 message: "max_files 必须大于 0 或为 None".to_string(),
65 });
66 }
67 }
68
69 if self.app_name.is_empty() {
70 return Err(LoggerError::ConfigError {
71 message: "app_name 不能为空".to_string(),
72 });
73 }
74
75 Ok(())
76 }
77
78 pub fn get_base_name(&self) -> Result<String> {
82 if self.path.is_dir() || !self.path.extension().is_some() {
83 Ok(self.app_name.clone())
84 } else {
85 self.path
86 .file_stem()
87 .and_then(|s| s.to_str())
88 .map(|s| s.to_string())
89 .ok_or_else(|| LoggerError::PathError {
90 path: self.path.clone(),
91 })
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_get_base_name_dir() {
102 let config = LoggerConfig::new(
103 Level::INFO,
104 LogOutput::File,
105 "./logs",
106 10 * 1024 * 1024,
107 None,
108 "myapp",
109 );
110 assert_eq!(config.get_base_name().unwrap(), "myapp");
111 }
112
113 #[test]
114 fn test_get_base_name_file() {
115 let config = LoggerConfig::new(
116 Level::INFO,
117 LogOutput::File,
118 "./logs/app.log",
119 10 * 1024 * 1024,
120 None,
121 "myapp",
122 );
123 assert_eq!(config.get_base_name().unwrap(), "app");
124 }
125}
126