This is an automated email from the ASF dual-hosted git repository.

hgruszecki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git


The following commit(s) were added to refs/heads/master by this push:
     new 07f74eae7 feat(server): add file_enabled option to logging config 
(#2443)
07f74eae7 is described below

commit 07f74eae72e0b46ca47fb84095fcf6984eaea43b
Author: Hubert Gruszecki <[email protected]>
AuthorDate: Thu Dec 4 16:13:46 2025 +0100

    feat(server): add file_enabled option to logging config (#2443)
    
    Allow disabling file logging via system.logging.file_enabled setting.
    When false, logs are only written to stdout.
---
 core/configs/server.toml            |  4 +++
 core/server/src/configs/defaults.rs |  1 +
 core/server/src/configs/displays.rs |  3 +-
 core/server/src/configs/system.rs   |  1 +
 core/server/src/log/logger.rs       | 62 +++++++++++++++++++++----------------
 5 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/core/configs/server.toml b/core/configs/server.toml
index 8fde53d28..581763acf 100644
--- a/core/configs/server.toml
+++ b/core/configs/server.toml
@@ -346,6 +346,10 @@ path = "logs"
 # Note: RUST_LOG environment variable always takes precedence over this 
setting.
 level = "info"
 
+# Whether to write logs to file. When false, logs are only written to stdout.
+# When enabled, logs are stored in {system.path}/{system.logging.path} 
(default: local_data/logs).
+file_enabled = true
+
 # Maximum size of the log files before rotation.
 max_size = "512 MB"
 
diff --git a/core/server/src/configs/defaults.rs 
b/core/server/src/configs/defaults.rs
index 89f7cdb3b..c864618ee 100644
--- a/core/server/src/configs/defaults.rs
+++ b/core/server/src/configs/defaults.rs
@@ -399,6 +399,7 @@ impl Default for LoggingConfig {
         LoggingConfig {
             path: SERVER_CONFIG.system.logging.path.parse().unwrap(),
             level: SERVER_CONFIG.system.logging.level.parse().unwrap(),
+            file_enabled: SERVER_CONFIG.system.logging.file_enabled,
             max_size: SERVER_CONFIG.system.logging.max_size.parse().unwrap(),
             retention: SERVER_CONFIG.system.logging.retention.parse().unwrap(),
             sysinfo_print_interval: SERVER_CONFIG
diff --git a/core/server/src/configs/displays.rs 
b/core/server/src/configs/displays.rs
index f0749eece..e15680608 100644
--- a/core/server/src/configs/displays.rs
+++ b/core/server/src/configs/displays.rs
@@ -248,9 +248,10 @@ impl Display for LoggingConfig {
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
         write!(
             f,
-            "{{ path: {}, level: {}, max_size: {}, retention: {} }}",
+            "{{ path: {}, level: {}, file_enabled: {}, max_size: {}, 
retention: {} }}",
             self.path,
             self.level,
+            self.file_enabled,
             self.max_size.as_human_string_with_zero_as_unlimited(),
             self.retention
         )
diff --git a/core/server/src/configs/system.rs 
b/core/server/src/configs/system.rs
index c2016eee3..c1b089a79 100644
--- a/core/server/src/configs/system.rs
+++ b/core/server/src/configs/system.rs
@@ -86,6 +86,7 @@ pub struct CompressionConfig {
 pub struct LoggingConfig {
     pub path: String,
     pub level: String,
+    pub file_enabled: bool,
     pub max_size: IggyByteSize,
     #[serde_as(as = "DisplayFromStr")]
     pub retention: IggyDuration,
diff --git a/core/server/src/log/logger.rs b/core/server/src/log/logger.rs
index 5646d1a51..4c0e0691e 100644
--- a/core/server/src/log/logger.rs
+++ b/core/server/src/log/logger.rs
@@ -248,39 +248,49 @@ impl Logging {
 
         self.dump_to_stdout();
 
-        // Initialize directory and file for logs
-        let base_directory = PathBuf::from(base_directory);
-        let logs_subdirectory = PathBuf::from(config.path.clone());
-        let logs_path = base_directory.join(logs_subdirectory.clone());
-        let file_appender =
-            tracing_appender::rolling::hourly(logs_path.clone(), 
IGGY_LOG_FILE_PREFIX);
-        let (mut non_blocking_file, file_guard) = 
tracing_appender::non_blocking(file_appender);
-
-        self.dump_to_file(&mut non_blocking_file);
-
-        let file_layer = fmt::layer()
-            .event_format(Self::get_log_format())
-            .with_target(true)
-            .with_writer(non_blocking_file)
-            .with_ansi(false)
-            .fmt_fields(NoAnsiFields {})
-            .boxed();
+        // Initialize file logging if enabled
+        let logs_path = if config.file_enabled {
+            let base_directory = PathBuf::from(base_directory);
+            let logs_subdirectory = PathBuf::from(config.path.clone());
+            let logs_path = base_directory.join(logs_subdirectory.clone());
+            let file_appender =
+                tracing_appender::rolling::hourly(logs_path.clone(), 
IGGY_LOG_FILE_PREFIX);
+            let (mut non_blocking_file, file_guard) = 
tracing_appender::non_blocking(file_appender);
+
+            self.dump_to_file(&mut non_blocking_file);
+
+            let file_layer = fmt::layer()
+                .event_format(Self::get_log_format())
+                .with_target(true)
+                .with_writer(non_blocking_file)
+                .with_ansi(false)
+                .fmt_fields(NoAnsiFields {})
+                .boxed();
+
+            self.file_guard = Some(file_guard);
+            self.file_reload_handle
+                .as_ref()
+                .ok_or(LogError::FileReloadFailure)?
+                .modify(|layer| *layer = file_layer)
+                .expect("Failed to modify file layer");
 
-        self.file_guard = Some(file_guard);
-        self.file_reload_handle
-            .as_ref()
-            .ok_or(LogError::FileReloadFailure)?
-            .modify(|layer| *layer = file_layer)
-            .expect("Failed to modify file layer");
+            Some(logs_path)
+        } else {
+            None
+        };
 
         // Initialize telemetry if enabled
         if telemetry_config.enabled {
             self.init_telemetry(telemetry_config)?;
         }
 
-        info!(
-            "Logging initialized, logs will be stored at: {logs_path:?}. Logs 
will be rotated hourly. Log filter: {log_filter}."
-        );
+        if let Some(logs_path) = logs_path {
+            info!(
+                "Logging initialized, logs will be stored at: {logs_path:?}. 
Logs will be rotated hourly. Log filter: {log_filter}."
+            );
+        } else {
+            info!("Logging initialized (file output disabled). Log filter: 
{log_filter}.");
+        }
 
         Ok(())
     }

Reply via email to