Skip to content

RollingFileAppender overwrites an old log even if AppendToFile is true when RollingStyle is Composite and there are some logs on that day. #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
WorldRobertProject opened this issue Aug 2, 2024 · 9 comments
Assignees

Comments

@WorldRobertProject
Copy link

When RollingStyle is Composite, it seems RollingFileAppender ignores AppendToFile flag except for the first log on that day.

The following code makes log files as 2024-08-02.0.log, 2024-08-02.1.log, ...

log4net.config.xml

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <log4net>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
      <param name="File" value=".\Log\" />
      <param name="AppendToFile" value="true" />
      <param name="RollingStyle" value="Composite" />
      <param name="DatePattern" value='yyyy-MM-dd".log"' />
      <param name="MaximumFileSize" value="5MB" />
      <param name="MaxSizeRollBackups" value="10" />
      <param name="StaticLogFileName" value="false" />
      <param name="CountDirection" value="1" />
      <param name="PreserveLogFileNameExtension" value="true"/>
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d{yyyy/MM/dd HH:mm:ss.fff} [%-5p] %m (%M)%n"/>
      </layout>
    </appender>

    <logger name="log">
      <level value="debug" />
      <appender-ref ref="LogFileAppender" />
    </logger>
  </log4net>
</configuration>

Program.cs

using log4net;
using log4net.Config;
using System.Reflection;

var pathConfig = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config.xml");
XmlConfigurator.Configure(new FileInfo(pathConfig));

var assembly = Assembly.GetEntryAssembly();
var logger = LogManager.GetLogger(assembly, "log");

logger.Info("Hello, log4net!");

When only 2024-08-02.0.log exists, it appends a new log to 2024-08-02.0.log as expected.
When both 2024-08-02.0.log and 2024-08-02.1.log exist and 2024-08-02.0.log is greater than 5MB, this code overwrites 2024-08-02.1.log and outputs the following error message:

log4net:ERROR RollingFileAppender: INTERNAL ERROR. Append is False but OutputFile [...\Log\2024-08-02.1.log] already exists.

It seems AppendToFile flag is ignored.

All log4net versions from 2.0.10 to 2.0.17 reproduce this issue.

@WorldRobertProject
Copy link
Author

I confirmed that 3.0.0-preview.2 also reproduces this issue.

@FreeAndNil
Copy link
Contributor

Hi @WorldRobertProject,

thanks for reporting.
I can reproduce your problem, but I haven't found the time to fix it yet.

@gdziadkiewicz
Copy link
Contributor

Hi @WorldRobertProject,

I found some time to dig in properly. The current codebase does not support specifying the extension in the DatePattern.
To get the behaviour you are looking for, you could go with:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <log4net>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
      <param name="File" value=".\Log\.log" />
      <param name="AppendToFile" value="true" />
      <param name="RollingStyle" value="Composite" />
      <param name="DatePattern" value='yyyy-MM-dd' />
      <param name="MaximumFileSize" value="5MB" />
      <param name="MaxSizeRollBackups" value="10" />
      <param name="StaticLogFileName" value="false" />
      <param name="CountDirection" value="1" />
      <param name="PreserveLogFileNameExtension" value="true"/>
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d{yyyy/MM/dd HH:mm:ss.fff} [%-5p] %m (%M)%n"/>
      </layout>
    </appender>

    <logger name="log">
      <level value="debug" />
      <appender-ref ref="LogFileAppender" />
    </logger>
  </log4net>
</configuration>

This will work thanks to the <param name="PreserveLogFileNameExtension" value="true"/> combined with file extension specified in <param name="File" value=".\Log\.log" /> .
Resulting log files:

  • .\Log\2025-02-25.0.log
  • .\Log\2025-02-25.1.log
    ...

You can also use the File to add a prefix to the log file names <param name="File" value=".\Log\prefix.log" /> + <param name="PreserveLogFileNameExtension" value="true"/>
Resulting log files:

  • .\Log\prefix2025-02-25.0.log
  • .\Log\prefix2025-02-25.1.log

@FreeAndNil I'm wondering if we should add support for specifying the extension in the DatePattern (could be a breaking change for some users) or focus on documenting the current behaviour better.

@WorldRobertProject
Copy link
Author

Thank you, @gdziadkiewicz,

We also found the same solution before, but this time MaxSizeRollBackups is ignored and log files for the same day are created endlessly.
So we thought this is just a workaround.

If this is the correct solution, we think the true issue is that MaxSizeRollBackups is ignored in this case.

@gdziadkiewicz
Copy link
Contributor

gdziadkiewicz commented Feb 25, 2025

Hi @WorldRobertProject , you are right. I just reproduced this bug with MaxSizeRollBackups. I created #231 to track it and make it easier for affected users to find it.

@FreeAndNil
Copy link
Contributor

@WorldRobertProject can you test whether #232 solves your problem?

@WorldRobertProject
Copy link
Author

Now when "DatePattern" is "yyyy-MM-dd", it reproduces the issue.

log4net:ERROR RollingFileAppender: INTERNAL ERROR. Append is False but OutputFile [...\Log\2025-03-21.1.log] already exists.

When "DatePattern" is 'yyyy-MM-dd".log"', it causes the following error:

log4net:ERROR Could not create Appender [LogFileAppender] of type [log4net.Appender.RollingFileAppender]. Reported error follows.
System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
   at System.ArgumentNullException.Throw(String paramName)
   at System.IO.Path.Combine(String path1, String path2)
   at log4net.Appender.RollingFileAppender.InitializeFromOneFile(String baseFile, String curFileName) in ...\logging-log4net\src\log4net\Appender\RollingFileAppender.cs:line 794
   at log4net.Appender.RollingFileAppender.InitializeRollBackups(String baseFile, IList`1 arrayFiles) in ...\logging-log4net\src\log4net\Appender\RollingFileAppender.cs:line 910
   at log4net.Appender.RollingFileAppender.DetermineCurSizeRollBackups() in ...\logging-log4net\src\log4net\Appender\RollingFileAppender.cs:line 654
   at log4net.Appender.RollingFileAppender.ExistingInit() in ...\logging-log4net\src\log4net\Appender\RollingFileAppender.cs:line 748
   at log4net.Appender.RollingFileAppender.ActivateOptions() in ...\logging-log4net\src\log4net\Appender\RollingFileAppender.cs:line 1025
   at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement) in ...\logging-log4net\src\log4net\Repository\Hierarchy\XmlHierarchyConfigurator.cs:line 316
log4net:ERROR Appender named [LogFileAppender] not found.

@gdziadkiewicz
Copy link
Contributor

Hi @WorldRobertProject
I was able to reproduce the second case and add a guard to prevent it from failing. Could you share more about your config from the first one? I'm not able to reproduce it; it works as expected on my machine.

@WorldRobertProject
Copy link
Author

Here is the setting which reproduces the issue.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <log4net>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
      <param name="File" value=".\Log\.log" />
      <param name="AppendToFile" value="true" />
      <param name="RollingStyle" value="Composite" />
      <param name="DatePattern" value="yyyy-MM-dd" />
      <param name="MaximumFileSize" value="3MB" />
      <param name="MaxSizeRollBackups" value="3" />
      <param name="StaticLogFileName" value="false" />
      <param name="CountDirection" value="1" />
      <param name="PreserveLogFileNameExtension" value="true"/>
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d{yyyy/MM/dd HH:mm:ss.fff} [%-5p] %m (%M)%n"/>
      </layout>
    </appender>

    <logger name="log">
      <level value="debug" />
      <appender-ref ref="LogFileAppender" />
    </logger>
  </log4net>
</configuration>

Here is the test code.

using log4net;
using log4net.Config;
using System;
using System.IO;
using System.Reflection;

namespace TestLog4net
{
    class Program
    {
        private static void Main()
        {
            var pathConfig = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config.xml");
            XmlConfigurator.Configure(new FileInfo(pathConfig));

            var assembly = Assembly.GetEntryAssembly();
            var logger = LogManager.GetLogger(assembly, "log");

            logger.Info("Hello, log4net!");
        }
    }
}

We prepared the following three log files:

  • 2025-04-10.0.log (4.10 MB)
  • 2025-04-10.1.log (4.10 MB)
  • 2025-04-10.2.log (4.10 MB)

After we executed the test code, 2025-04-10.1.log was truncated and overwritten.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants