fix: make logger work while loading config file (#581)
This commit is contained in:
@@ -17,17 +17,19 @@ use regex::Regex;
|
||||
use regex_split::RegexSplit;
|
||||
use serde::Deserialize;
|
||||
use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator};
|
||||
use tracing::debug;
|
||||
use which_crate::which;
|
||||
|
||||
use super::utils::{editor, hostname};
|
||||
use crate::command::CommandExt;
|
||||
use crate::sudo::SudoKind;
|
||||
use crate::utils::string_prepend_str;
|
||||
|
||||
use super::utils::{editor, hostname};
|
||||
use tracing::{debug, error};
|
||||
|
||||
pub static EXAMPLE_CONFIG: &str = include_str!("../config.example.toml");
|
||||
|
||||
/// Topgrade's default log level.
|
||||
pub const DEFAULT_LOG_LEVEL: &str = "warn";
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! str_value {
|
||||
($section:ident, $value:ident) => {
|
||||
@@ -607,11 +609,11 @@ impl ConfigFile {
|
||||
*/
|
||||
for include in dir_include {
|
||||
let include_contents = fs::read_to_string(&include).map_err(|e| {
|
||||
tracing::error!("Unable to read {}", include.display());
|
||||
error!("Unable to read {}", include.display());
|
||||
e
|
||||
})?;
|
||||
let include_contents_parsed = toml::from_str(include_contents.as_str()).map_err(|e| {
|
||||
tracing::error!("Failed to deserialize {}", include.display());
|
||||
error!("Failed to deserialize {}", include.display());
|
||||
e
|
||||
})?;
|
||||
|
||||
@@ -628,7 +630,7 @@ impl ConfigFile {
|
||||
}
|
||||
|
||||
let mut contents_non_split = fs::read_to_string(&config_path).map_err(|e| {
|
||||
tracing::error!("Unable to read {}", config_path.display());
|
||||
error!("Unable to read {}", config_path.display());
|
||||
e
|
||||
})?;
|
||||
|
||||
@@ -641,7 +643,7 @@ impl ConfigFile {
|
||||
|
||||
for contents in contents_split {
|
||||
let config_file_include_only: ConfigFileIncludeOnly = toml::from_str(contents).map_err(|e| {
|
||||
tracing::error!("Failed to deserialize an include section of {}", config_path.display());
|
||||
error!("Failed to deserialize an include section of {}", config_path.display());
|
||||
e
|
||||
})?;
|
||||
|
||||
@@ -654,28 +656,24 @@ impl ConfigFile {
|
||||
let include_contents = match fs::read_to_string(&include_path) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
tracing::error!("Unable to read {}: {}", include_path.display(), e);
|
||||
error!("Unable to read {}: {}", include_path.display(), e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
match toml::from_str::<Self>(&include_contents) {
|
||||
Ok(include_parsed) => result.merge(include_parsed),
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to deserialize {}: {}", include_path.display(), e);
|
||||
error!("Failed to deserialize {}: {}", include_path.display(), e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
debug!("Configuration include found: {}", include_path.display());
|
||||
}
|
||||
} else {
|
||||
debug!("No include paths found in {}", config_path.display());
|
||||
}
|
||||
}
|
||||
|
||||
match toml::from_str::<Self>(contents) {
|
||||
Ok(contents) => result.merge(contents),
|
||||
Err(e) => tracing::error!("Failed to deserialize {}: {}", config_path.display(), e),
|
||||
Err(e) => error!("Failed to deserialize {}: {}", config_path.display(), e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,8 +711,6 @@ impl ConfigFile {
|
||||
}
|
||||
}
|
||||
|
||||
debug!("Loaded configuration: {:?}", result);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@@ -832,7 +828,7 @@ pub struct CommandLineArgs {
|
||||
/// Tracing filter directives.
|
||||
///
|
||||
/// See: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/struct.EnvFilter.html
|
||||
#[clap(long, default_value = "warn")]
|
||||
#[clap(long, default_value = DEFAULT_LOG_LEVEL)]
|
||||
pub log_filter: String,
|
||||
|
||||
/// Print completion script for the given shell and exit
|
||||
@@ -860,6 +856,27 @@ impl CommandLineArgs {
|
||||
pub fn env_variables(&self) -> &Vec<String> {
|
||||
&self.env
|
||||
}
|
||||
|
||||
/// In Topgrade, filter directives come from 3 places:
|
||||
/// 1. CLI option `--log-filter`
|
||||
/// 2. Config file
|
||||
/// 3. `debug` if the `--verbose` option is present
|
||||
///
|
||||
/// Before loading the configuration file, we need our logger to work, so this
|
||||
/// function will return directives coming from part 1 and 2.
|
||||
///
|
||||
///
|
||||
/// When the configuration file is loaded, `Config::tracing_filter_directives()`
|
||||
/// will return all the 3 parts.
|
||||
pub fn tracing_filter_directives(&self) -> String {
|
||||
let mut ret = self.log_filter.clone();
|
||||
if self.verbose {
|
||||
ret.push(',');
|
||||
ret.push_str("debug");
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the application configuration
|
||||
@@ -867,6 +884,7 @@ impl CommandLineArgs {
|
||||
/// The struct holds the loaded configuration file, as well as the arguments parsed from the command line.
|
||||
/// Its provided methods decide the appropriate options based on combining the configuration file and the
|
||||
/// command line arguments.
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
opt: CommandLineArgs,
|
||||
config_file: ConfigFile,
|
||||
@@ -883,7 +901,7 @@ impl Config {
|
||||
ConfigFile::read(opt.config.clone()).unwrap_or_else(|e| {
|
||||
// Inform the user about errors when loading the configuration,
|
||||
// but fallback to the default config to at least attempt to do something
|
||||
tracing::error!("failed to load configuration: {}", e);
|
||||
error!("failed to load configuration: {}", e);
|
||||
ConfigFile::default()
|
||||
})
|
||||
} else {
|
||||
@@ -1442,6 +1460,14 @@ impl Config {
|
||||
self.opt.verbose
|
||||
}
|
||||
|
||||
/// After loading the config file, filter directives consist of 3 parts:
|
||||
///
|
||||
/// 1. directives from the configuration file
|
||||
/// 2. directives from the CLI options `--log-filter`
|
||||
/// 3. `debug`, which would be enabled if the `--verbose` option is present
|
||||
///
|
||||
/// Previous directive will be overwritten if a directive with the same target
|
||||
/// appear later.
|
||||
pub fn tracing_filter_directives(&self) -> String {
|
||||
let mut ret = String::new();
|
||||
if let Some(directives) = self.config_file.misc.as_ref().and_then(|m| m.log_filters.as_ref()) {
|
||||
|
||||
Reference in New Issue
Block a user