【问题标题】:Different appender per method每个方法不同的附加程序
【发布时间】:2011-09-16 18:03:06
【问题描述】:

刚开始使用 log4net 并试图了解配置和记录器层次结构。这个层次结构是基于命名空间还是类和方法/函数层次结构?

假设我有以下类结构...

public class MyClass
{
  private static readonly ILog log = LogManager.GetLogger(typeof(MyClass));

  public void Method1()
  {
    log4net.info("message");
  }

  public void Method2()
  {
    log4net.info("message");
  }

}

是否可以在配置中设置方法 1 中的 log4net.info 使用一个附加程序,而方法 2 中的 log4net.info 使用另一个附加程序,即使它们属于同一类型,例如SMTPAppender。如果是这样,配置的外观如何。这是我第一次尝试。

<appender name="SMTP1" type="log4net.Appender.SMTPAppender">
</appender>
<appender name="SMTP2" type="log4net.Appender.SMTPAppender">
</appender>


<logger name="MyClass.Method1">
    <level value="INFO" />
    <appender-ref ref="SMTP1" />
</logger>
<logger name="MyClass.Method2">
    <level value="INFO" />
    <appender-ref ref="SMTP2" />
</logger>

【问题讨论】:

    标签: c# .net asp.net logging log4net


    【解决方案1】:

    层次结构基于“名称”。这是什么意思?
    好吧,您可以在 logger xml 中指定一个命名空间(例如 Foo.Bar),然后使用采用 TypeGetLogger 方法为该命名空间中的类获取一个记录器。 Foo.Bar 下的任何“子”命名空间都将继承 Foo.Bar 的记录器配置。
    或者,您可以使用GetLogger 方法获取基于任何旧字符串的记录器,该方法采用string

    您可以通过几种不同的方式获取记录器。最值得注意的是,Typestring

    能够通过string 获取,你真的可以为你的记录器命名任何东西并使用任何东西来获取它们。您目前所拥有的将无法使用,因为log4net 将根据类获取记录器...所以您将在两种方法中使用相同的记录器。

    您必须创建两个记录器:

    public class MyClass
    {
      private static readonly ILog log = LogManager.GetLogger(typeof(MyClass).Name + "." + "Method1");
      private static readonly ILog log2 = LogManager.GetLogger(typeof(MyClass).Name + "." + "Method2");
    
      public void Method1()
      {
        log.info("message");
      }
    
      public void Method2()
      {
        log2.info("message");
      }
    }
    

    这是相同的记录器 xml 文件:

    <logger name="MyClass.Method1">
        <level value="INFO" />
        <appender-ref ref="SMTP1" />
    </logger>
    <logger name="MyClass.Method2">
        <level value="INFO" />
        <appender-ref ref="SMTP2" />
    </logger>
    

    我对 .Net 不太熟悉,所以也许有人可以找到更好/更强大的方法来使用一些忍者反射来获取每种方法的记录器,但这是我能做的最好的。

    【讨论】:

      【解决方案2】:

      同一个 logger 不能基于当前方法路由到多个 appender,至少不能直接路由。但是,您可以做的是使用 log4net 的过滤器

      做你想做的事。 log4net 框架使用您需要的location information(例如方法名称)填充每个 LoggingEvent,以进行您想要的过滤。不过,您可能需要编写一个自定义的IFilter 来过滤它。 IFilter 是一个非常简单的实现接口:1 个方法/1 个属性。您的过滤器的 Decide() 方法对传递给它的每个日志事件做出 3 个决策中的 1 个:

      • 拒绝。删除日志记录事件。该事件不会被记录,并且不会查询附加程序的过滤器链中的后续过滤器。
      • 中性。日志记录事件将传递给该附加程序的过滤器链中的下一个过滤器。
      • 接受。事件被记录。没有查询过滤器链中的后续过滤器。

      然后将您的过滤器添加到您想要拥有的每个附加程序的过滤器链中。这可以即时完成,也可以通过 log4net.config 进行配置。

      不过,您应该知道,您获得的位置信息的质量取决于它是 Debug 还是 Release 版本……以及我相信它是否有可用的调试符号。

      您可能还想查看 log4net 的各种上下文(和上下文堆栈)

      如果您需要添加一些上下文信息作为过滤的基础。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-04
        • 1970-01-01
        • 1970-01-01
        • 2016-11-05
        • 1970-01-01
        相关资源
        最近更新 更多