【问题标题】:Log4net dynamic separate log does not work?Log4net 动态分离日志不起作用?
【发布时间】:2013-06-13 03:07:03
【问题描述】:

我有一个配置文件如下:

<configuration>
<configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />        
</configSections>
<appSettings> 
    <add key="log4net.Config" value="log4net.config"/>
</appSettings>
<log4net>
    <appender name="appenderA" type="log4net.Appender.RollingFileAppender">
        <file type="log4net.Util.PatternString" value="logs\\%property{LogName}" />
        <param name="AppendToFile" value="true" />
        <param name="RollingStyle" value="Composite" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <maxSizeRollBackups value="3" />
        <maximumFileSize value="5KB" />     
        <staticLogFileName value="true" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%d [%t] %-5p %c [%logger] = %m%n" />
        </layout>
    </appender>
    <logger name="ConsoleApplication1.testCls">
        <level value="INFO" />          
    </logger>   
    <root>
        <level value="ALL" />
        <appender-ref ref="appenderA" />
    </root>
</log4net>
</configuration>

然后我有一个函数会返回log4net.ILog

Public Function func(cls As Object) As log4net.ILog
    Dim clsName As String = cls.ToString()
    Dim rollAppen As New RollingFileAppender()

    log4net.ThreadContext.Properties("LogName") = clsName.ToLower() & ".log"
    log4net.Config.XmlConfigurator.Configure(New System.IO.FileInfo("Log4Net.config"))
    Dim logg As ILog = LogManager.GetLogger(clsName)
    Dim l As log4net.Repository.Hierarchy.Logger = DirectCast(logg.Logger, log4net.Repository.Hierarchy.Logger)
    If l.Level Is Nothing Then
        l.Level = l.Hierarchy.LevelMap("INFO")
    End If
    Return logg
End Function

现在我测试函数 func

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

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

    l4n.Debug("... Here is a debug log -2.")
    l4n.Info("... and an Info log.")
    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(" ... ... ... ")
    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 aaa.")
    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 bbb.")
    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 .")

生成了 2 个名为 consoleapplication1.testcls.logconsoleapplication1.logtest2.log 的日志文件。但是……

只有consoleapplication1.logtest2.log有日志内容,所有日志内容保存到consoleapplication1.logtest2.log。生成了另一个日志 consoleapplication1.testcls.log,但其中没有内容。

consoleapplication1.testcls.log
====no content====

consoleapplication1.logtest2.log
2013-06-13 11:00:33,390 [11724] INFO   = ... and an Info log.
2013-06-13 11:00:36,408 [11724] WARN   = ... and a warning 1.
2013-06-13 11:00:36,411 [11724] WARN   = ... and a warning 2.
2013-06-13 11:00:36,413 [11724] WARN   = ... and a warning 3.
2013-06-13 11:00:36,414 [11724] WARN   = l4n2 cls and a warning -1.
2013-06-13 11:00:36,416 [11724] WARN   = ... and a warning 4.
2013-06-13 11:00:36,418 [11724] WARN   = ... and a warning 5.
2013-06-13 11:00:39,421 [11724] WARN   = ... and a warning 6.
2013-06-13 11:00:39,424 [11724] WARN   = ... and a warning 7.
2013-06-13 11:00:39,426 [11724] INFO   = l4n2 cls and an Info log.
2013-06-13 11:00:39,429 [11724] FATAL  = ... and a fatal aaa.
2013-06-13 11:00:39,431 [11724] FATAL  = l4n2 and a fatal .
2013-06-13 11:00:39,433 [11724] WARN   = ... and a warning 8.
2013-06-13 11:00:39,435 [11724] ERROR  = ... and an error.
2013-06-13 11:00:39,437 [11724] FATAL  = ... and a fatal bbb.
2013-06-13 11:00:39,439 [11724] INFO   = l4n2 cls and an Info log.
2013-06-13 11:00:39,441 [11724] WARN   = l4n2 cls and a warning.
2013-06-13 11:00:39,443 [11724] ERROR  = l4n2 cls and an error.
2013-06-13 11:00:39,444 [11724] FATAL  = l4n2 cls and a fatal .

你知道我的代码有什么问题吗?我已经为此苦苦挣扎了两天了。

【问题讨论】:

    标签: logging dynamic log4net


    【解决方案1】:

    在你的配置文件中配置的 appender 是 RollingLogFileAppender 的唯一实例——你只有两个指向它的对象。因此,当您调用 func() 设置 l4n2 时,您将覆盖 l4n 的设置。为了证明这个理论,你应该可以换行:

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

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

    并且您的所有日志输出都应该进入 consoleapplication1.testcls.log,而不是所有输出当前所在的 consoleapplication1.logtest2.log。

    解决方法是要么以编程方式为每个类生成一个新的 log4net appender(就像他们在this question 的答案中所做的那样),或者只是将两个 RollingLogFileAppender 实例放入你的配置文件中:一个用于你想要记录的每个类为。

    【讨论】:

    • 感谢您的及时回复。在我使用您的方法后以编程方式生成一个新的 log4net appender。日志内容成功生成在相关日志文件中。但是当我在程序运行过程中尝试更改配置文件(记录器级别)时,更改后日志内容无法保存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多