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

时间:2009-07-30 18:44:27

标签: .net log4net

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

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

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

2 个答案:

答案 0 :(得分: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; }
  }
}

它将配置如下:

<filter type="Company.Project.Logging.ExceptionThrottleFilter">
  <threshold value="2" />
  <exceptionType value="System.ApplicationException" />
</filter>

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

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;
  }
}

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

Some message.
Some message.
Some message.
Look, a new message.
Some message.
Some message.
Look, a new message.

可以生成这样的内容:

Some message. (3 times)
Look, a new message.
Some message. (2 times)
Look, a new message.

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

也许您(或其他人)会发现此信息有用。

答案 1 :(得分:1)

取决于您的日志记录。如果每秒都要记录一些内容,那么也许您应该重新审视您正在记录的内容。

您可以对相似的消息进行散列并在一段时间后打印出来。