log4net create logging file but do not append any log item

66 Views Asked by At

C# application which is executed with .NETFramework 4.7.2.

We have been using log4net for several years now and have always been satisfied. Unfortunately, since version 2.0.12 we have been having problems with the log not being written. When I delete the old log file, a new file is created, but no log entries are added to the file.

Here is the entry in the App.config:

  <log4net>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="Log\WMS4_Server_Log.xml" />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="5" />
      <maximumFileSize value="10MB" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
        <locationInfo value="true" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>

Can anyone give us a hint as to why this might be?

I have added the following entry in the Main() method as suggested:

log4net.Config.XmlConfigurator.Configure();

That helped for a while, but now we have the same problem again. We are now ready to replace log4net with another logger if there is no remedy. I also enabled the internal logging but didn't get any hint.

1

There are 1 best solutions below

1
user246821 On

The following shows how one can use Nuget package log4Net to write to a log file. It's been tested with Nuget package log4Net (v2.0.15). While the code below does write to the log file, I'm not all that familiar with log4net, so you may have to modify the code below to get the output in the desired format.

Note: The following will write to log file: %ProgramData%\log4netTest\Logs\log.xml. Also, you'll notice that I've used .NET Framework v4.8 for the test, so change the value as necessary.

App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <!-- see https://logging.apache.org/log4net/release/sdk/index.html => log4net.config => Log4NetCofigurationSectionHandler  Class -->
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    </configSections>
    <log4net>
        <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
            <file value="${ProgramData}\log4netTest\Logs\log.xml"/>
            <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="5" />
            <maximumFileSize value="10MB" />
            <staticLogFileName value="true" />
            <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
                <locationInfo value="true" />
            </layout>
        </appender>

        <root>
            <level value="ALL" />
            <appender-ref ref="LogFileAppender" />
        </root>
    </log4net>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
    </startup>
</configuration>

Here's a test project that logs the current time every 5 seconds. To re-create the test project I used:

Create a Windows Forms App (.NET Framework) (name: log4netTest)

Add two buttons to Form1

  1. name: buttonStart
  2. name: buttonStop

enter image description here

Note: In the form designer, double-click each button to add the Click event handler.

Form1.cs:

using log4net;
using System;
using System.Reflection;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Security.Principal;

namespace log4netTest
{
    public partial class Form1 : Form
    {
        private Timer timer1 = new Timer();
        private ILog log = null;

        private static string logFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().Location));
        private static string logFilename = Path.Combine(logFolder, "Logs", "log.xml");
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Debug.WriteLine($"Log Folder: {logFolder}");
            Debug.WriteLine($"Log Filename: {logFilename}");

            //create directory if it doesn't exist
            if (!Directory.Exists(logFolder))
                Directory.CreateDirectory(logFolder);

            //set access
            DirectorySecurity logFolderSecurity = new DirectorySecurity(logFolder, AccessControlSections.Access);
            logFolderSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
           
            DirectoryInfo logFolderInfo = new DirectoryInfo(logFolder);
            logFolderInfo.SetAccessControl(logFolderSecurity);

            //initialize the log
            //To use this method to configure log4net you must specify the
            //'Log4NetConfigurationSectionHandler' section handler for the log4net configuration section.
            //see the 'Log4NetConfigurationSectionHandler' for an example.

            log4net.Config.XmlConfigurator.Configure();

            log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

            timer1.Interval = 5 * 1000; //5 secs

            //subscribe to event
            timer1.Tick += timer1_Tick;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            log.Info($"The current time is {DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff")}");
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            timer1.Stop();
        } 
    }
}

Resources: