ppkarwasz commented on code in PR #3226:
URL: https://github.com/apache/logging-log4j2/pull/3226#discussion_r1851632621


##########
log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java:
##########
@@ -506,9 +506,16 @@ public synchronized void rollover() {
 
             if (rollover(rolloverStrategy)) {
                 try {
-                    size = 0;
-                    initialTime = System.currentTimeMillis();
                     createFileAfterRollover();
+                    final File file = new File(getFileName());
+                    size = file.length();
+                    try {
+                        final FileTime creationTime = (FileTime) 
Files.getAttribute(file.toPath(), "creationTime");
+                        initialTime = creationTime.toMillis();
+                    } catch (Exception ex) {
+                        LOGGER.warn("Unable to get current file time for {}", 
file);
+                        initialTime = System.currentTimeMillis();
+                    }

Review Comment:
   - Even if the rollover fails, I would still reset the `size` field. This is 
the field used by 
[`SizeBasedTriggeringPolicy`](https://logging.apache.org/log4j/3.x/manual/appenders/rolling-file.html#SizeBasedTriggeringPolicy)
 to determine, when a rollover is due. Otherwise the triggering policy might 
attempt a rollover at **each** log event. It is safe to assume that the new 
rollover might fail too.
   - The `initialTime` field is not really used by any triggering policy at 
runtime. It is only used at **configuration time** and never queried again. I 
would leave it as is.



##########
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java:
##########
@@ -188,4 +193,40 @@ public void testCreateParentDir() {
             manager.close();
         }
     }
+
+    @Test
+    @Issue("https://github.com/apache/logging-log4j2/issues/2592";)
+    public void testRolloverOfDeletedFile() throws IOException {
+        final Configuration configuration = new NullConfiguration();
+        final File file = File.createTempFile("testRolloverOfDeletedFile", 
"log");
+        file.deleteOnExit();
+        final String testContent = "Test";
+        try (final OutputStream os =
+                        new ByteArrayOutputStream(); // use a dummy 
OutputStream so that the real file can be deleted
+                final RollingFileManager manager = new RollingFileManager(
+                        configuration.getLoggerContext(),
+                        file.getAbsolutePath(),
+                        "testRolloverOfDeletedFile.log.%d{yyyy-MM-dd}",
+                        os,
+                        true,
+                        false,
+                        0,
+                        System.currentTimeMillis(),
+                        OnStartupTriggeringPolicy.createPolicy(1),
+                        DefaultRolloverStrategy.newBuilder().build(),
+                        file.getName(),
+                        PatternLayout.createDefaultLayout(configuration),

Review Comment:
   Both the `LoggerContext` and `Layout` parameters can actually be `null`. 
This way you don't need the rather expensive `Configuration` object.



##########
log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java:
##########
@@ -636,7 +643,7 @@ private boolean rollover(final RolloverStrategy strategy) {
                     asyncExecutor.execute(new 
AsyncAction(descriptor.getAsynchronous(), this));
                     releaseRequired = false;
                 }
-                return success;
+                return true;

Review Comment:
   There are a lot of `boolean`s in this method with different purposes. It 
might be useful to rename them to make the code more clear. For example:
   
   - `releaseRequired` actually tells us if the asynchronous action has 
started. Maybe we could rename it to `asyncActionStarted` and define it only 
where it is needed (just after the first `try`).
   - `success` tells use if the synchronous action has succeeded. It should be 
rather called something like `syncActionSuccess` and be defined just before the 
synchronous action is executed.
   - A third unnamed `boolean` is used in the return statements and there is no 
comment stating what `rollover(RolloverStrategy)` returns. I think we should 
introduce a `outputStreamClosed` variable that is defined at the beginning of 
the method and used in all the return statements. The lack of documentation is 
what caused #2592 in the first place.



##########
log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java:
##########
@@ -188,4 +193,40 @@ public void testCreateParentDir() {
             manager.close();
         }
     }
+
+    @Test
+    @Issue("https://github.com/apache/logging-log4j2/issues/2592";)
+    public void testRolloverOfDeletedFile() throws IOException {
+        final Configuration configuration = new NullConfiguration();
+        final File file = File.createTempFile("testRolloverOfDeletedFile", 
"log");
+        file.deleteOnExit();
+        final String testContent = "Test";
+        try (final OutputStream os =
+                        new ByteArrayOutputStream(); // use a dummy 
OutputStream so that the real file can be deleted
+                final RollingFileManager manager = new RollingFileManager(

Review Comment:
   Nice test! :100:
   
   By calling the constructor directly, you prevent the registration of 
`RollingFileManager` in the registry kept by `AbstractManager`. This a very 
nice approach for tests!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to