use std::fmt::Display;
use schemars::JsonSchema;
use serde::Deserialize;
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub(crate) struct LoggerConfig {
#[serde(default = "default_true")]
pub enable: bool,
#[serde(default)]
pub pretty_backtrace: bool,
#[serde(default)]
pub level: LogLevel,
#[serde(default)]
pub format: Format,
pub override_filter: Option<String>,
#[serde(rename = "file")]
pub file_appender: Option<LoggerFileAppender>,
}
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
pub(crate) enum LogLevel {
#[serde(rename = "off")]
Off,
#[serde(rename = "trace")]
Trace,
#[serde(rename = "debug")]
Debug,
#[serde(rename = "info")]
#[default]
Info,
#[serde(rename = "warn")]
Warn,
#[serde(rename = "error")]
Error,
}
impl Display for LogLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Off => "off",
Self::Trace => "trace",
Self::Debug => "debug",
Self::Info => "info",
Self::Warn => "warn",
Self::Error => "error",
}
)
}
}
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
pub(crate) enum Format {
#[serde(rename = "compact")]
#[default]
Compact,
#[serde(rename = "pretty")]
Pretty,
#[serde(rename = "json")]
Json,
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub(crate) struct LoggerFileAppender {
pub enable: bool,
#[serde(default = "default_true")]
pub non_blocking: bool,
#[serde(default)]
pub format: Format,
#[serde(default)]
pub rotation: Rotation,
#[serde(default = "default_dir")]
pub dir: String,
#[serde(default = "default_prefix")]
pub filename_prefix: String,
#[serde(default = "default_suffix")]
pub filename_suffix: String,
#[serde(default = "default_max_log_files")]
pub max_log_files: usize,
}
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
pub(crate) enum Rotation {
#[serde(rename = "minutely")]
Minutely,
#[serde(rename = "hourly")]
Hourly,
#[serde(rename = "daily")]
#[default]
Daily,
#[serde(rename = "never")]
Never,
}
fn default_dir() -> String {
"./logs".to_string()
}
fn default_prefix() -> String {
"app".to_string()
}
fn default_suffix() -> String {
"log".to_string()
}
fn default_max_log_files() -> usize {
365
}
fn default_true() -> bool {
true
}
#[allow(clippy::from_over_into)]
impl Into<tracing_appender::rolling::Rotation> for Rotation {
fn into(self) -> tracing_appender::rolling::Rotation {
match self {
Self::Minutely => tracing_appender::rolling::Rotation::MINUTELY,
Self::Hourly => tracing_appender::rolling::Rotation::HOURLY,
Self::Daily => tracing_appender::rolling::Rotation::DAILY,
Self::Never => tracing_appender::rolling::Rotation::NEVER,
}
}
}