125
votes

Hey I have this configuration in my web.config

<log4net>
    <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
        <param name="File" value="mylog.log" />
        <param name="AppendToFile" value="true" />
        <layout type="log4net.Layout.PatternLayout">
            <param name="Header" value="" />
            <param name="Footer" value="" />
            <param name="ConversionPattern" value="%d [%t] %-5p %m%n" />
        </layout>
    </appender>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
        <layout type="log4net.Layout.PatternLayout">
            <param name="Header" value="[Header]\r\n" />
            <param name="Footer" value="[Footer]\r\n" />
            <param name="ConversionPattern" value="%d [%t] %-5p %m%n" />
        </layout>
    </appender>
    <root>
        <level value="DEBUG" />
        <appender-ref ref="LogFileAppender" />
        <appender-ref ref="ConsoleAppender" />
    </root>
</log4net>

but log4net is not working. My project compiles fine, and I get no errors debugging either. The lines where I tell to log.debug("somemessage") gets run fine, but I can't find the mylog.log file, so where is it?

16

16 Answers

306
votes

One gotcha for this type of thing is to make sure to add the XmlConfigurator attribute to the assembly by placing the following line in your AssemblyInfo.cs:

[assembly: log4net.Config.XmlConfigurator]

Otherwise log4net never activates.

51
votes

I guess that either log4net is not logging at all, or the file is not ending up where you expect it.

Firstly, have you actually called

XmlConfigurator.Configure()

anywhere in your code? If the xml snippet above is in the application configuration file, this call will do the trick. If the xml snippet is in it's own file, you'll need to use the .Configure(string) overload that takes the path to the file. Without this call (or apparently the assembly level attribute mentioned by Kirk Woll), then log4net won't be logging at all.

If you believe this is all done, and log4net should be logging, then maybe you should put a fully qualified path in for the log file while you debug further. That will let you be sure where the file should be.

35
votes

There is another small gotcha, see here: http://logging.apache.org/log4net/release/manual/configuration.html#dot-config

the [assembly: log4net.Config.XmlConfigurator] method doesn't work with app.config. If you configure log4net from app.config, you must use the log4net.Config.XmlConfigurator.Configure() method.

22
votes

Here is my checklist for when log4net is proving to be recalcitrant:

  • ensure that log4net.config file is copied to the bin\ folder when building (set to 'Copy if newer' in compiler)
    • when dealing with installed code, ensure that the log4net.config came along for the ride (set to 'Content' in compiler)
  • ensure that the user that the process runs as has write rights to the folder where the logs are to be written
  • if in doubt, give promiscuous permissions to c:\temp\ and get everything to log to there ()
  • fire up Sysinternal/Dbgview.exe to see if that tells you anything
8
votes

For an ASP.NET MVC project adding

log4net.Config.XmlConfigurator.Configure();

to the Global.asax.cs also helps:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();

        log4net.Config.XmlConfigurator.Configure();
    }
}
7
votes

These are the steps which eventually got my file logging working:

  • -Check AssemblyInfo.cs contains the following attribute. [assembly: log4net.Config.XmlConfigurator]. This loads log4net.
  • Check the log directory has write permissions.
  • Check the logger has a format specified. This is done by checking each element in your configuration has a layout element specified. Eg:

<appender name="MainLogger"... <layout type="log4net.Layout.SimpleLayout"/>

  • Finally, try turning on log4net internal logging to enable console logging and checking the console. To do this, add <add key="log4net.Internal.Debug" value="true"/> to your appSettings.
6
votes

I've had experiences where logging systems fail silently without raising exceptions. I suppose this makes sense because if the logger is logging errors then how can it log an error that it's unable to perform logging?

So if the file isn't created on disk, start by looking into file system permissions to ensure the user your application is running under can write a new file to that disk location.

For testing purposes you might want to manually create the file on disk that should be written to and open up permissions for everybody to write to it. If the logger starts writing to it then you know it's permission based rather than configuration based.

3
votes

On my side, I forgot to mark the config file to be copied while the app is being compiled.

Copy the config file to output directory

Just right click the log4net.config file, select property and then choose Copy to Output Directory to be Copy XXXX

2
votes

Unfortunately none of the above helped. Explicit configuration in the class to be logged additionaly to the previous settings suggestions did the trick for me.

string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
log4net.Config.XmlConfigurator.Configure(new FileInfo(assemblyFolder + "/log4net.config"));
1
votes

I tried all of the above but nothing worked. Adding this line in app.config's configSections section worked for me.

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a" />

Ensure that Version and PublicKeyToken is correct

1
votes

So, in the Accepted Answer, the solution was to put

[assembly: log4net.Config.XmlConfigurator]

into the AssemblyInfo.cs File.

Also, there was a comment sugesting

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

however, if it is still not working, consider configuring the name of your log4net config file (log4net.config in my case):

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")]

after that, logging worked like a charm.

0
votes
<param name="File" value="mylog.log" />

is saying "write mylog.log to actual folder". This means that if your webapp is under IIS, then log will be written to C:\inetpub\wwwroot\appname\mylog.log.

If log file is not there, then maybe account under which is app running doesn't have write permission on folder. You can run Process Monitor from SysInternals to see if and where a file is written.

Also run VS in debug mode, to see if any exceptions are thrown (Debug->Exceptions->CLR Exceptions, check Thrown).

0
votes

In my case I forget to set the log4Net.config file properties as "Content" so the file was not included in the deploy. So pay attention on it:

Compile action : Content
0
votes

Check your Reporting level is set to "Debug" or "ALL". This caught me and I spent ages trying to debug my log4net setup. I had it set to Error and as it wasn't erroring it didn't log anything.

0
votes

Aside from all the other answers, my problem that was I needed a call to GetLogger() in my start-up class (WinForms example):

static class Program
{
    public static readonly ILog MainLog = LogManager.GetLogger("Main");

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

All my 'meaningful' logging statements were in a DLL that is apparently loaded too late for log4net.

-7
votes

Also after some hours, I figured out why it wasn't working for me...

i had:

public static class Program
{

    private static CommunicationManager _bcScanner = new CommunicationManager();
    private static ILog _log = LogManager.GetLogger(typeof(Program));
    private static SocketServer socketListener;

but it should be:

public static class Program
    {
        private static ILog _log = LogManager.GetLogger(typeof(Program));
        private static CommunicationManager _bcScanner = new CommunicationManager();
        private static SocketServer socketListener;

So make sure the ILog is on the first line....