VansFannel
VansFannel

Reputation: 45921

Log4net is not writing anything in log files

I'm developing a Windows Service application with C#, .NET Framework 4.7 and log4net 2.08.

My problem is that log4net is not logging anything. It only creates the files and nothing else.

This is my configuration file (app.config):

<log4net>
    <appender type="log4net.Appender.RollingFileAppender" name="ERPErrorAppender">
        <file value="D:\MyCompany\Logs\ERP_Service.Error.log" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <datePattern value=".yyyyMMdd.lo\g" />
        <maximumFileSize value="5MB" />
        <maxSizeRollBackups value="-1" />
        <countDirection value="1" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date %-5level [%thread] %logger - %message%newline%exception" />
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="WARN" />
            <levelMax value="ERROR" />
        </filter>
    </appender>
    <appender type="log4net.Appender.RollingFileAppender" name="ERPDebugAppender">
        <file value="D:\MyCompany\Logs\ERP_Service.Debug.log" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <datePattern value=".yyyyMMdd.lo\g" />
        <maximumFileSize value="5MB" />
        <maxSizeRollBackups value="-1" />
        <countDirection value="1" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date %-5level [%thread] %logger - %message%newline%exception" />
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="DEBUG" />
            <levelMax value="INFO" />
        </filter>
    </appender>
    <logger name="ERPService_Error">
        <level value="ERROR" />
        <appender-ref ref="ERPErrorAppender" />
    </logger>
    <logger name="ERPService_Debug">
        <level value="DEBUG" />
        <appender-ref ref="ERPDebugAppender" />
    </logger>
</log4net>

And the contents in Program.cs:

static class Program
{
    private static readonly log4net.ILog log =
        log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

And the contents in my ServiceBase class:

public partial class ERPWindowsService : ServiceBase
{
    private static readonly ILog _log =
        LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

And when I catch an exception in my ServiceBase class:

catch (Exception ex)
{
    _log.Error(ex);

    this.Stop();
}

And when I Stop the service (I do the same on OnStart):

protected override void OnStop()
{
    _log.Debug("OnStop");

    // Stop timer and dispose it.
    if (_timer != null)
    {
        try
        {
            _timer.Stop();

            _timer.Dispose();
        }
        catch (Exception ex)
        {
            _log.Error(ex);
        }
    }
}

Why it is not writing anything on files?

I have restarted the service and the log files remain empty.

Upvotes: 3

Views: 3274

Answers (2)

pfx
pfx

Reputation: 23214

You mention that the log files get created, this means that the configuration has been loaded successfully.

Since you haven't configured a root logger (which is valid to do so), but only named loggers, you must make sure that the configured names match with the ones given to the ILog instances.

This is where it goes wrong.

Your ILog instances get named via the type returned from the line below.

System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

This will be the FullName of the Type, including its namespace.

For class Program this will be YourNamespace.Program.
For class ERPWindowsService this will be YourNamespace.ERPWindowsService.

You must use these full names in the Log4net configuration.

<logger name="YourNamespace.ERPWindowsService">         
    <level value="DEBUG" />
    <appender-ref ref="ERPDebugAppender" />
</logger>

Because there is no root logger configured, an explicit one must be configured for each ILog instance; here for class Program.

<logger name="YourNamespace.Program">         
    <!-- .... -->
</logger>

Alternatively, you can assign explicit names to your ILog instances, eg.:

 log4net.ILog log = log4net.LogManager.GetLogger("ERPService_Error");

to match with your current Log4net configuration.

<logger name="ERPService_Error">

Upvotes: 5

Rob
Rob

Reputation: 120

j.v. in your comments is correct. Make sure that if you are configuring the logger in your AssemblyInfo.cs file, that it points to the correct xml configuration file (in your case app.config).

Alternatively you can call

log4net.Config.XmlConfigurator.Configure();

Or one of its overloads from within your program.cs file.

This thread might provide some more explanation.

Upvotes: 1

Related Questions