mod options;
mod rotation;
pub use options::{LogRotation, LoggingOptions};
use tracing_appender::non_blocking::{NonBlockingBuilder, WorkerGuard};
use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt};
pub use rotation::build_writer;
const FILE_WRITER_BUFFER_LINES: usize = 16_384;
pub fn init(options: LoggingOptions) -> Option<WorkerGuard> {
if cfg!(test) {
return None;
}
install_subscriber(&options)
}
fn non_blocking_writer(options: &LoggingOptions) -> (tracing_appender::non_blocking::NonBlocking, WorkerGuard) {
let writer = build_writer(&options.logs_dir, options.app_name, options.rotation, options.max_files)
.expect("failed to initialize rolling log writer");
NonBlockingBuilder::default()
.buffered_lines_limit(FILE_WRITER_BUFFER_LINES)
.finish(writer)
}
fn install_subscriber(options: &LoggingOptions) -> Option<WorkerGuard> {
let env_filter = EnvFilter::new(options.level.clone());
match (options.file_enabled, options.console_enabled) {
(true, true) => {
let (non_blocking, guard) = non_blocking_writer(options);
tracing_subscriber::registry()
.with(env_filter)
.with(
fmt::layer()
.json()
.with_writer(non_blocking)
.with_ansi(false)
.with_target(true),
)
.with(
fmt::layer()
.with_writer(std::io::stdout)
.with_target(true)
.with_ansi(true),
)
.init();
Some(guard)
}
(true, false) => {
let (non_blocking, guard) = non_blocking_writer(options);
tracing_subscriber::registry()
.with(env_filter)
.with(
fmt::layer()
.json()
.with_writer(non_blocking)
.with_ansi(false)
.with_target(true),
)
.init();
Some(guard)
}
(false, true) => {
tracing_subscriber::registry()
.with(env_filter)
.with(
fmt::layer()
.with_writer(std::io::stdout)
.with_target(true)
.with_ansi(true),
)
.init();
None
}
(false, false) => {
tracing_subscriber::registry().with(env_filter).init();
None
}
}
}