Skip to content

Commit d4b06b6

Browse files
authored
Merge pull request #3967 from Bravo555/fix/tedge-log-level
fix: Make log level overrides for `tedge` binary work again
2 parents eef2b01 + 3a077bc commit d4b06b6

File tree

3 files changed

+64
-66
lines changed

3 files changed

+64
-66
lines changed

crates/common/tedge_config/src/cli.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,6 @@ pub struct LogConfigArgs {
4343
pub log_level: Option<tracing::Level>,
4444
}
4545

46-
impl LogConfigArgs {
47-
pub fn with_default_level(self, log_level: tracing::Level) -> Self {
48-
Self {
49-
log_level: self.log_level.or(Some(log_level)),
50-
..self
51-
}
52-
}
53-
}
54-
5546
fn log_level_completions() -> Vec<CompletionCandidate> {
5647
use tracing::Level as L;
5748
let options = [L::TRACE, L::DEBUG, L::INFO, L::WARN, L::ERROR];

crates/common/tedge_config/src/system_toml/log_level.rs

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ use camino::Utf8Path;
55
use std::io::IsTerminal;
66
use std::str::FromStr;
77
use std::sync::Arc;
8+
use tracing_subscriber::util::SubscriberInitExt;
9+
10+
const DEFAULT_LEVEL: tracing::Level = tracing::Level::INFO;
811

912
#[macro_export]
1013
/// The basic subscriber
@@ -19,9 +22,11 @@ macro_rules! subscriber_builder {
1922

2023
/// Configures and enables logging taking into account flags, env variables and file config.
2124
///
22-
/// 1. Log config is taken from the file configuration first
23-
/// 2. If `RUST_LOG` variable is set, it overrides file-based configuration
24-
/// 3. If `--debug` or `--log-level` flags are set, they override previous steps
25+
/// Priority order (highest to lowest):
26+
/// 1. `--debug` or `--log-level` flags
27+
/// 2. `RUST_LOG` environment variable
28+
/// 3. File configuration (`system.toml`)
29+
/// 4. Default level (INFO)
2530
///
2631
/// Reports all the log events sent either with the `log` crate or the `tracing`
2732
/// crate.
@@ -30,29 +35,17 @@ pub fn log_init(
3035
flags: &LogConfigArgs,
3136
config_dir: &Utf8Path,
3237
) -> Result<(), SystemTomlError> {
33-
let subscriber = subscriber_builder!();
34-
35-
let log_level = flags
36-
.log_level
37-
.or(flags.debug.then_some(tracing::Level::DEBUG));
38-
39-
if let Some(log_level) = log_level {
40-
subscriber.with_max_level(log_level).init();
41-
return Ok(());
42-
}
43-
44-
if std::env::var("RUST_LOG").is_ok() {
45-
subscriber
46-
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
47-
.with_file(true)
48-
.with_line_number(true)
49-
.init();
50-
return Ok(());
51-
}
52-
53-
let log_level = get_log_level(sname, config_dir)?;
54-
subscriber.with_max_level(log_level).init();
38+
log_init_with_default_level(sname, flags, config_dir, DEFAULT_LEVEL)
39+
}
5540

41+
pub fn log_init_with_default_level(
42+
sname: &str,
43+
flags: &LogConfigArgs,
44+
config_dir: &Utf8Path,
45+
default_level: tracing::Level,
46+
) -> Result<(), SystemTomlError> {
47+
let logger = logger(sname, flags, Some(config_dir), default_level)?;
48+
logger.init();
5649
Ok(())
5750
}
5851

@@ -64,6 +57,7 @@ pub fn unconfigured_logger() -> Arc<dyn tracing::Subscriber + Send + Sync> {
6457
log_level: None,
6558
},
6659
None,
60+
DEFAULT_LEVEL,
6761
)
6862
.unwrap()
6963
}
@@ -72,47 +66,59 @@ fn logger(
7266
sname: &str,
7367
flags: &LogConfigArgs,
7468
config_dir: Option<&Utf8Path>,
69+
default_level: tracing::Level,
7570
) -> Result<Arc<dyn tracing::Subscriber + Send + Sync>, SystemTomlError> {
76-
let subscriber = tracing_subscriber::fmt()
77-
.with_writer(std::io::stderr)
78-
.with_ansi(std::io::stderr().is_terminal() && yansi::Condition::no_color())
79-
.with_timer(tracing_subscriber::fmt::time::UtcTime::rfc_3339());
71+
let subscriber = subscriber_builder!();
72+
73+
// first use log level from flags
8074
let log_level = flags
8175
.log_level
8276
.or(flags.debug.then_some(tracing::Level::DEBUG));
8377

8478
if let Some(log_level) = log_level {
85-
Ok(Arc::new(subscriber.with_max_level(log_level).finish()))
86-
} else if std::env::var("RUST_LOG").is_ok() {
87-
Ok(Arc::new(
79+
return Ok(Arc::new(subscriber.with_max_level(log_level).finish()));
80+
}
81+
82+
// if no flags used, use EnvFilter
83+
if std::env::var("RUST_LOG").is_ok() {
84+
return Ok(Arc::new(
8885
subscriber
8986
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
9087
.with_file(true)
9188
.with_line_number(true)
9289
.finish(),
93-
))
94-
} else {
95-
let log_level = config_dir
96-
.map(|config_dir| get_log_level(sname, config_dir))
97-
.unwrap_or(Ok(DEFAULT_MAX_LEVEL))?;
98-
Ok(Arc::new(subscriber.with_max_level(log_level).finish()))
90+
));
91+
}
92+
93+
// if no EnvFilter, get log level from config file
94+
if let Some(log_level) = config_dir.and_then(|config_dir| {
95+
get_log_level_from_config_file(sname, config_dir)
96+
.ok()
97+
.flatten()
98+
}) {
99+
return Ok(Arc::new(subscriber.with_max_level(log_level).finish()));
99100
}
100-
}
101101

102-
const DEFAULT_MAX_LEVEL: tracing::Level = tracing::Level::INFO;
102+
// otherwise, use the default log level
103+
Ok(Arc::new(subscriber.with_max_level(default_level).finish()))
104+
}
103105

104-
pub fn get_log_level(
106+
/// Return the log level for a given service, if it's defined in the config file. Otherwise return `None`.
107+
pub fn get_log_level_from_config_file(
105108
sname: &str,
106109
config_dir: &Utf8Path,
107-
) -> Result<tracing::Level, SystemTomlError> {
110+
) -> Result<Option<tracing::Level>, SystemTomlError> {
108111
let loglevel = SystemConfig::try_new(config_dir)?.log;
109112
match loglevel.get(sname) {
110-
Some(ll) => tracing::Level::from_str(&ll.to_uppercase()).map_err(|_| {
111-
SystemTomlError::InvalidLogLevel {
112-
name: ll.to_string(),
113-
}
114-
}),
115-
None => Ok(tracing::Level::INFO),
113+
Some(ll) => {
114+
let ll = tracing::Level::from_str(&ll.to_uppercase()).map_err(|_| {
115+
SystemTomlError::InvalidLogLevel {
116+
name: ll.to_string(),
117+
}
118+
})?;
119+
Ok(Some(ll))
120+
}
121+
None => Ok(None),
116122
}
117123
}
118124

@@ -151,8 +157,8 @@ mod tests {
151157
"#;
152158

153159
let (_dir, config_dir) = create_temp_system_config(toml_conf)?;
154-
let res = get_log_level("tedge_mapper", &config_dir)?;
155-
assert_eq!(Level::DEBUG, res);
160+
let res = get_log_level_from_config_file("tedge_mapper", &config_dir)?;
161+
assert_eq!(Some(Level::DEBUG), res);
156162
Ok(())
157163
}
158164

@@ -163,7 +169,7 @@ mod tests {
163169
tedge_mapper = "other"
164170
"#;
165171
let (_dir, config_dir) = create_temp_system_config(toml_conf)?;
166-
let res = get_log_level("tedge_mapper", &config_dir).unwrap_err();
172+
let res = get_log_level_from_config_file("tedge_mapper", &config_dir).unwrap_err();
167173
assert_eq!(
168174
"Invalid log level: \"other\", supported levels are info, warn, error and debug",
169175
res.to_string()
@@ -179,7 +185,7 @@ mod tests {
179185
"#;
180186

181187
let (_dir, config_dir) = create_temp_system_config(toml_conf)?;
182-
let res = get_log_level("tedge_mapper", &config_dir).unwrap_err();
188+
let res = get_log_level_from_config_file("tedge_mapper", &config_dir).unwrap_err();
183189

184190
assert_eq!(
185191
"Invalid log level: \"\", supported levels are info, warn, error and debug",
@@ -196,8 +202,8 @@ mod tests {
196202
"#;
197203

198204
let (_dir, config_dir) = create_temp_system_config(toml_conf)?;
199-
let res = get_log_level("tedge_mapper", &config_dir).unwrap();
200-
assert_eq!(Level::INFO, res);
205+
let res = get_log_level_from_config_file("tedge_mapper", &config_dir).unwrap();
206+
assert_eq!(None, res);
201207
Ok(())
202208
}
203209

crates/core/tedge/src/main.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use tedge::TEdgeCli;
1717
use tedge::TEdgeOpt;
1818
use tedge::TEdgeOptMulticall;
1919
use tedge_config::cli::CommonArgs;
20-
use tedge_config::log_init;
20+
use tedge_config::log_init_with_default_level;
2121
use tedge_config::unconfigured_logger;
2222
use tedge_file_log_plugin::bin::TEdgeConfigView;
2323
use tracing::log;
@@ -91,10 +91,11 @@ async fn main() -> anyhow::Result<()> {
9191
.context("failed to run tedge file log plugin")?
9292
}
9393
TEdgeOptMulticall::Tedge(TEdgeCli { cmd, common }) => {
94-
log_init(
94+
log_init_with_default_level(
9595
"tedge",
96-
&common.log_args.with_default_level(tracing::Level::WARN),
96+
&common.log_args,
9797
&common.config_dir,
98+
tracing::Level::WARN,
9899
)?;
99100

100101
let tedge_config = tedge_config::TEdgeConfig::load(&common.config_dir).await?;

0 commit comments

Comments
 (0)