Add a config for writing logs to a file (#6449)

This commit is contained in:
teor 2023-04-04 07:23:11 +10:00 committed by GitHub
parent f92db25f72
commit a049e2084c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 1 deletions

View File

@ -101,6 +101,10 @@ pub struct Config {
/// replaced with `.folded` and `.svg` for the respective files.
pub flamegraph: Option<PathBuf>,
/// If set to a path, write the tracing logs to that path.
/// By default, logs are sent to the terminal standard output.
pub log_file: Option<PathBuf>,
/// The use_journald flag sends tracing events to systemd-journald, on Linux
/// distributions that use systemd.
///
@ -117,6 +121,7 @@ impl Default for Config {
buffer_limit: 128_000,
endpoint_addr: None,
flamegraph: None,
log_file: None,
use_journald: false,
}
}

View File

@ -1,5 +1,7 @@
//! The Abscissa component for Zebra's `tracing` implementation.
use std::{fs::File, io::Write};
use abscissa_core::{Component, FrameworkError, Shutdown};
use tracing_error::ErrorLayer;
use tracing_subscriber::{
@ -17,6 +19,9 @@ use crate::{application::app_version, components::tracing::Config};
#[cfg(feature = "flamegraph")]
use super::flame;
/// A type-erased boxed writer that can be sent between threads safely.
pub type BoxWrite = Box<dyn Write + Send + Sync + 'static>;
/// Abscissa component for initializing the `tracing` subsystem
pub struct Tracing {
/// The installed filter reloading handle, if enabled.
@ -43,16 +48,26 @@ pub struct Tracing {
impl Tracing {
/// Try to create a new [`Tracing`] component with the given `filter`.
#[allow(clippy::print_stdout, clippy::print_stderr)]
pub fn new(config: Config) -> Result<Self, FrameworkError> {
let filter = config.filter.unwrap_or_default();
let flame_root = &config.flamegraph;
let writer = if let Some(log_file) = config.log_file.as_ref() {
println!("running zebra, sending logs to {log_file:?}...");
let log_file = File::options().append(true).create(true).open(log_file)?;
Box::new(log_file) as BoxWrite
} else {
let stdout = std::io::stdout();
Box::new(stdout) as BoxWrite
};
// Builds a lossy NonBlocking logger with a default line limit of 128_000 or an explicit buffer_limit.
// The write method queues lines down a bounded channel with this capacity to a worker thread that writes to stdout.
// Increments error_counter and drops lines when the buffer is full.
let (non_blocking, _guard) = NonBlockingBuilder::default()
.buffered_lines_limit(config.buffer_limit.max(100))
.finish(std::io::stdout());
.finish(writer);
// Only use color if tracing output is being sent to a terminal or if it was explicitly
// forced to.