log4net针对不同appender的不同消息,在文件中创建重复的日志条目

时间:2014-11-11 00:15:32

标签: c# logging log4net log4net-configuration log4net-appender

我已经为log4net实现了一个自定义appender,我正在记录一个文件并发送邮件。我想为每个案例记录不同的消息字符串。下面的代码在文件中创建了两个日志条目,一个附加了字符串&一个没有附加字符串。它还发送没有附加字符串的电子邮件。

public static void Log(this ILog log, Level level, string message)
{
    var token = string.Format("{0},{1},{2}", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, level, message);
    int count = _tokenTimeThrottler.CheckAllow(token);
    if (count >= 0)
    {
        //only to file logger, with an appended string
        log = LogManager.GetLogger("LogFileAppender");
        log.Logger.Log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, level, count <= 1 ? message : count + " counts of: " + message, null);
    }

    //only to mail
    log = LogManager.GetLogger("MyMailAppender");
    log.Logger.Log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, level, message, null);
    }

但我想在我做的时候不想登录文件。

//only to mail
log = LogManager.GetLogger("MyMailAppender");
log.Logger.Log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, level, message, null);

My Config文件,使用配置文件添加一个appender,另一个appender是dll,因此在运行时添加。

第一个appender:

<log4net>
    <root>
      <level value="INFO" />
      <appender-ref ref="LogFileAppender" />
    </root>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="C:\git\logs\log.log" />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="5" />
      <maximumFileSize value="10MB" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%d [%t] %-5p  %m%n" />
      </layout>
    </appender>
</log4net>

第二个appender(在运行时添加):

Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
      PatternLayout patternLayout = new PatternLayout { ConversionPattern = "%d [%t] %-5p %m%n" };

      MyMailAppender myAppender = new MyMailAppender 
      {
        Name = "MyMailAppender",
        Layout = patternLayout,
        Access = "ghjkgj",
        Threshold = Level.Info,
      };

      myAppender .ActivateOptions();
      hierarchy.Root.AddAppender(myAppender );

      hierarchy.Root.Level = Level.All;
      hierarchy.Configured = true;

3 个答案:

答案 0 :(得分:0)

我不完全清楚你在做什么,因为你的例子实际上并没有调用你的扩展方法,但我认为最简单的解决方案是在扩展方法中添加另一个参数来指定如果您想通过电子邮件发送日志条目:

public static void Log(this ILog log, Level level,
                       string message, bool sendEmail = true)
{ …

 if (sendEmail)
  { 
      //only to mail
      log = LogManager.GetLogger("MyMailAppender");
      log.Logger.Log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, level, message, null);
  }
}

然后,您只需指定何时不希望将其发送:

log = LogManager.GetLogger("MyMailAppender");

// Call extension method, specifying no email should be sent
log.Log(level, message, false);

由于sendEmail的默认值为true,如果您确实希望发送电子邮件,则根本不需要传递参数,这意味着对现有代码没有影响。

答案 1 :(得分:0)

我建议使用两个BufferingFowardAppender基于记录器名称(log4net.Filter.LoggerMatchFilter)的过滤器:

  • 一个转发appender将根据记录器名称过滤邮件记录器的消息:INFO级别的root - &gt;带有MyMailAppender记录器名称过滤器的apowder appender - &gt; mail appender
  • 一个转发appender将过滤标准记录器的消息:INFO级别的root - &gt;使用过滤器进行appender不要让MyMailAppender记录器名称通过 - &gt;其他appender

您不需要在代码配置中使用,这完全可以通过仅配置

来实现

答案 2 :(得分:0)

解决方案是使用两个记录器元素而不是root,因为root适用于所有appender。因此,添加到root的任何附加内容都将被写入,从而创建重复的条目。

    <log4net>
         <logger name="MyMailAppender">
          <level value="INFO" />
        </logger>
        <logger name="LogFileAppender">
          <level value="INFO" />
          <appender-ref ref="LogFileAppender" />
        </logger>
</log4net>

然后在运行时我从dll创建appender并将其添加到MyMailAppender记录器。