Visitar URL original
V6.0: When scrolling, the newer files are deleted rather than the older ones. An example is as follows. · Issue #5986 · NLog/NLog · GitHub
Skip to content

V6.0: When scrolling, the newer files are deleted rather than the older ones. An example is as follows. #5986

Closed

Description

@airvehicle

NLog version: 6.0.3

Platform: .NET9 + Windows10

Current NLog config (C#)

 // Nlog version: 6.0.3

 // Nlog config:
 NLog.LogManager.Setup().LoadConfiguration(builder =>
 {
     builder 
     .ForLogger(loggerNamePattern: "*") 
     .FilterMinLevel(LogLevel.Trace) 
     .WriteToFile(fileName:  "${basedir}/logs/test.log",
                  archiveAboveSize: 1024 *10,
                  maxArchiveFiles: 10
                  );
 });

  // Logger
 var logger_test = LogManager.GetLogger("abc");
 
 // Loop test
 string msg = string.Concat(Enumerable.Repeat("ABCDEF", 200));
 int loop = 0;
 while (true)
 {
     Console.WriteLine("press any key to log...");
     Console.ReadKey(true);
 
     Parallel.For(0, 1000, i =>
     { 
         // to log
         logger_test.Trace(msg); 
     });
     Console.WriteLine($"loop-{++loop} completed");
 }

Test result:

   loop-1 completed:
            file list(10):
                test_91.log ... test99.log,
                test_111.log -----Q: Why is it 111? Why not 100?

   loop-2 completed:  
            file list(10):
                test_91.log ... test99.log,
                test_222.log -----Q: Why is it 222? And why not delete the older log-files? 

The old files or old serial numbers were not deleted; instead, the new files were deleted. Why??
This seems to be a bug.. Or did I use it incorrectly? Who can tell me how to correct it?

Activity

  1. snakefoot commented on Sep 5, 2025

    @snakefoot
    Contributor

    Thank you for providing this great feedback, and example code. The current archive-cleanup-logic is optimized for fileName containing ${date:format=yyyyMMdd-hh}, or if specifying archiveFileName. But of course it should also work, when just relying on the default sequence-number.

    Will improve the archive-cleanup-logic to better recognize the default sequence-number, and not just perform cleanup of sorting based on filename alone.

  2. snakefoot commented on Sep 5, 2025

    @snakefoot
    Contributor

    Created #5987 for NLog v6.0.4 (That will be released in 1 week)

  3. airvehicle commented on Sep 5, 2025

    @airvehicle
    Author

    Thank you for providing this great feedback, and example code. The current archive-cleanup-logic is optimized for fileName containing ${date:format=yyyyMMdd-hh}, or if specifying archiveFileName. But of course it should also work, when just relying on the default sequence-number.

    Will improve the archive-cleanup-logic to better recognize the default sequence-number, and not just perform cleanup of sorting based on filename alone.

    @snakefoot
    Thank you for your reply. After re-testing, this problem still persists..
    After I configured fileName:"${basedir}/logs/test_${date:universalTime=true:format=yyyyMMdd}.log", I also got the same result.
    This has brought about a serious problem: when Nlog is scrolling, it deletes the newer files but the older ones are not deleted instead. This will directly lead to the logs not being continuous, or in other words, the intermediate log contents are lost. This is really dangerous.

    // Nlog config:

    NLog.LogManager.Setup().LoadConfiguration(builder =>
    {
       builder 
       .ForLogger(loggerNamePattern: "*") 
       .FilterMinLevel(LogLevel.Trace) 
       .WriteToFile(fileName: "${basedir}/logs/test_${date:universalTime=true:format=yyyyMMdd}.log",
                    archiveAboveSize: 1024 *10,
                    maxArchiveFiles: 10
                    );
    });
    
  4. snakefoot commented on Sep 5, 2025

    @snakefoot
    Contributor

    Yes if you expect more than 100 log-files within a single day, then you need to specify ArchiveSuffix like this:

    NLog.LogManager.Setup().LoadConfiguration(builder =>
    {
       builder 
       .ForLogger(loggerNamePattern: "*") 
       .FilterMinLevel(LogLevel.Trace) 
       .WriteTo(new FileTarget() {
          FileName = "${basedir}/logs/test_${date:universalTime=true:format=yyyyMMdd}.log",
          ArchiveAboveSize = 1024 * 10,
          MaxArchiveFiles = 10,
          ArchiveSuffixFormat = "_{0:000000}",   // Handle 1 million files within a single day
        });
    });

    But believe #5987 will make the archive-cleanup-logic better at handling these special cases, without having to override ArchiveSuffixFormat.

  5. added this to the 6.0.4 milestone on Sep 5, 2025
  6. snakefoot commented on Sep 5, 2025

    @snakefoot
    Contributor

    You can try this pre-release to see if it improves the behavior of your initial example without ${date:universalTime=true:format=yyyyMMdd}.

    Download NLog.6.0.3.4495-PR5989.nupkg to a local nuget-folder (And rename from .zip to .nupkg) and then setup nuget-source in Visual Studio to point at the local folder.

    Because the FileTarget FileName supports dynamic values, then it is not easy for NLog FileTarget to determine the correct ordering for doing archive-cleanup. The best approach is ensuring the generated filenames are sortable by filename.

  7. snakefoot commented on Sep 11, 2025

    @snakefoot
    Contributor

    NLog v6.0.4 have now been released, and should improve the archive cleanup logic when using just sequence-number.

    Thanks again for the feedback, and helping to improve NLog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions