use serde::{Deserialize, Serialize};
use std::fmt;
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LogLevel {
Error = 1,
Warn = 2,
Info = 3,
Debug = 4,
Trace = 5,
}
impl From<LogLevel> for tracing::Level {
fn from(level: LogLevel) -> Self {
match level {
LogLevel::Error => tracing::Level::ERROR,
LogLevel::Warn => tracing::Level::WARN,
LogLevel::Info => tracing::Level::INFO,
LogLevel::Debug => tracing::Level::DEBUG,
LogLevel::Trace => tracing::Level::TRACE,
}
}
}
impl fmt::Display for LogLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LogLevel::Error => write!(f, "ERROR"),
LogLevel::Warn => write!(f, "WARN"),
LogLevel::Info => write!(f, "INFO"),
LogLevel::Debug => write!(f, "DEBUG"),
LogLevel::Trace => write!(f, "TRACE"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum RollingPolicy {
Time(TimeRollingConfig),
Size(SizeRollingConfig),
Compound {
time: TimeRollingConfig,
size: SizeRollingConfig,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TimeRollingConfig {
pub period: TimePeriod,
pub keep_days: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum TimePeriod {
Hourly,
Daily,
Weekly,
Monthly,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SizeRollingConfig {
pub max_size: u64,
pub max_files: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LogFormat {
Text(TextFormatConfig),
Json(JsonFormatConfig),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TextFormatConfig {
pub time_format: String,
pub show_level: bool,
pub show_target: bool,
pub show_thread_id: bool,
pub show_file: bool,
pub show_line: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JsonFormatConfig {
pub time_format: String,
pub pretty: bool,
pub include_caller: bool,
pub include_thread: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoggerConfig {
pub level: LogLevel,
pub dir: PathBuf,
pub filename: String,
pub rolling_policy: RollingPolicy,
pub format: LogFormat,
pub async_write: bool,
pub split_by_level: bool,
pub console: Option<ConsoleConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConsoleConfig {
pub enabled: bool,
pub level: LogLevel,
pub colored: bool,
}
impl Default for LoggerConfig {
fn default() -> Self {
Self {
level: LogLevel::Info,
dir: PathBuf::from("logs"),
filename: "app.log".to_string(),
rolling_policy: RollingPolicy::Time(TimeRollingConfig {
period: TimePeriod::Daily,
keep_days: 30,
}),
format: LogFormat::Text(TextFormatConfig {
time_format: "%Y-%m-%d %H:%M:%S%.3f".to_string(),
show_level: true,
show_target: true,
show_thread_id: true,
show_file: true,
show_line: true,
}),
async_write: true,
split_by_level: false,
console: Some(ConsoleConfig {
enabled: true,
level: LogLevel::Info,
colored: true,
}),
}
}
}