log4net - 用于仅记录第N条消息的任何过滤器?

Geo*_*uer 8 .net log4net

我有一个不断从设备读取值的组件.目前,它每隔{n}秒更新一次,并将带有值的调试消息记录到ILog实例.

每一秒对我来说太频繁了,我只是不在乎它会占用太多的日志空间.但是,我当然有兴趣从该组件捕获每个第10或第30条消息,这样我就可以得到它正在做的事情的一般要点.

有没有人知道这样做的方式不涉及我自己的ILog实现?

wag*_*ghe 13

这可能为时已晚,无法帮助您,但您可以实施过滤器. http://www.mail-archive.com/log4net-user%40logging.apache.org/msg02517.html展示了如何实现过滤器来限制记录异常的频率(如果异常类型与上一个异常类型相同,如果已经过了少于一些指定的时间).

以下是该链接的实际过滤器源代码:

public class ExceptionThrottleFilter : FilterSkeleton
{
  private DateTime lastException = DateTime.MinValue;
  private Type exceptionType = typeof(Exception);
  private int threshold = 5; // seconds

  public override void ActivateOptions()
  {
    base.ActivateOptions();
  }

  public override FilterDecision Decide(LoggingEvent loggingEvent)
  {
    if (loggingEvent.ExceptionObject != null &&  loggingEvent.ExceptionObject.GetType) == exceptionType)
    {
      if (loggingEvent.TimeStamp.Subtract(lastException).TotalSeconds > threshold)
      {
        lastException = loggingEvent.TimeStamp;
        return FilterDecision.Accept;
      }
      else
      {
        return FilterDecision.Deny;
      }
    }
    else
    {
      return FilterDecision.Neutral;
    }
  }

  public Type ExceptionType
  {
    get { return exceptionType; }
    set { exceptionType = value; }
  }

  public int Threshold
  {
    get { return threshold; }
    set { threshold = value; }
  }
}
Run Code Online (Sandbox Code Playgroud)

它将配置如下:

<filter type="Company.Project.Logging.ExceptionThrottleFilter">
  <threshold value="2" />
  <exceptionType value="System.ApplicationException" />
</filter>
Run Code Online (Sandbox Code Playgroud)

似乎将它修改为"限制"重复的消息是非常简单的.也许是这样的(未经测试):

public class DuplicateMessageThrottleFilter : FilterSkeleton
{
  private string lastMessage;

  public override void ActivateOptions()
  {
    base.ActivateOptions();
  }

  public override FilterDecision Decide(LoggingEvent loggingEvent)
  {
    string newMessage;
    if (loggingEvent.MessageObject != null)
    {
      newMessage = loggingEvent.MessageObject.ToString();
    }

    if (newMessage.Equals(lastMessage))
    {
      return FilterDecision.Deny;
    }

    lastMessage = newMessage;
    return FilterDecision.Accept;
  }
}
Run Code Online (Sandbox Code Playgroud)

将已记录的消息注释重复次数可能会很好,但如何做到这一点对我来说并不明显:

Some message.
Some message.
Some message.
Look, a new message.
Some message.
Some message.
Look, a new message.
Run Code Online (Sandbox Code Playgroud)

可以生成这样的东西:

Some message. (3 times)
Look, a new message.
Some message. (2 times)
Look, a new message.
Run Code Online (Sandbox Code Playgroud)

可能是某种ForwardingAppender或BufferingForwardingAppender.它总是会留下一个信息.消息进来."RepeatedMessageAppender"将保留该消息.下一条消息进来.如果它与上一条消息不同,则将最后一条消息转发给"真正的"Appender(如果"重复计数"> 0,则在转发之前将该号码附加到最后一条消息 - 这是我的部分不确定因为我认为修改传递给Appender的LoggingEvent并不容易.如果它与最后一条消息相同,则递增计数器并且不转发.由于"RepeatedMessageAppender"落后于其中,它可能必须是BufferingForwardingAppender并且它必须实现Flush.

也许你(或其他人)会发现这些信息很有用.