diff --git a/Cargo.lock b/Cargo.lock index 8af204ff6..0430f90b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -289,6 +289,21 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "darling" version = "0.20.10" @@ -962,6 +977,7 @@ dependencies = [ "thiserror", "tokio", "tracing", + "tracing-appender", "tracing-error", "tracing-subscriber", "typetag", @@ -1986,6 +2002,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" version = "0.1.27" diff --git a/Cargo.toml b/Cargo.toml index 90df86fc9..35ae54d80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ sysctl = "0.5.4" walkdir = "2.3.3" indexmap = { version = "2.0.2", features = ["serde"] } once_cell = "1.19.0" +tracing-appender = "0.2.3" [dev-dependencies] eyre = { version = "0.6.8", default-features = false, features = [ "track-caller" ] } diff --git a/src/bin/nix-installer.rs b/src/bin/nix-installer.rs index e61f95f08..f13aa0b15 100644 --- a/src/bin/nix-installer.rs +++ b/src/bin/nix-installer.rs @@ -19,7 +19,7 @@ async fn main() -> eyre::Result { let cli = nix_installer::cli::NixInstallerCli::parse(); - cli.instrumentation.setup()?; + let _guard = cli.instrumentation.setup()?; tracing::info!("nix-installer v{}", env!("CARGO_PKG_VERSION")); diff --git a/src/cli/arg/instrumentation.rs b/src/cli/arg/instrumentation.rs index 085eb8df1..9d27eb6e6 100644 --- a/src/cli/arg/instrumentation.rs +++ b/src/cli/arg/instrumentation.rs @@ -1,10 +1,12 @@ -use eyre::WrapErr; use std::error::Error; use std::io::IsTerminal; + +use eyre::WrapErr; use tracing_error::ErrorLayer; -use tracing_subscriber::{ - filter::Directive, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, -}; +use tracing_subscriber::filter::Directive; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::{EnvFilter, Layer as _}; #[derive(Clone, Default, Debug, clap::ValueEnum)] pub enum Logger { @@ -52,45 +54,56 @@ impl Instrumentation { .to_string() } - pub fn setup(&self) -> eyre::Result<()> { - let filter_layer = self.filter_layer()?; + pub fn setup(&self) -> eyre::Result { + let log_path = format!("/tmp/nix-installer.log"); + let trace_log_file = std::fs::File::create(&log_path)?; + let (nonblocking, guard) = tracing_appender::non_blocking(trace_log_file); + let file_layer = tracing_subscriber::fmt::layer() + .with_writer(nonblocking) + .with_filter(EnvFilter::new(format!( + "{}=trace", + env!("CARGO_PKG_NAME").replace('-', "_"), + ))); let registry = tracing_subscriber::registry() - .with(filter_layer) - .with(ErrorLayer::default()); + .with(ErrorLayer::default()) + .with(file_layer); + + let filter_layer = self.filter_layer()?; match self.logger { Logger::Compact => { - let fmt_layer = self.fmt_layer_compact(); - registry.with(fmt_layer).try_init()? + let fmt_layer = self.fmt_layer_compact(filter_layer); + registry.with(fmt_layer).try_init()?; }, Logger::Full => { - let fmt_layer = self.fmt_layer_full(); - registry.with(fmt_layer).try_init()? + let fmt_layer = self.fmt_layer_full(filter_layer); + registry.with(fmt_layer).try_init()?; }, Logger::Pretty => { - let fmt_layer = self.fmt_layer_pretty(); - registry.with(fmt_layer).try_init()? + let fmt_layer = self.fmt_layer_pretty(filter_layer); + registry.with(fmt_layer).try_init()?; }, Logger::Json => { - let fmt_layer = self.fmt_layer_json(); - registry.with(fmt_layer).try_init()? + let fmt_layer = self.fmt_layer_json(filter_layer); + registry.with(fmt_layer).try_init()?; }, } - Ok(()) + Ok(guard) } - pub fn fmt_layer_full(&self) -> impl tracing_subscriber::layer::Layer + pub fn fmt_layer_full(&self, filter: EnvFilter) -> impl tracing_subscriber::layer::Layer where S: tracing::Subscriber + for<'span> tracing_subscriber::registry::LookupSpan<'span>, { tracing_subscriber::fmt::Layer::new() .with_ansi(std::io::stderr().is_terminal()) .with_writer(std::io::stderr) + .with_filter(filter) } - pub fn fmt_layer_pretty(&self) -> impl tracing_subscriber::layer::Layer + pub fn fmt_layer_pretty(&self, filter: EnvFilter) -> impl tracing_subscriber::layer::Layer where S: tracing::Subscriber + for<'span> tracing_subscriber::registry::LookupSpan<'span>, { @@ -98,9 +111,10 @@ impl Instrumentation { .with_ansi(std::io::stderr().is_terminal()) .with_writer(std::io::stderr) .pretty() + .with_filter(filter) } - pub fn fmt_layer_json(&self) -> impl tracing_subscriber::layer::Layer + pub fn fmt_layer_json(&self, filter: EnvFilter) -> impl tracing_subscriber::layer::Layer where S: tracing::Subscriber + for<'span> tracing_subscriber::registry::LookupSpan<'span>, { @@ -108,9 +122,13 @@ impl Instrumentation { .with_ansi(std::io::stderr().is_terminal()) .with_writer(std::io::stderr) .json() + .with_filter(filter) } - pub fn fmt_layer_compact(&self) -> impl tracing_subscriber::layer::Layer + pub fn fmt_layer_compact( + &self, + filter: EnvFilter, + ) -> impl tracing_subscriber::layer::Layer where S: tracing::Subscriber + for<'span> tracing_subscriber::registry::LookupSpan<'span>, { @@ -124,6 +142,7 @@ impl Instrumentation { .with_thread_names(false) .with_file(false) .with_line_number(false) + .with_filter(filter) } pub fn filter_layer(&self) -> eyre::Result {