log4net - 是否有仅记录第 N 条消息的过滤器?

发布于 2024-07-29 13:51:32 字数 197 浏览 7 评论 0原文

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

每一秒对我来说都太频繁了,我只是不在乎,而且它占用了太多的日志空间。 不过,我当然有兴趣从该组件捕获每 10 条或 30 条消息,这样我就可以了解它正在做什么的一般要点。

有谁知道不涉及我自己的 ILog 实现的任何方法?

I have a component that is constantly reading a values from a device. Currently it updates every {n} seconds and logs a debug message with the value to an instance of ILog.

Every second is too frequent for me, I just don't care and it eats up too much log space. However, I would certainly be interested in capturing every 10th or 30th message from that component so I can get the general gist of what it is doing.

Does anyone know any way of doing this that does not involve me witting my own ILog implementation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

友谊不毕业 2024-08-05 13:51:32

这可能已经太晚了,无法帮助您,但您可以实现一个过滤器。 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。

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

This is probably too late to help you, but you could implement a filter. http://www.mail-archive.com/log4net-user%40logging.apache.org/msg02517.html shows how to implement a filter for limiting how often an exception is logged (if exception type is same as last exception type and if less than some specified amount of time has passed).

Here is the actual filter source code from that link:

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

It would be configured like this:

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

It seems like it would be pretty straightforward to modify it to "throttle" messages that repeat. Maybe something like this (untested):

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

It might be nice to annotate a logged message with how many times it was repeated, but how to do that is not obvious to me:

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

Could generate something like this:

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

Probably some kind of ForwardingAppender or BufferingForwardingAppender. It would always be one message behind. A message comes in. The "RepeatedMessageAppender" would hold that message. The next message comes in. If it is different than last message, forward last message to the "real" Appender (if "repeated count" is > 0, append the number to the last message before forwarding - this is the part that I am not sure about because I think htat it is not easy to modify the LoggingEvent that is passed to the Appender). If it is the same as the last message, increment counter and do not forward. Since the "RepeatedMessageAppender" is one behind, it probably has to be a BufferingForwardingAppender and it must implement Flush.

Maybe you (or someone else) will find this information useful.

开始看清了 2024-08-05 13:51:32

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

您可以散列类似的消息并在一段时间后打印它们。

Depends on what you are logging. If there is something to be logged every second, then perhaps you should revisit what you are logging.

You could hash the similiar messages and print them after some time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文