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

mpochatkin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 4b7d78551ec IGNITE-23377 Add node name to log file (#7781)
4b7d78551ec is described below

commit 4b7d78551ecaa59cd67736880f7e7fd1d6f48c0c
Author: Vadim Pakhnushev <[email protected]>
AuthorDate: Tue Mar 24 06:01:28 2026 +0300

    IGNITE-23377 Add node name to log file (#7781)
---
 .../ignite/internal/logger/IgniteLoggerImpl.java   |  3 +
 .../apache/ignite/internal/app/IgniteRunner.java   | 74 ++++++++++++++++++++++
 packaging/common/linux/bootstrap-functions.sh      |  3 +-
 packaging/common/windows/bootstrap-functions.bat   |  5 +-
 packaging/db/ignite.java.util.logging.properties   |  4 ++
 5 files changed, 87 insertions(+), 2 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/logger/IgniteLoggerImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/logger/IgniteLoggerImpl.java
index 7322f8df09f..649aa55ed9f 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/logger/IgniteLoggerImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/logger/IgniteLoggerImpl.java
@@ -23,6 +23,9 @@ import java.util.function.Supplier;
 import org.apache.ignite.internal.lang.IgniteStringFormatter;
 import org.jetbrains.annotations.Nullable;
 
+// NOTE: The default logging backend is JUL. 
IgniteRunner.updateLoggingConfiguration() rewrites JUL log file
+// patterns at startup to include the node name. If the backend is switched 
away from JUL, that code must be
+// updated or removed.
 class IgniteLoggerImpl implements IgniteLogger {
     /** Logger delegate. */
     final System.Logger delegate;
diff --git 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteRunner.java 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteRunner.java
index 9a99cdfdd44..2a2d5422c85 100644
--- 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteRunner.java
+++ 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteRunner.java
@@ -17,13 +17,18 @@
 
 package org.apache.ignite.internal.app;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.LogManager;
 import jdk.internal.misc.Signal;
 import jdk.internal.misc.Signal.Handler;
 import org.apache.ignite.IgniteServer;
+import org.jetbrains.annotations.Nullable;
 import picocli.CommandLine;
 import picocli.CommandLine.Command;
 import picocli.CommandLine.Option;
@@ -44,11 +49,80 @@ public class IgniteRunner implements Callable<IgniteServer> 
{
     @Option(names = "--node-name", description = "Node name.", required = true)
     private String nodeName;
 
+    @Option(names = "--log-dir", description = "Path to log directory.")
+    private Path logDir;
+
+    /** Default log file name used in distribution properties files. */
+    private static final String DEFAULT_LOG_FILE = "ignite3db-%g.log";
+
+    /** Default metrics log file name used in distribution properties files. */
+    private static final String DEFAULT_METRICS_LOG_FILE = 
"ignite3db-metrics-%g.log";
+
     @Override
     public IgniteServer call() throws Exception {
+        updateLoggingConfiguration();
+
         return IgniteServer.start(nodeName, configPath.toAbsolutePath(), 
workDir);
     }
 
+    /**
+     * Updates JUL logging configuration to include the node name in log file 
paths.
+     * Only modifies patterns that match the default distribution values.
+     * If {@code --log-dir} is specified, the directory part is also replaced.
+     */
+    private void updateLoggingConfiguration() {
+        String julConfigFile = 
System.getProperty("java.util.logging.config.file");
+        if (julConfigFile == null) {
+            return;
+        }
+
+        Path configFilePath = Path.of(julConfigFile);
+        if (!Files.exists(configFilePath)) {
+            return;
+        }
+
+        try (InputStream is = Files.newInputStream(configFilePath)) {
+            // We re-read the same file that LogManager already loaded, so 
oldVal and newVal are always identical.
+            // The BiFunction only needs to rewrite the matched pattern keys; 
everything else stays unchanged.
+            LogManager.getLogManager().updateConfiguration(is, key -> {
+                if (key.equals("java.util.logging.FileHandler.pattern")) {
+                    return (oldVal, newVal) -> 
insertNodeNameInTheLogFilePattern(oldVal, DEFAULT_LOG_FILE);
+                }
+
+                if (key.endsWith(".LogPushFileHandler.pattern")) {
+                    return (oldVal, newVal) -> 
insertNodeNameInTheLogFilePattern(oldVal, DEFAULT_METRICS_LOG_FILE);
+                }
+
+                return (oldVal, newVal) -> oldVal;
+            });
+        } catch (IOException ignored) {
+            // Keep the original configuration if we can't update it.
+        }
+    }
+
+    /**
+     * Rewrites a log file pattern if it ends with the expected default file 
name.
+     * Inserts the node name into the file name and optionally replaces the 
directory.
+     *
+     * @param currentPattern Current pattern value from the properties file.
+     * @param defaultFileName Expected default file name (e.g. {@code 
ignite3db-%g.log}).
+     * @return Rewritten pattern, or the original if it doesn't match the 
default.
+     */
+    private @Nullable String insertNodeNameInTheLogFilePattern(@Nullable 
String currentPattern, String defaultFileName) {
+        if (currentPattern == null || 
!currentPattern.endsWith(defaultFileName)) {
+            return currentPattern;
+        }
+
+        String dir = currentPattern.substring(0, currentPattern.length() - 
defaultFileName.length());
+        if (logDir != null) {
+            dir = logDir.toAbsolutePath() + "/";
+        }
+
+        // Insert node name before the extension: ignite3db-%g.log -> 
ignite3db-<nodeName>-%g.log
+        String nameWithoutExt = defaultFileName.substring(0, 
defaultFileName.indexOf("-%g.log"));
+        return dir + nameWithoutExt + "-" + nodeName + "-%g.log";
+    }
+
     /**
      * Starts a new Ignite node.
      *
diff --git a/packaging/common/linux/bootstrap-functions.sh 
b/packaging/common/linux/bootstrap-functions.sh
index a929b94ad85..bf3408e1585 100644
--- a/packaging/common/linux/bootstrap-functions.sh
+++ b/packaging/common/linux/bootstrap-functions.sh
@@ -64,4 +64,5 @@ export JAVA_CMD_WITH_ARGS="${JAVACMD} \
 export APPLICATION_ARGS="\
   --config-path ${CONFIG_FILE} \
   --work-dir ${WORK_DIR} \
-  --node-name ${NODE_NAME}"
+  --node-name ${NODE_NAME} \
+  --log-dir ${LOG_DIR}"
diff --git a/packaging/common/windows/bootstrap-functions.bat 
b/packaging/common/windows/bootstrap-functions.bat
index 73f2cc3c18d..f810897a981 100644
--- a/packaging/common/windows/bootstrap-functions.bat
+++ b/packaging/common/windows/bootstrap-functions.bat
@@ -39,4 +39,7 @@ set JAVA_CMD_WITH_ARGS="%JAVA_EXE%" ^
 %IGNITE3_EXTRA_JVM_ARGS% ^
 %CLASSPATH%
 
-set APPLICATION_ARGS=--config-path "%CONFIG_FILE%" --work-dir "%WORK_DIR%" 
--node-name %NODE_NAME%
+set APPLICATION_ARGS=--config-path "%CONFIG_FILE%" ^
+--work-dir "%WORK_DIR%" ^
+--node-name %NODE_NAME% ^
+--log-dir "%LOG_DIR%"
diff --git a/packaging/db/ignite.java.util.logging.properties 
b/packaging/db/ignite.java.util.logging.properties
index 028fbcc5bfb..1e65595b26d 100644
--- a/packaging/db/ignite.java.util.logging.properties
+++ b/packaging/db/ignite.java.util.logging.properties
@@ -20,6 +20,10 @@
 #
 # To use another config file use `java.util.logging.config.file` system
 # property. For example `java -Djava.util.logging.config.file=myfile`
+#
+# NOTE: IgniteRunner.updateLoggingConfiguration() rewrites log file
+# patterns at startup to include the node name. If the logging backend
+# is switched away from JUL, that code must be updated or removed.
 #########################################################################
 
 #

Reply via email to