【问题标题】:Correct way of using log4net (logger naming)log4net的正确使用方式(记录器命名)
【发布时间】:2011-10-28 16:36:06
【问题描述】:

log4net 有两种配置和使用方式。第一个是我可以配置自己的附加程序和关联的记录器:

<!-- language: xml -->

<appender name="myLogAppender" type="log4net.Appender.RollingFileAppender" >
    <file value="Logs\myLog.log" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %level - %message%n" />
    </layout>
</appender>

<logger name="myLog">
    <level value="All"></level>
    <appender-ref ref="myLogAppender" />
</logger>

然后当我想在日志中写一些东西时,我可以执行以下操作:

ILog log = LogManager.GetLogger("myLog");
log.Info("message");

另一种使用方法是将root配置为我想要的详细信息:

<!-- language: xml -->

<root>
    <level value="Error" />
    <appender-ref ref="myLogAppender" />
</root>

在这种情况下,我可以记录这样的消息:

ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");

第二种方法的好处是您可以即时启用或禁用某些消息。但问题是我在 EPiServer CMS 中开发,它有自己的使用 log4net 的日志记录系统,如果我在根级别启用信息日志记录,则会写入大量系统日志。

你如何使用 log4net?系统的每个部分都写在自己的记录器中,或者一切都写在默认记录器中,配置决定下一步做什么?

【问题讨论】:

    标签: c# .net logging log4net episerver


    【解决方案1】:

    关于如何在代码中记录消息,我会选择第二种方法:

    ILog log = LogManager.GetLogger(typeof(Bar));
    log.Info("message");
    

    发送到上述日志的消息将使用完全限定类型Bar“命名”,例如

    MyNamespace.Foo.Bar [INFO] message
    

    这种方法的优点是它是组织日志的事实标准,它还允许您按命名空间过滤日志消息。例如,您可以指定要记录 INFO 级别的消息,但将 Bar 的日志记录级别提高到 DEBUG:

    <log4net>
        <!-- appenders go here -->
        <root>
            <level value="INFO" />
            <appender-ref ref="myLogAppender" />
        </root>
    
        <logger name="MyNamespace.Foo.Bar">
            <level value="DEBUG" />
        </logger>
    </log4net>
    

    通过名称过滤日志的能力是 log4net 的一项强大功能,如果您只是将所有消息记录到 "myLog",您将失去很多这种能力!

    关于 EPiServer CMS,您应该能够使用上述方法为 CMS 和您自己的代码指定不同的日志记录级别。

    为了进一步阅读,这是我写的关于日志记录的代码项目文章:

    【讨论】:

    • 您甚至可以通过使用 PatternLayout logging.apache.org/log4net/release/sdk/… 从日志中排除类名称空间的部分以减少日志中的噪音@ "例如,对于记录器名称 "abc",模式 %logger{2} 将输出 "公元前“。”
    • 私有静态只读 ILog 日志 = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    • 为什么第二种方法比第一种更好?!类名是静态的,如果你改变它,你也必须更新记录器中的名称,为了获取类名而引发反射调用有什么意义吗?
    • @CasperLeonNielsen 你能解释一下这与this.GetType()有什么不同吗?
    • @ErikE this.GetType() 在定义静态属性、在静态类中或在构造函数之外时不可用。
    【解决方案2】:

    我的答案可能会迟到,但我认为它可以帮助新手。除非进行如下更改,否则您不会看到执行的日志。

    2 实施 Log4net 时必须更改文件。


    1. 在项目中添加log4net.dll的引用。
    2. app.config
    3. 文件,您将在其中实现日志。

    在 [app.config] 内:

    首先,在“configSections”下,您需要添加以下代码;

    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    

    然后,在“配置”块下,您需要编写下面的一段代码。(这段代码是根据我的需要定制的,但它就像魅力一样。)

    <log4net debug="true">
        <logger name="log">
          <level value="All"></level>
          <appender-ref ref="RollingLogFileAppender" />
        </logger>
    
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <file value="log.txt" />
          <appendToFile value="true" />
          <rollingStyle value="Composite" />
          <maxSizeRollBackups value="1" />
          <maximumFileSize value="1MB" />
          <staticLogFileName value="true" />
    
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date %C.%M [%line] %-5level - %message %newline %exception %newline" />
          </layout>
        </appender>
    </log4net>
    

    内部调用类

    在你要使用这个 log4net 的类中,你需要在下面声明一段代码。

     ILog log = LogManager.GetLogger("log");
    

    现在,您可以在同一个班级的任何地方进行通话记录。以下是您在执行操作时可以调用的方法之一。

    log.Error("message");
    

    【讨论】:

    • 您不需要将ILog 设为实例成员,对吧?我已经更详细地问了同样的问题here,但也许我可以得到你的意见?
    【解决方案3】:

    我没有命名我的调用类,而是开始使用以下内容:

    private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    

    这样,我可以在每个使用 log4net 的类中使用同一行代码,而不必记住在复制和粘贴时更改代码。 或者,我可以创建一个日志类,并让其他所有类都继承自我的日志类。

    【讨论】:

      【解决方案4】:

      第二种方法的缺点是带有创建记录器的大型存储库。如果定义了 root 而未定义类记录器,则此记录器执行相同的操作。生产系统上的标准方案是使用少数专用于类组的记录器。对不起我的英语不好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-31
        相关资源
        最近更新 更多