use crate::config::{Console, FileAppender};
use crate::{level_from_str, rotation_from_str};
use std::io;
use tracing::Subscriber;
use tracing_appender::rolling::RollingFileAppender;
use tracing_subscriber::fmt::time::ChronoLocal;
use tracing_subscriber::{filter, fmt, registry, Layer};
pub fn get_file_layer<S>(
appender: &FileAppender
) -> impl Layer<S>
where
S: Subscriber + for<'span> registry::LookupSpan<'span> + 'static,
{
let timer = ChronoLocal::new(appender.format.clone());
let level_filter = level_from_str(&appender.level);
let only_level = appender.only_level;
let rotation = rotation_from_str(&appender.rotation);
let file_appender = RollingFileAppender::builder()
.max_log_files(appender.max_files)
.rotation(rotation)
.filename_prefix(&appender.prefix)
.filename_suffix(&appender.suffix)
.build(&appender.directory)
.expect("日志初始化失败");
let target = appender.target.clone();
fmt::layer()
.with_ansi(false)
.with_timer(timer)
.with_thread_names(appender.thread)
.with_writer(file_appender)
.with_line_number(appender.line_number)
.with_filter(level_filter)
.with_filter(filter::filter_fn(move |metadata| {
if only_level {
metadata.level() == &level_filter
} else {
metadata.level() >= &level_filter
}
}))
.with_filter(filter::filter_fn(move |metadata| {
target.is_empty() || metadata.target() == target
}))
}
pub fn get_console_layer<S>(
console: &Console
) -> impl Layer<S>
where
S: Subscriber + for<'span> registry::LookupSpan<'span> + 'static,
{
let timer = ChronoLocal::new(console.format.clone());
let level_filter = level_from_str(&console.level);
fmt::layer()
.with_ansi(false)
.with_timer(timer)
.with_thread_names(console.thread)
.with_line_number(console.line_number)
.with_writer(io::stderr)
.with_filter(level_filter)
}