Пользовательский фильтр Log4net не фильтрует

В настоящее время есть фильтр log4net, как показано ниже. Этот фильтр не должен позволять регистрировать одно и то же сообщение через определенный интервал. Тем не менее, сообщения обязательно регистрируются. Источник: Log4net, удалите повторяющиеся сообщения

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>


person Gauravsa    schedule 06.12.2018    source источник


Ответы (1)


Метод Decide для UniqueLogFilter не выполняется, потому что в иерархии фильтров верхний LevelRangeFilter принимает событие, если оно соответствует его условию, вместо того, чтобы передавать его следующему фильтру, UniqueLogFilter.

Чтобы позволить UniqueFilter решать, вы должны установить AcceptOnMatch на False на LevelRangeFilter.
С этой настройкой вы заметите, что UniqueLogFilter выполняется во время отладки.

<acceptOnMatch>False</acceptOnMatch>

Настройка фильтра выглядит следующим образом.

<filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="INFO" />
    <levelMax value="WARN" />
    <acceptOnMatch>False</acceptOnMatch>
</filter>
<filter type="CPVEmailWatcher.UniqueLogFilter">
    <loggerToMatch value="RollingLogFileAppender" />
    <timeWindow value="1800" />
    <!--(30 min interval)-->  
    <lastOnly value="false" />
 </filter>
person pfx    schedule 06.12.2018