每种方法不同的appender

sug*_*982 7 .net c# asp.net logging log4net

刚开始使用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");
  }

}
Run Code Online (Sandbox Code Playgroud)

是否可以在配置中为method1中的log4net.info设置使用一个appender和方法2中的log4net.info来使用另一个appender,即使它们不属于同一类型,例如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>
Run Code Online (Sandbox Code Playgroud)

Pol*_*878 6

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

您可以通过几种不同的方式获取记录器.最值得注意的是,by Type或by string.

能够获取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");
  }
}
Run Code Online (Sandbox Code Playgroud)

这是相同的logger 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>
Run Code Online (Sandbox Code Playgroud)

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


Nic*_*rey 6

同一记录器无法根据当前方法路由到多个appender,至少不能直接路由.但是,您可以使用log4net的过滤器

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

  • 拒绝.删除日志记录事件.不记录该事件,并且不会查询appender的过滤器链中的后续过滤器.
  • 中性.记录事件将传递给该appender的过滤器链中的下一个过滤器.
  • 接受.记录该事件.不会查询过滤器链中的后续过滤器.

然后将过滤器添加到您想要拥有的每个追加器的过滤器链中.这可以在运行中完成,也可以通过log4net.config进行配置.

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

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

如果您需要添加一些上下文信息作为过滤依据.