Question

I want to set a Rolling Appender dynamic in code rather than in config file. So I have a function that will return log4net.ILog

    <Assembly: log4net.config.XmlConfigurator(ConfigFile:="Log4Net.config", Watch:=True)> 
Public Function genLogXMLCfg(cls As Object) As log4net.ILog
    Dim clsName As String = cls.ToString()
    Dim rollAppen As New RollingFileAppender()

    rollAppen.Name = clsName + "Appender"
    rollAppen.RollingStyle = RollingFileAppender.RollingMode.Composite
    rollAppen.File = "logs\\"
    rollAppen.DatePattern = "'" + clsName.ToLower() + "'" + "yyyyMMdd'.log'"
    rollAppen.LockingModel = New log4net.Appender.FileAppender.MinimalLock()
    rollAppen.AppendToFile = True
    rollAppen.StaticLogFileName = False
    rollAppen.MaxSizeRollBackups = 3
    rollAppen.MaximumFileSize = "100KB"
    Dim layout As New log4net.Layout.PatternLayout("%d [%t] %-5p %c (line:%L) - %m%n")
    rollAppen.Layout = layout
    layout.ActivateOptions()
    rollAppen.ActivateOptions()

    Dim logg As ILog = LogManager.GetLogger(clsName)
    Dim l As log4net.Repository.Hierarchy.Logger = DirectCast(logg.Logger, log4net.Repository.Hierarchy.Logger)
    l.AddAppender(rollAppen)
    l.Repository.Configured = True
    Return logg      
End Function

Because I want to dynamic generate rolling appender from code but at the same time I want to set the logger from config file, so I have following config file call (Log4Net.config)

   <configSections>
       <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />     
   </configSections>
   <appSettings>    
    <add key="log4net.Config" value="log4net.config"/>
    <add key="log4net.Config.Watch" value="True"/>
   </appSettings>
<log4net>
    <logger name="ConsoleApplication1.LogTest2">
        <level value="WARN" />      
    </logger>
    <logger name="ConsoleApplication1.testCls">
        <level value="INFO" />
    </logger>
</log4net>

Now I test the function by following code:

       Dim cls As LogTest2 = New LogTest2()
    Dim tCls As testCls = New testCls()
    Dim l4n As log4net.ILog
    Dim l4n2 As log4net.ILog

    l4n = cls.genLogXMLCfg(tCls.GetType().ToString())
    l4n2 = cls.genLogXMLCfg(cls.GetType().ToString())

    l4n.Debug("... Here is a debug log -2.")
    l4n.Info("... and an Info log.")
    System.Threading.Thread.Sleep(3000)
    l4n.Warn("... and a warning 1.")
    l4n.Debug("... Here is a debug log -1.")
    l4n.Warn("... and a warning 2.")
    l4n.Warn("... and a warning 3.")
    l4n2.Warn("l4n2 cls and a warning -1.")
    l4n.Warn("... and a warning 4.")
    l4n.Warn("... and a warning 5.")
    Console.Write(" ... ... ... ")
    System.Threading.Thread.Sleep(3000)
    l4n.Warn("... and a warning 6.")
    l4n.Debug("... Here is a debug log 1.")
    l4n.Warn("... and a warning 7.")
    l4n2.Debug("l4n2 cls Here is a debug log.")
    l4n2.Info("l4n2 cls and an Info log.")
    l4n.Fatal("... and a fatal .")
    l4n2.Fatal("l4n2 and a fatal .")
    l4n.Debug("... Here is a debug log 2.")
    l4n.Warn("... and a warning 8.")
    l4n.Error("... and an error.")
    l4n.Debug("... Here is a debug log 3.")
    l4n.Fatal("... and a fatal .")
    l4n.Debug("... Here is a debug log 4.")
    l4n2.Debug("l4n2 cls Here is a debug log.")
    l4n2.Info("l4n2 cls and an Info log.")
    l4n2.Warn("l4n2 cls and a warning.")
    l4n2.Error("l4n2 cls and an error.")
    l4n2.Fatal("l4n2 cls and a fatal .")

After that, two log file generated in logs folder call

**consoleapplication1.logtest220130610.log** and **consoleapplication1.testcls20130610.log**
The content are:

**consoleapplication1.logtest220130610.log**
2013-06-10 18:41:38,802 [9] WARN  ConsoleApplication1.LogTest2 (line:182) - l4n2 cls and a warning -1.
2013-06-10 18:41:41,819 [9] FATAL ConsoleApplication1.LogTest2 (line:193) - l4n2 and a fatal .
2013-06-10 18:41:41,831 [9] WARN  ConsoleApplication1.LogTest2 (line:206) - l4n2 cls and a warning.
2013-06-10 18:41:41,833 [9] ERROR ConsoleApplication1.LogTest2 (line:207) - l4n2 cls and an error.
2013-06-10 18:41:41,836 [9] FATAL ConsoleApplication1.LogTest2 (line:208) - l4n2 cls and a fatal .


**consoleapplication1.testcls20130610.log**
2013-06-10 18:41:35,767 [9] INFO  ConsoleApplication1.testCls (line:176) - ... and an Info log.
2013-06-10 18:41:38,792 [9] WARN  ConsoleApplication1.testCls (line:178) - ... and a warning 1.
2013-06-10 18:41:38,795 [9] WARN  ConsoleApplication1.testCls (line:180) - ... and a warning 2.
2013-06-10 18:41:38,800 [9] WARN  ConsoleApplication1.testCls (line:181) - ... and a warning 3.
2013-06-10 18:41:38,804 [9] WARN  ConsoleApplication1.testCls (line:183) - ... and a warning 4.
2013-06-10 18:41:38,806 [9] WARN  ConsoleApplication1.testCls (line:184) - ... and a warning 5.
2013-06-10 18:41:41,809 [9] WARN  ConsoleApplication1.testCls (line:187) - ... and a warning 6.
2013-06-10 18:41:41,813 [9] WARN  ConsoleApplication1.testCls (line:189) - ... and a warning 7.
2013-06-10 18:41:41,817 [9] FATAL ConsoleApplication1.testCls (line:192) - ... and a fatal .
2013-06-10 18:41:41,823 [9] WARN  ConsoleApplication1.testCls (line:195) - ... and a warning 8.
2013-06-10 18:41:41,826 [9] ERROR ConsoleApplication1.testCls (line:196) - ... and an error.
2013-06-10 18:41:41,828 [9] FATAL ConsoleApplication1.testCls (line:199) - ... and a fatal .

Everything are OKAY. But.... If I change the config file during the program running, let say I change the level from INFO to FATAL

            <logger name="ConsoleApplication1.testCls">
            <level value="FATAL" />  <!-- INFO to FATAL -->
        </logger>

the two log file now are:

 **consoleapplication1.logtest220130610.log**
2013-06-10 19:05:20,880 [9] WARN  ConsoleApplication1.LogTest2 (line:182) - l4n2 cls and a warning -1.
**consoleapplication1.testcls20130610.log**
2013-06-10 19:05:17,848 [9] INFO  ConsoleApplication1.testCls (line:176) - ... and an Info log.
2013-06-10 19:05:20,872 [9] WARN  ConsoleApplication1.testCls (line:178) - ... and a warning 1.
2013-06-10 19:05:20,875 [9] WARN  ConsoleApplication1.testCls (line:180) - ... and a warning 2.
2013-06-10 19:05:20,877 [9] WARN  ConsoleApplication1.testCls (line:181) - ... and a warning 3.
2013-06-10 19:05:20,884 [9] WARN  ConsoleApplication1.testCls (line:183) - ... and a warning 4.
2013-06-10 19:05:20,886 [9] WARN  ConsoleApplication1.testCls (line:184) - ... and a warning 5.

I wonder that why the watch function cannot update log properly and seem will affect other log file even I only change one logger data? May I know the reason? What wrong of my code

Was it helpful?

Solution

When you change your config file will your program is running. Log4net will reread you config file because of the Watch:=True. However your genLogXMLCfg is not executed. So your configuration of your appenders in not configured after you save the new config. There is no appender, so you do not see any new entries in your logs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top