3

I have 3 appenders in my config file for creating 3 different types of logs. I am using dynamic naming of file in each of the 3 appenders by setting the global context properties. In some cases, i need to set the log file name dynamically for just 1 appender.
When i set the file name for just 1 appender, it creates another file named "null" with no data in addition to the actual logfile whose name has been set dynamically. I have created the config file as shown.

<appender name="RollingFileAppenderV1" type="log4net.Appender.RollingFileAppender">   
<file type="log4net.Util.PatternString" value="Logs\%property{applog}" /> 
.
.
.
<appender name="RollingFileAppenderV2" type="log4net.Appender.RollingFileAppender"> 
<file type="log4net.Util.PatternString" value="Logs\%property{dblog}" />
.
.
.
<logger name="Logger1"> 
<level value="DEBUG" /> 
<appender-ref ref="RollingFileAppenderV1" /> 
</logger> 
<logger name="Logger2"> 
<level value="DEBUG" /> 
<appender-ref ref="RollingFileAppenderV2" /> 
</logger> 

In the VB.NET code i set the filename as :

log4net.GlobalContext.Properties("applog") = "file1.log"  
Dim logobj as log4net.Ilog = LogManager.GetLogger("Logger1")   
logobj.debug("test") 

In this case it creates "file1.log" and also another empty file with name as "null". This happens only when i am setting either of the appenders filename at runtime. Any help appreciated.

Ranjith
  • 31
  • 1
  • 3

3 Answers3

6

As far as I know the log file is created the moment you configure log4net. This means that you need to make sure to set the property first and configure log4net afterwards.

e.g.

log4net.GlobalContext.Properties["applog"] = "file1.log"
log4net.Config.XmlConfigurator.Configure();
Martin
  • 10,738
  • 14
  • 59
  • 67
  • What about if I need to change the property more that one time ? Supose it starts with "file1.log" and after some reasons I need to change it to "anotherfile.log" at global context (not thread context). – Luciano Mar 20 '14 at 16:46
  • This does not work for my case (similar with the OP). I already set the Global Context before, but it does not work. – Hoàng Long Oct 16 '15 at 09:04
  • 1
    Sorry, I'm wrong. The problem is that I already have another log4net configuration in assembly file, so it is called "before" setting the file name dynamically. Removing that resolved the problem – Hoàng Long Oct 16 '15 at 09:12
0

I had exactly the same problem. Calling XmlConfigurator.Configure() created two files - one with the correct file path and the other with 'null' named file in the folder from which the assembly runs.

I solved this by initializing all of my file path properties to string.Empty before calling XmlConfigurator.Configure() for the first time.

So, in your case, the following code should solve the issue:

log4net.GlobalContext.Properties("applog") = "file1.log"

' Set all of the other properties defined in the config file to String.Empty.
' By default, they are null and cause the issue.
log4net.GlobalContext.Properties("dblog") = String.Empty

log4net.Config.XmlConfigurator.Configure()

Dim logobj as log4net.Ilog = LogManager.GetLogger("Logger1")
logobj.debug("test")
tetsushmz
  • 11
  • 2
0

There is discussion about this very thing on the log4net github page:

https://github.com/net-commons/common-logging/issues/81

I won't paraphrase the entire discussion, but the suggested workaround, until properties can be overridden dynamically, is to instruct log4net to reset its configuration explicitly:

// This line sets the properties in global context
var dummy = Common.Logging.LogManager.GetLogger("dummy");

// Now reset the ILoggingFactoryAppender to null so log4net needs to be re-configured
Common.Logging.LogManager.Reset(); 

// Now you can override properties in the global context
dummy.GlobalVariablesContext.Set("LogsDirectory", "C:\\Logs");

// Access to LogManager.GetLogger() triggers log4net initialization because the ILoggingFactoryAppender was set to NULL by LogManager.Reset().
var logger = Common.Logging.LogManager.GetLogger<MyLogger>();
Ashby
  • 583
  • 9
  • 20