Log4net自定义过滤器未过滤

时间:2018-12-06 02:10:51

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

目前有一个log4net过滤器,如下所示。此过滤器不应允许在一定间隔内记录相同的消息。但是,肯定会记录消息。来源:Log4net, eliminate duplicate messages

public class UniqueLogFilter : FilterSkeleton
{
    private string lastMessage = null;
    private List<Tuple<DateTime, string>> lastMessages = new List<Tuple<DateTime, string>>();

    public int timeWindow { get; set; } = 0;

    public bool lastOnly { get; set; } = false;

    public override FilterDecision Decide(LoggingEvent loggingEvent)
    {
        if (lastOnly)
        {
            if (lastMessage == loggingEvent.RenderedMessage)
            {
                return FilterDecision.Deny;
            }

            lastMessage = loggingEvent.RenderedMessage;
            return FilterDecision.Accept;
        }

        if (timeWindow <= 0)
            return FilterDecision.Accept;

        // Removes old messages
        lastMessages.RemoveAll(m => m.Item1 < DateTime.Now.AddSeconds(0 - timeWindow));

        if (!lastMessages.Any(m => m.Item2 == loggingEvent.RenderedMessage))
        {
            lastMessages.Add(new Tuple<DateTime, string>(loggingEvent.TimeStamp, loggingEvent.RenderedMessage));
            return FilterDecision.Accept;
        }

        return FilterDecision.Deny;
    } 

这是App.Config:

<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender,log4net">
  <file value="Logs\\EmailWatcher.log" />
  <appendToFile value="true" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%-5p %d{MM-dd hh:mm:ss} [%thread] %level %logger - %message%newline" />
  </layout>
  <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="INFO" />
    <levelMax value="FATAL" />
  </filter>
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="Logs\\" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%-5p %d{dd-MM-yyyy hh:mm:ss} [%thread] %level %logger - %message%newline" />
  </layout>
  <datePattern value="'EmailWatcher.'dd.MM.yyyy'.log'" />
  <staticLogFileName value="false" />
  <appendToFile value="true" />
  <rollingStyle value="Composite" />
  <maxSizeRollBackups value="10" />
  <maximumFileSize value="5MB" />
  <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="INFO" />
    <levelMax value="WARN" />
  </filter>
  <filter type="CPVEmailWatcher.UniqueLogFilter">
    <loggerToMatch value="RollingLogFileAppender" />
    <timeWindow value="1800" />
     <!--(30 min interval)-->  
    <lastOnly value="false" />
  </filter>
</appender>
<appender name="ErrorLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="Logs\\" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%-5p%d{ yyyy-MM-dd HH:mm:ss} – [%thread] %m method: %method %n stacktrace: %stacktrace{5} %n type: %type %n line: %line %n" />
  </layout>
  <datePattern value="'EmailWatcher.'dd.MM.yyyy'.log'" />
  <staticLogFileName value="false" />
  <appendToFile value="true" />
  <rollingStyle value="Composite" />
  <maxSizeRollBackups value="10" />
  <maximumFileSize value="5MB" />
  <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="ERROR" />
    <levelMax value="FATAL" />
  </filter>
  <filter type="CPVEmailWatcher.UniqueLogFilter">
    <loggerToMatch value="ErrorLogFileAppender" />
    <timeWindow value="1800" />
     <!--(30 min interval)-->  
    <lastOnly value="false" />
  </filter>
</appender>
<root>
  <level value="INFO" />
  <appender-ref ref="RollingLogFileAppender" />
  <appender-ref ref="ErrorLogFileAppender" />
</root>

1 个答案:

答案 0 :(得分:4)

Decide的{​​{1}}方法未执行,因为在过滤器层次结构中,顶部UniqueLogFilter如果符合条件则接受事件,而不是将其传递给下一个事件过滤器,LevelRangeFilter

为了让UniqueLogFilter做出决定,您必须在UniqueFilter上将AcceptOnMatch设置为False
使用此设置,您会注意到LevelRangeFilter在调试时被执行。

UniqueLogFilter

过滤器设置如下所示。

<acceptOnMatch>False</acceptOnMatch>