【问题标题】:Dynamic loading of log4net.Config for separate threads? C#/.NET为单独的线程动态加载 log4net.Config? C#/.NET
【发布时间】:2011-03-01 05:36:23
【问题描述】:

我的应用程序有许多并行的独立线程无限期地运行。我正在使用 log4net 来记录信息。

我想动态检测 log4net 的日志记录配置信息。 (即:其中一个线程正在做一些奇怪的事情,我可以在其中“注入”一个更详细的配置)。 我正在使用 log4net.Config 方法在其中一个线程中动态加载 XML 配置文件。不幸的是,它似乎影响了所有其他线程。

在使用 log4net 时,有没有办法隔离每个线程的配置?

谢谢!

【问题讨论】:

    标签: c# multithreading log4net


    【解决方案1】:

    使用 LogManager.GetLogger("MyApp.Thread1") 为每个将要运行的线程创建一个新的记录器。此方法可以接受一个字符串,因此只需给每个字符串一个不同的名称。然后您应该能够单独使用每个日志级别。

     <!-- Set root logger level to DEBUG and its only appender to A1 -->
    <root>
        <level value="DEBUG" />
        <appender-ref ref="A1" />
    </root>
    
    <!-- Print only messages of level WARN or above in the package Com.Foo -->
    <logger name="MyApp.Thread1">
        <level value="WARN" />
    </logger>
    

    更多信息: http://logging.apache.org/log4net/release/manual/configuration.html

    另外,如果您刚刚开始,请查看Log4View。我没有任何从属关系,只是一个满意的客户。

    【讨论】:

      【解决方案2】:

      我自己才刚刚开始使用 log4net,所以如果这没有用,我深表歉意,但我认为使用 Contexts 功能可以解决这个问题。

      您可以通过结合使用上下文过滤器来获取您的特定线程:

      编辑

      仔细观察这些,似乎 Mdc/Ndc 是遗留功能,所以也许这不是最佳选择。所以,这是另一个想法。

      根据您识别线程的方式(如果您不是从线程池中收集完全黑盒任务),您可以简单地命名您的记录器,并使用过滤器来匹配记录器名称。

      http://logging.apache.org/log4net/release/sdk/log4net.Filter.LoggerMatchFilter.html

      您可以在运行时配置过滤器,只要您以自动重新加载的方式加载配置:Configuration Attributes(特别是Watch = true)。

      您还可以在不记录时使用if(log.IsDebugEnabled) { /* do logging here */ } 之类的块来保持性能。

      【讨论】:

        【解决方案3】:

        “不幸的是,它似乎影响了所有其他线程”是什么意思?

        我正在考虑性能或锁定。

        如果您的线程被锁定(即第一个线程记录但另一个挂起在日志调用中),那么您需要MinimalLocking 选项以用于FileAppender。这样,一旦记录器写入日志文件,它就会将文件句柄释放给其他线程。不幸的是,这会影响性能(但性能仍然取决于内核:如果 Mac 或 Linux 内核,当您使用单声道时,在处理打开/关闭操作时更快或更慢,您会得到不同的结果),因为连续关闭/刷新/打开。

        最终的解决方案是声明不同的 appender不同的 loggers。对于您实例化的每个记录器(之前知道它们!),声明一个专用的FileAppender 以供独占使用,这样线程就不会出现并发问题。

        【讨论】:

        • 我不同意。您可以将多个线程记录到同一个文件,而不会出现并发问题。您无法保证日志条目出现的顺序,但我从来没有遇到过任何问题。 OP 没有锁定任何东西,他只是想要一种方法来控制运行时每个线程的日志输出的详细程度。
        • 我也不同意。如果线程共享相同的记录器实例,则不会发生并发问题(但显然性能可能会受到影响)。但是,如果他们为每个调用一次 GetLog,则会创建多个实例。反正他没提问题,这才是真正的问题!!
        猜你喜欢
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 2011-06-04
        • 1970-01-01
        • 2017-03-05
        • 2012-11-06
        相关资源
        最近更新 更多