From d1cc807b65333d43ecc9e315f4cf494290298bd6 Mon Sep 17 00:00:00 2001 From: Niklas Keller Date: Wed, 6 Aug 2025 23:17:31 +0200 Subject: [PATCH 1/2] Round initialTime in RollingFileManager Caching of filesystem timestamps (at least in ext4 on Linux) results in non-accurate creation timestamps. Thus, let's round it to the second. Rounding is also applied for the lastModified time, but I'm not sure whether it's needed there. Fixes #3068. --- .../rolling/RollingFileManagerTest.java | 11 +++++++++++ .../appender/rolling/RollingFileManager.java | 19 ++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java index 78784cfa755..0f944f798bb 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java @@ -224,4 +224,15 @@ void testRolloverOfDeletedFile() throws IOException { } assertEquals(testContent, new String(Files.readAllBytes(file.toPath()), StandardCharsets.US_ASCII)); } + + @Test + @Issue("https://github.com/apache/logging-log4j2/issues/3068") + void testInitialTimeRounded() { + assertEquals(1755031147000L, RollingFileManager.roundMillis(1755031147000L)); + assertEquals(1755031147000L, RollingFileManager.roundMillis(1755031147123L)); + assertEquals(1755031147000L, RollingFileManager.roundMillis(1755031147499L)); + assertEquals(1755031148000L, RollingFileManager.roundMillis(1755031147500L)); + assertEquals(1755031148000L, RollingFileManager.roundMillis(1755031147999L)); + assertEquals(1755031148000L, RollingFileManager.roundMillis(1755031148000L)); + } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java index b033f5785e0..23485347ee6 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java @@ -918,15 +918,24 @@ private static long initialFileTime(final File file) { final FileTime fileTime = attrs.creationTime(); if (fileTime.compareTo(EPOCH) > 0) { LOGGER.debug("Returning file creation time for {}", file.getAbsolutePath()); - return fileTime.toMillis(); + + return roundMillis(fileTime.toMillis()); } - LOGGER.info("Unable to obtain file creation time for " + file.getAbsolutePath()); + LOGGER.info("Unable to obtain file creation time for {}", file.getAbsolutePath()); } catch (final Exception ex) { - LOGGER.info("Unable to calculate file creation time for " + file.getAbsolutePath() + ": " - + ex.getMessage()); + LOGGER.info( + "Unable to calculate file creation time for {}: {}", file.getAbsolutePath(), ex.getMessage()); } } - return file.lastModified(); + + return roundMillis(file.lastModified()); + } + + /** + * @see Issue #3068 + */ + static long roundMillis(long millis) { + return Math.round(millis / 1000d) * 1000; } private static class EmptyQueue extends ArrayBlockingQueue { From 5032334f68087e867a348a4c955a5c352919a605 Mon Sep 17 00:00:00 2001 From: Niklas Keller Date: Tue, 12 Aug 2025 22:51:22 +0200 Subject: [PATCH 2/2] Add test for initialFileTime returning rounded millis --- .../core/appender/rolling/RollingFileManagerTest.java | 7 ++++++- .../log4j/core/appender/rolling/RollingFileManager.java | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java index 0f944f798bb..d0eb7cbb62e 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java @@ -227,12 +227,17 @@ void testRolloverOfDeletedFile() throws IOException { @Test @Issue("https://github.com/apache/logging-log4j2/issues/3068") - void testInitialTimeRounded() { + void testInitialTimeRounded() throws IOException { assertEquals(1755031147000L, RollingFileManager.roundMillis(1755031147000L)); assertEquals(1755031147000L, RollingFileManager.roundMillis(1755031147123L)); assertEquals(1755031147000L, RollingFileManager.roundMillis(1755031147499L)); assertEquals(1755031148000L, RollingFileManager.roundMillis(1755031147500L)); assertEquals(1755031148000L, RollingFileManager.roundMillis(1755031147999L)); assertEquals(1755031148000L, RollingFileManager.roundMillis(1755031148000L)); + + final File file = File.createTempFile("testFile", "log"); + file.deleteOnExit(); + + assertEquals(0, RollingFileManager.initialFileTime(file) % 1000); } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java index 23485347ee6..97db00f785e 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java @@ -910,7 +910,7 @@ public RollingFileManager createManager(final String name, final FactoryData dat } } - private static long initialFileTime(final File file) { + static long initialFileTime(final File file) { final Path path = file.toPath(); if (Files.exists(path)) { try {