Skip to content

Commit 50ebb9a

Browse files
committed
feat!: [torrust#591] move log_level into a new logging section in config
Old: ```toml log_level = "info" [website] name = "Torrust" ``` New: ```toml [logging] log_level = "info" [website] name = "Torrust" ``` And the value is not Optional anymore. It was a Optional<LogLevel> but when it was None it defaulted to LogLevel::Info. In practice that means is mandatory but with the `Info` default value.
1 parent 82fc32c commit 50ebb9a

14 files changed

+117
-47
lines changed

share/default/config/index.container.mysql.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[logging]
12
log_level = "info"
23

34
[database]

share/default/config/index.container.sqlite3.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[logging]
12
log_level = "info"
23

34
[database]

share/default/config/index.development.sqlite3.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[logging]
12
log_level = "info"
23

34
# Uncomment if you want to enable TSL for development

share/default/config/index.private.e2e.container.sqlite3.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[logging]
12
log_level = "info"
23

34
[tracker]

share/default/config/index.public.e2e.container.mysql.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[logging]
12
log_level = "info"
23

34
[tracker]

share/default/config/index.public.e2e.container.sqlite3.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[logging]
12
log_level = "info"
23

34
[tracker]

src/app.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub struct Running {
3838
/// It panics if there is an error connecting to the database.
3939
#[allow(clippy::too_many_lines)]
4040
pub async fn run(configuration: Configuration, api_version: &Version) -> Running {
41-
let log_level = configuration.settings.read().await.log_level.clone();
41+
let log_level = configuration.settings.read().await.logging.log_level.clone();
4242

4343
logging::setup(&log_level);
4444

src/bootstrap/logging.rs

+3-17
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ use std::sync::Once;
1111
use tracing::info;
1212
use tracing::level_filters::LevelFilter;
1313

14-
use crate::config::v1::LogLevel;
14+
use crate::config::v1::logging::LogLevel;
1515

1616
static INIT: Once = Once::new();
1717

18-
pub fn setup(log_level: &Option<LogLevel>) {
19-
let tracing_level = config_level_or_default(log_level);
18+
pub fn setup(log_level: &LogLevel) {
19+
let tracing_level: LevelFilter = log_level.clone().into();
2020

2121
if tracing_level == LevelFilter::OFF {
2222
return;
@@ -27,20 +27,6 @@ pub fn setup(log_level: &Option<LogLevel>) {
2727
});
2828
}
2929

30-
fn config_level_or_default(log_level: &Option<LogLevel>) -> LevelFilter {
31-
match log_level {
32-
None => LevelFilter::INFO,
33-
Some(level) => match level {
34-
LogLevel::Off => LevelFilter::OFF,
35-
LogLevel::Error => LevelFilter::ERROR,
36-
LogLevel::Warn => LevelFilter::WARN,
37-
LogLevel::Info => LevelFilter::INFO,
38-
LogLevel::Debug => LevelFilter::DEBUG,
39-
LogLevel::Trace => LevelFilter::TRACE,
40-
},
41-
}
42-
}
43-
4430
fn tracing_stdout_init(filter: LevelFilter, style: &TraceStyle) {
4531
let builder = tracing_subscriber::fmt().with_max_level(filter);
4632

src/config/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub type Mail = v1::mail::Mail;
2727
pub type Network = v1::net::Network;
2828
pub type TrackerStatisticsImporter = v1::tracker_statistics_importer::TrackerStatisticsImporter;
2929
pub type Tracker = v1::tracker::Tracker;
30+
pub type Logging = v1::logging::Logging;
3031
pub type Website = v1::website::Website;
3132
pub type EmailOnSignup = v1::auth::EmailOnSignup;
3233

@@ -325,7 +326,10 @@ mod tests {
325326

326327
#[cfg(test)]
327328
fn default_config_toml() -> String {
328-
let config = r#"[website]
329+
let config = r#"[logging]
330+
log_level = "info"
331+
332+
[website]
329333
name = "Torrust"
330334
331335
[tracker]

src/config/v1/logging.rs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use std::fmt;
2+
3+
use serde::{Deserialize, Serialize};
4+
use tracing::level_filters::LevelFilter;
5+
6+
/// Core configuration for the API
7+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
8+
pub struct Logging {
9+
/// Logging level. Possible values are: `Off`, `Error`, `Warn`, `Info`, `Debug`, `Trace`.
10+
#[serde(default = "Logging::default_log_level")]
11+
pub log_level: LogLevel,
12+
}
13+
14+
impl Default for Logging {
15+
fn default() -> Self {
16+
Self {
17+
log_level: Logging::default_log_level(),
18+
}
19+
}
20+
}
21+
22+
impl Logging {
23+
fn default_log_level() -> LogLevel {
24+
LogLevel::Info
25+
}
26+
}
27+
28+
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Clone)]
29+
#[serde(rename_all = "lowercase")]
30+
pub enum LogLevel {
31+
/// A level lower than all log levels.
32+
Off,
33+
/// Corresponds to the `Error` log level.
34+
Error,
35+
/// Corresponds to the `Warn` log level.
36+
Warn,
37+
/// Corresponds to the `Info` log level.
38+
Info,
39+
/// Corresponds to the `Debug` log level.
40+
Debug,
41+
/// Corresponds to the `Trace` log level.
42+
Trace,
43+
}
44+
45+
impl Default for LogLevel {
46+
fn default() -> Self {
47+
Self::Info
48+
}
49+
}
50+
51+
impl fmt::Display for LogLevel {
52+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53+
let display_str = match self {
54+
LogLevel::Off => "off",
55+
LogLevel::Error => "error",
56+
LogLevel::Warn => "warn",
57+
LogLevel::Info => "info",
58+
LogLevel::Debug => "debug",
59+
LogLevel::Trace => "trace",
60+
};
61+
write!(f, "{display_str}")
62+
}
63+
}
64+
65+
impl From<LogLevel> for LevelFilter {
66+
fn from(log_level: LogLevel) -> Self {
67+
match log_level {
68+
LogLevel::Off => LevelFilter::OFF,
69+
LogLevel::Error => LevelFilter::ERROR,
70+
LogLevel::Warn => LevelFilter::WARN,
71+
LogLevel::Info => LevelFilter::INFO,
72+
LogLevel::Debug => LevelFilter::DEBUG,
73+
LogLevel::Trace => LevelFilter::TRACE,
74+
}
75+
}
76+
}

src/config/v1/mod.rs

+4-20
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ pub mod api;
22
pub mod auth;
33
pub mod database;
44
pub mod image_cache;
5+
pub mod logging;
56
pub mod mail;
67
pub mod net;
78
pub mod tracker;
89
pub mod tracker_statistics_importer;
910
pub mod website;
1011

12+
use logging::Logging;
1113
use serde::{Deserialize, Serialize};
1214

1315
use self::api::Api;
@@ -24,10 +26,9 @@ use super::validator::{ValidationError, Validator};
2426
/// The whole configuration for the index.
2527
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2628
pub struct Settings {
27-
/// Logging level. Possible values are: `Off`, `Error`, `Warn`, `Info`,
28-
/// `Debug` and `Trace`. Default is `Info`.
29+
/// The logging configuration.
2930
#[serde(default)]
30-
pub log_level: Option<LogLevel>,
31+
pub logging: Logging,
3132
/// The website customizable values.
3233
#[serde(default)]
3334
pub website: Website,
@@ -73,20 +74,3 @@ impl Validator for Settings {
7374
self.tracker.validate()
7475
}
7576
}
76-
77-
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Clone)]
78-
#[serde(rename_all = "lowercase")]
79-
pub enum LogLevel {
80-
/// A level lower than all log levels.
81-
Off,
82-
/// Corresponds to the `Error` log level.
83-
Error,
84-
/// Corresponds to the `Warn` log level.
85-
Warn,
86-
/// Corresponds to the `Info` log level.
87-
Info,
88-
/// Corresponds to the `Debug` log level.
89-
Debug,
90-
/// Corresponds to the `Trace` log level.
91-
Trace,
92-
}

src/console/commands/tracker_statistics_importer/app.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub async fn import() {
9090

9191
let configuration = initialize_configuration();
9292

93-
let log_level = configuration.settings.read().await.log_level.clone();
93+
let log_level = configuration.settings.read().await.logging.log_level.clone();
9494

9595
logging::setup(&log_level);
9696

tests/common/contexts/settings/mod.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ pub mod responses;
33
use serde::{Deserialize, Serialize};
44
use torrust_index::config::v1::tracker::ApiToken;
55
use torrust_index::config::{
6-
Api as DomainApi, Auth as DomainAuth, Database as DomainDatabase, ImageCache as DomainImageCache, Mail as DomainMail,
7-
Network as DomainNetwork, Settings as DomainSettings, Tracker as DomainTracker,
6+
Api as DomainApi, Auth as DomainAuth, Database as DomainDatabase, ImageCache as DomainImageCache, Logging as DomainLogging,
7+
Mail as DomainMail, Network as DomainNetwork, Settings as DomainSettings, Tracker as DomainTracker,
88
TrackerStatisticsImporter as DomainTrackerStatisticsImporter, Website as DomainWebsite,
99
};
1010
use url::Url;
1111

1212
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
1313
pub struct Settings {
14+
pub logging: Logging,
1415
pub website: Website,
1516
pub tracker: Tracker,
1617
pub net: Network,
@@ -22,6 +23,11 @@ pub struct Settings {
2223
pub tracker_statistics_importer: TrackerStatisticsImporter,
2324
}
2425

26+
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
27+
pub struct Logging {
28+
pub log_level: String,
29+
}
30+
2531
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
2632
pub struct Website {
2733
pub name: String,
@@ -90,6 +96,7 @@ pub struct TrackerStatisticsImporter {
9096
impl From<DomainSettings> for Settings {
9197
fn from(settings: DomainSettings) -> Self {
9298
Settings {
99+
logging: Logging::from(settings.logging),
93100
website: Website::from(settings.website),
94101
tracker: Tracker::from(settings.tracker),
95102
net: Network::from(settings.net),
@@ -103,6 +110,14 @@ impl From<DomainSettings> for Settings {
103110
}
104111
}
105112

113+
impl From<DomainLogging> for Logging {
114+
fn from(logging: DomainLogging) -> Self {
115+
Self {
116+
log_level: logging.log_level.to_string(),
117+
}
118+
}
119+
}
120+
106121
impl From<DomainWebsite> for Website {
107122
fn from(website: DomainWebsite) -> Self {
108123
Self { name: website.name }

tests/environments/isolated.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use tempfile::TempDir;
22
use torrust_index::config;
3-
use torrust_index::config::v1::LogLevel;
3+
use torrust_index::config::v1::logging::LogLevel;
44
use torrust_index::config::FREE_PORT;
55
use torrust_index::web::api::Version;
66
use url::Url;
@@ -72,10 +72,9 @@ impl Default for TestEnv {
7272

7373
/// Provides a configuration with ephemeral data for testing.
7474
fn ephemeral(temp_dir: &TempDir) -> config::Settings {
75-
let mut configuration = config::Settings {
76-
log_level: Some(LogLevel::Off), // Change to `debug` for tests debugging
77-
..config::Settings::default()
78-
};
75+
let mut configuration = config::Settings::default();
76+
77+
configuration.logging.log_level = LogLevel::Off; // Change to `debug` for tests debugging
7978

8079
// Ephemeral API port
8180
configuration.net.port = FREE_PORT;

0 commit comments

Comments
 (0)