17

How can I limit the rate of emails a Logback SMTPAppender, so that it would email me at most once every n minutes?

I have setup my logging according to the Logback appender, but I don't quite see how it be configured or subclassed to implement that.

Is there a hidden feature? Did someone develop a subclass to handle this?

djechlin
  • 59,258
  • 35
  • 162
  • 290
notnoop
  • 58,763
  • 21
  • 123
  • 144
  • 1
    Rate-limiting is one of those frustratingly tricky problems to solve. I'd be surprised if logback had a simple solution for this. – skaffman Jan 02 '10 at 22:12
  • @skaffman, can you explain the complexity? I understand this may conceal some failures, in case an critical error occurs slightly after less-critial error. – notnoop Jan 02 '10 at 22:18

7 Answers7

7

Based on the documentation it appears that the way to do this is to write an EventEvaluator (see example 4.14 and 4.15) which looks at the time stamp for each event to only accept an event when "enough time" has passed since the last event was accepted.

You can use System.currentTimeMillis to get a number you can do math on to calculate time differences. http://java.sun.com/javase/6/docs/api/java/lang/System.html#currentTimeMillis%28%29

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
6

As Thorbjørn, it's easy to create an EventEvaluator that limit the rate by which an appender fires a message.

However, I found Logback to support DuplicateMessageFilter, that solves my problem probably in a bitter way: "The DuplicateMessageFilter merits a separate presentation. This filter detects duplicate messages, and beyond a certain number of repetitions, drops repeated messages."

notnoop
  • 58,763
  • 21
  • 123
  • 144
3

Have a look at the new Whisper appender. It does smart suppression. Available via Maven and github here

Statutory disclaimer: I'm the author.

Καrτhικ
  • 3,833
  • 2
  • 29
  • 42
2

To solve same problem I've written custom evaluator. It extends ch.qos.logback.classic.boolex.OnMarkerEvaluator, but you can use any other evaluator as base. If there will many acceptable messages in silence interval evaluator will discard these. For my use case it's ok, but if you need different behavior - just add extra checks to the second if.

public class LimitingOnMarkerEvaluator extends OnMarkerEvaluator {

  private long lastSend = 0, interval = 0;

  @Override
  public boolean evaluate(ILoggingEvent event) throws EvaluationException {
    if (super.evaluate(event)) {
      long now = System.currentTimeMillis();

      if (now - lastSend > interval) {
        lastSend = now;
        return true;
      }
    }

    return false;
  }


  public long getInterval() {
    return interval;
  }

  public void setInterval(long interval) {
    this.interval = interval;
  }
}

Config to send maximum one message every 1000 second (about 17 mins):

<evaluator class="package.LimitingOnMarkerEvaluator">
  <marker>FATAL</marker>
  <interval>1000000</interval>
</evaluator>
MrTux
  • 32,350
  • 30
  • 109
  • 146
valodzka
  • 5,535
  • 4
  • 39
  • 50
2

This tool would do exactly what you want but it's not threadsafe at all: http://code.google.com/p/throttled-smtp-appender/wiki/Usage

I've written a threadsafe version but haven't open sourced it yet.

The reason you would have trouble finding good tools for this is that SMTP isn't a real endpoint. Use a service like loggly, airbrake, or dozens of others, or run your own server using something like logstash.

djechlin
  • 59,258
  • 35
  • 162
  • 290
-1

I suggest filing a jira item requesting this feature. It is likely to be implemented if only asked.

Ceki
  • 26,753
  • 7
  • 62
  • 71
-1

Btw,

Logback v0.9.26 allows now to set the size of SMTPAppender message buffer. Until yesterday it would send the current contens of the buffer which was up to 256 messages which imho was a pain in the neck as I wanted to show only the last one in the email. Thus it's now possible to implement periodically recurring email warnings that carry only one particular error as per my interpretation of this question.

http://logback.qos.ch/manual/appenders.html#cyclicBufferSize

Have fun.

danirod
  • 1,011
  • 3
  • 9
  • 18