diff options
| author | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2026-02-10 09:42:41 +0100 |
|---|---|---|
| committer | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2026-02-10 09:42:41 +0100 |
| commit | e8ce8e080877e3fee1970d66e4b1936e219784d3 (patch) | |
| tree | 36becdb0ae1d20c6184c0e2f88ba25a71bc7d2a5 | |
| parent | ca121961b549ca72e3c959a5951135e216a281cc (diff) | |
| parent | f0c6b199e494dfd8b0726a98014751e57cc31330 (diff) | |
| download | mullvadvpn-test-broken-ci.tar.xz mullvadvpn-test-broken-ci.zip | |
Merge branch 'early-boot-fwlog-doesnt-flush-des-2834'test-broken-ci
| -rw-r--r-- | mullvad-daemon/src/logging.rs | 37 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 26 |
2 files changed, 34 insertions, 29 deletions
diff --git a/mullvad-daemon/src/logging.rs b/mullvad-daemon/src/logging.rs index 2b97d2d2ab..156ba31fb0 100644 --- a/mullvad-daemon/src/logging.rs +++ b/mullvad-daemon/src/logging.rs @@ -2,10 +2,7 @@ use mullvad_logging::{EnvFilter, LevelFilter, silence_crates}; use std::{ io, path::PathBuf, - sync::{ - Arc, - atomic::{AtomicBool, Ordering}, - }, + sync::atomic::{AtomicBool, Ordering}, }; use talpid_core::logging::rotate_log; use tracing_appender::non_blocking; @@ -56,11 +53,12 @@ pub fn is_enabled() -> bool { LOG_ENABLED.load(Ordering::SeqCst) } +/// Handle to interact with the logs. Use it to change the log level at runtime or +/// to receive a stream of logs. #[derive(Clone)] pub struct LogHandle { env_filter: Handle<EnvFilter, Registry>, log_stream: LogStreamer, - _file_appender_guard: Option<Arc<non_blocking::WorkerGuard>>, } /// A location to put logs. @@ -159,17 +157,23 @@ pub fn init_logger( let default_filter = silence_crates(env_filter); // TODO: Switch this to a rolling appender, likely daily or hourly - let (_file_appender_guard, non_blocking_file_appender) = - if let Some(log_location) = log_location.as_ref() { - // NOTE: Make sure to rotate log file *before* initializing any kind of logger. - rotate_log(&log_location.log_path()).map_err(Error::RotateLog)?; - let file_appender = - tracing_appender::rolling::never(&log_location.directory, &log_location.filename); - let (appender, guard) = non_blocking(file_appender); - (Some(Arc::new(guard)), OptionalMakeWriter(Some(appender))) - } else { - (None, OptionalMakeWriter(None)) - }; + let non_blocking_file_appender = if let Some(log_location) = log_location.as_ref() { + // NOTE: Make sure to rotate log file *before* initializing any kind of logger. + rotate_log(&log_location.log_path()).map_err(Error::RotateLog)?; + let file_appender = + tracing_appender::rolling::never(&log_location.directory, &log_location.filename); + let (appender, guard) = non_blocking(file_appender); + // Spawn a task to keep file logger guard alive for the duration of the program. When the tokio + // executor shuts down, its drop function will be called to flush any remaining logs to file. + // Note that calling e.g. `std::process::exit` will prevent this and might result in lost logs. + tokio::spawn(async move { + std::future::pending::<()>().await; + drop(guard); + }); + OptionalMakeWriter(Some(appender)) + } else { + OptionalMakeWriter(None) + }; let (tx, _) = tokio::sync::broadcast::channel(128); let log_stream = LogStreamer { tx }; @@ -178,7 +182,6 @@ pub fn init_logger( let reload_handle = LogHandle { env_filter: reload_handle, log_stream: log_stream.clone(), - _file_appender_guard, }; let reg = tracing_subscriber::registry().with(user_filter); diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index bbc99ca7ee..4a87f976c4 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -35,7 +35,8 @@ fn main() { } }; - log::debug!("Process exiting with code {}", exit_code); + log::debug!("Process exiting with code {exit_code}"); + runtime.shutdown_timeout(Duration::from_millis(100)); std::process::exit(exit_code); } @@ -57,14 +58,14 @@ async fn run() -> Result<(), String> { match config.command { cli::Command::Daemon => { - // uniqueness check must happen before logging initializaton, + // uniqueness check must happen before logging initialization, // as initializing logs will rotate any existing log file. assert_unique().await?; - let (log_location, reload_handle) = init_daemon_logging(config)?; + let (log_location, log_handle) = init_daemon_logging(config)?; log::trace!("Using configuration: {:?}", config); let log_dir = log_location.map(|l| l.directory); - run_standalone(log_dir, reload_handle).await + run_standalone(log_dir, log_handle).await } #[cfg(target_os = "linux")] @@ -118,18 +119,18 @@ fn init_daemon_logging( filename: PathBuf::from("daemon.log"), }); - let reload_handle = init_logger(config, log_location.clone())?; + let log_handle = init_logger(config, log_location.clone())?; if let Some(log_location) = log_location.as_ref() { log::info!("Logging to {}", log_location.log_path().display()); } - Ok((log_location, reload_handle)) + Ok((log_location, log_handle)) } -/// Initialize logging to stder and to the [`EARLY_BOOT_LOG_FILENAME`] +/// Initialize logging to stderr and to the [`EARLY_BOOT_LOG_FILENAME`] #[cfg(target_os = "linux")] fn init_early_boot_logging(config: &cli::Config) { - let logging = get_log_dir(config) + let log_file_location = get_log_dir(config) .ok() .flatten() .map(|log_dir| LogLocation { @@ -139,9 +140,10 @@ fn init_early_boot_logging(config: &cli::Config) { // If it's possible to log to the filesystem - attempt to do so, but failing that mustn't stop // the daemon from starting here. - if init_logger(config, logging).is_err() { + if let Err(e) = init_logger(config, log_file_location) { + eprintln!("Failed to initialize early-boot logging to file: '{e}'"); let _ = init_logger(config, None); - }; + } } /// Initialize logging to stderr and to file (if provided). @@ -163,12 +165,12 @@ fn init_logger( exception_logging::enable(); - let reload_handle = + let log_handle = logging::init_logger(config.log_level, log_location, config.log_stdout_timestamps) .map_err(|e| e.display_chain_with_msg("Unable to initialize logger"))?; log_panics::init(); version::log_version(); - Ok(reload_handle) + Ok(log_handle) } fn get_log_dir(config: &cli::Config) -> Result<Option<PathBuf>, String> { |
