cloudpub_common/
logging.rs

1use anyhow::{Context as _, Result};
2use rolling_file::{BasicRollingFileAppender, RollingConditionBasic};
3use std::path::Path;
4use tracing::debug;
5pub use tracing_appender::non_blocking::WorkerGuard;
6use tracing_log::LogTracer;
7use tracing_subscriber::fmt;
8use tracing_subscriber::prelude::*;
9
10pub fn init_log(
11    level: &str,
12    log_file: &Path,
13    stderr: bool,
14    max_size: usize,
15    max_files: usize,
16) -> Result<WorkerGuard> {
17    let file_appender = BasicRollingFileAppender::new(
18        log_file,
19        RollingConditionBasic::new().max_size(max_size as u64), // 10 MB
20        max_files,
21    )
22    .context("Failed to create rolling file appender")?;
23
24    let (file_writer, guard) = tracing_appender::non_blocking(file_appender);
25
26    let trace_cfg = format!(
27        "{},hyper=error,tokio_postgres=info,pingora_core=info,pingora_proxy=off,pingora_pool=error,tungstenite=info,{}",
28        level,
29        std::env::var("RUST_LOG").unwrap_or_default()
30    );
31
32    let timer = time::format_description::parse(
33        "[year]-[month padding:zero]-[day padding:zero] [hour]:[minute]:[second]",
34    )
35    .context("Failed to parse time format")?;
36
37    let time_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC);
38    let timer = fmt::time::OffsetTime::new(time_offset, timer);
39
40    // Create the file layer with common settings
41    let file_layer = fmt::Layer::default()
42        .with_timer(timer.clone())
43        .with_ansi(false)
44        .with_writer(file_writer);
45
46    // Build a registry with the file layer and conditional stderr layer
47    let registry = tracing_subscriber::registry()
48        .with(tracing_subscriber::EnvFilter::new(trace_cfg))
49        .with(file_layer);
50
51    // Add stderr layer only if requested
52    if stderr {
53        let stderr_layer = fmt::Layer::default()
54            .with_timer(timer)
55            .with_ansi(cfg!(unix))
56            .with_writer(std::io::stderr);
57
58        tracing::subscriber::set_global_default(registry.with(stderr_layer))
59            .context("Failed to set global default subscriber")?;
60    } else {
61        tracing::subscriber::set_global_default(registry)
62            .context("Failed to set global default subscriber")?;
63    }
64
65    LogTracer::init().context("Failed to initialize log tracer")?;
66    log_panics::init();
67
68    debug!("Tracing initialized ({})", level);
69    Ok(guard)
70}