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
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.