40

I'm trying to customise a log4net file path to use a property I have set in the log4net.GlobalContext.Properties dictionary.

log4net.GlobalContext.Properties["LogPathModifier"] = "SomeValue";

I can see that this value is set correctly when debugging through it. and then in my configuration

<file type="log4net.Util.PatternString" 
      value="Logs\%appdomain_%property{LogPathModifier}.log" />

However, the output of this gives me "_(null).log" at the end of the path. What gives?

Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188
Long Pham
  • 433
  • 1
  • 5
  • 5

4 Answers4

58

I ran into the same behavior and solved it by setting the global variable before calling the XmlConfigurator... Here is what I am successfully using:

log4net.config details:

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
  <File type="log4net.Util.PatternString" value="App_Data/%property{LogName}" />
  ...
</appender>

Global.asax details:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger("Global.asax");
void Application_Start(object sender, EventArgs e) 
{
    // Set logfile name and application name variables
    log4net.GlobalContext.Properties["LogName"] = GetType().Assembly.GetName().Name + ".log";
    log4net.GlobalContext.Properties["ApplicationName"] = GetType().Assembly.GetName().Name;

    // Load log4net configuration
    System.IO.FileInfo logfile = new System.IO.FileInfo(Server.MapPath("log4net.config"));
    log4net.Config.XmlConfigurator.ConfigureAndWatch(logfile);

    // Record application startup
    log.Debug("Application startup");
}

Hope this helps...

Dscoduc
  • 7,714
  • 10
  • 42
  • 48
  • 1
    I was having exactly same problem, in my case i was trying to log into same file from 2 different processes. It was getting in 2 separate files, but setting the global variable before calling the XmlConfigurator in second app solved the problem. Thank you very much. +1 – Tara Singh Sep 30 '11 at 19:19
  • 1
    i used `System.Reflection.Assembly.GetExecutingAssembly().GetName().Name` for the application name – Valamas Jan 13 '14 at 01:54
  • @Dscoduc Which class contains Server.MapPath could you please share the details – Venkat Aug 14 '17 at 05:23
16

Add type=log4net.Util.PatternString into File element

Noctis
  • 11,507
  • 3
  • 43
  • 82
4

The problem( I think) is that you GET(GetLogger) the logger before you set the name and load the config...

Try to do declare the logger like: private static log4net.ILog _pLog and then in the Application_Start do:

void Application_Start(object sender, EventArgs e) 
{
    // Set logfile name and application name variables
    log4net.GlobalContext.Properties["LogName"] = GetType().Assembly.GetName().Name + ".log";
    log4net.GlobalContext.Properties["ApplicationName"] = GetType().Assembly.GetName().Name;

    // Load log4net configuration
    System.IO.FileInfo logfile = new System.IO.FileInfo(Server.MapPath("log4net.config"));
    log4net.Config.XmlConfigurator.ConfigureAndWatch(logfile);

    //Get the loger
    _pLog = log4net.LogManager.GetLogger("Global.asax");

    // Record application startup
    pLog .Debug("Application startup");
}

So the sequence is:

// Set logfile name and application name variables
// Load log4net configuration
// get the logger
// Record application startup
Noctis
  • 11,507
  • 3
  • 43
  • 82
1

Has the logger been initialized through the global or main method in the application? It could be that the GlobalContext has not been initialize yet.

Dillie-O
  • 29,277
  • 14
  • 101
  • 140
  • I have called LogManager.GetLogger() before setting the property. Also, logging is working correctly, its just that the file name is not picking up the custom value. – Long Pham Feb 19 '09 at 09:33