Add a config for writing logs to a file (#6449)
This commit is contained in:
parent
f92db25f72
commit
a049e2084c
|
@ -101,6 +101,10 @@ pub struct Config {
|
||||||
/// replaced with `.folded` and `.svg` for the respective files.
|
/// replaced with `.folded` and `.svg` for the respective files.
|
||||||
pub flamegraph: Option<PathBuf>,
|
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
|
/// The use_journald flag sends tracing events to systemd-journald, on Linux
|
||||||
/// distributions that use systemd.
|
/// distributions that use systemd.
|
||||||
///
|
///
|
||||||
|
@ -117,6 +121,7 @@ impl Default for Config {
|
||||||
buffer_limit: 128_000,
|
buffer_limit: 128_000,
|
||||||
endpoint_addr: None,
|
endpoint_addr: None,
|
||||||
flamegraph: None,
|
flamegraph: None,
|
||||||
|
log_file: None,
|
||||||
use_journald: false,
|
use_journald: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! The Abscissa component for Zebra's `tracing` implementation.
|
//! The Abscissa component for Zebra's `tracing` implementation.
|
||||||
|
|
||||||
|
use std::{fs::File, io::Write};
|
||||||
|
|
||||||
use abscissa_core::{Component, FrameworkError, Shutdown};
|
use abscissa_core::{Component, FrameworkError, Shutdown};
|
||||||
use tracing_error::ErrorLayer;
|
use tracing_error::ErrorLayer;
|
||||||
use tracing_subscriber::{
|
use tracing_subscriber::{
|
||||||
|
@ -17,6 +19,9 @@ use crate::{application::app_version, components::tracing::Config};
|
||||||
#[cfg(feature = "flamegraph")]
|
#[cfg(feature = "flamegraph")]
|
||||||
use super::flame;
|
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
|
/// Abscissa component for initializing the `tracing` subsystem
|
||||||
pub struct Tracing {
|
pub struct Tracing {
|
||||||
/// The installed filter reloading handle, if enabled.
|
/// The installed filter reloading handle, if enabled.
|
||||||
|
@ -43,16 +48,26 @@ pub struct Tracing {
|
||||||
|
|
||||||
impl Tracing {
|
impl Tracing {
|
||||||
/// Try to create a new [`Tracing`] component with the given `filter`.
|
/// 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> {
|
pub fn new(config: Config) -> Result<Self, FrameworkError> {
|
||||||
let filter = config.filter.unwrap_or_default();
|
let filter = config.filter.unwrap_or_default();
|
||||||
let flame_root = &config.flamegraph;
|
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.
|
// 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.
|
// 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.
|
// Increments error_counter and drops lines when the buffer is full.
|
||||||
let (non_blocking, _guard) = NonBlockingBuilder::default()
|
let (non_blocking, _guard) = NonBlockingBuilder::default()
|
||||||
.buffered_lines_limit(config.buffer_limit.max(100))
|
.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
|
// Only use color if tracing output is being sent to a terminal or if it was explicitly
|
||||||
// forced to.
|
// forced to.
|
||||||
|
|
Loading…
Reference in New Issue