2

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.

VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • Have you added any logging other than in an exception handler? Have you debugged it to try to check that you're actually hitting a line which logs something? I'd add a line to log a "starting" message just to check... – GPW Jul 20 '18 at 08:58
  • Yes, I've done all of that. See my updated question, please. – VansFannel Jul 20 '18 at 09:01
  • Search for this line [assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4net.config", Watch = true)] and check if it match name of your log4net config file – j.v. Jul 20 '18 at 09:13
  • You are missing a root logger. Is this supported? – sgmoore Jul 20 '18 at 09:22
  • @j.v. I used log4net in many projects and in none I use that. – VansFannel Jul 20 '18 at 10:07
  • @sgmoore I'm not using root and I think it is not supported. – VansFannel Jul 20 '18 at 10:08
  • @j.v. I have added that in AssemblyInfo, and it still doesn't write anything in the log files. – VansFannel Jul 20 '18 at 10:22
  • I don't know how did it, but thanks for downvoting and don't telling why. It is very constructive. – VansFannel Jul 20 '18 at 10:37

2 Answers2

3

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">
pfx
  • 20,323
  • 43
  • 37
  • 57
0

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.

Rob
  • 110
  • 4