@ThreadSafe
public class RateLimitedLog
extends java.lang.Object
private static final Logger logger = LoggerFactory.getLogger(getClass()); private static final RateLimitedLog rateLimitedLog = RateLimitedLog.withRateLimit(logger) .maxRate(5).every(Duration.standardSeconds(10)) .build();This will wrap an existing SLF4J Logger object, allowing a max of 5 messages to be output every 10 seconds, suppressing any more than that. When a log is suppressed, at the end of the 10-second period, another log message is output indicating how many logs were hidden. This style of rate limiting is the same as the one used by UNIX syslog, so should be comprehensible, easy to predict, and familiar to many users, unlike more complex adaptive rate limits. Each log message has its own internal rate limiting counter. In other words, if you have 2 log messages, you can safely reuse the same RateLimitedLog object to log both, and the rate of one will not caused the other to be suppressed as a side effect. However, this means that if you wish to include dynamic, variable data in the log output, you will need to use SLF4J-style templates, instead of ("foo " + bar + " baz") string interpolation. For example:
rateLimitedLog.info("Just saw an event of type {}: {}", event.getType(), event);"{}" will implicitly invoke an object's toString() method, so toString() does not need to be called explicitly when logging. (This has obvious performance benefits, in that those toString() methods will not be called at all once the rate limits have been exceeded.) Where performance is critical, note that you can obtain a reference to the RateLimitedLogWithPattern object for an individual log template, which will avoid a ConcurrentHashMap lookup. The RateLimitedLog objects are thread-safe.
Modifier and Type | Method and Description |
---|---|
void |
debug(java.lang.String template,
java.lang.Object... args) |
void |
error(java.lang.String template,
java.lang.Object... args) |
RateLimitedLogWithPattern |
get(java.lang.String message) |
void |
info(java.lang.String template,
java.lang.Object... args) |
void |
trace(java.lang.String template,
java.lang.Object... args)
logging APIs.
|
void |
warn(java.lang.String template,
java.lang.Object... args) |
static RateLimitedLogBuilder.MissingRateAndPeriod |
withRateLimit(org.slf4j.Logger logger)
Start building a new RateLimitedLog, wrapping the SLF4J logger @param logger.
|
public static RateLimitedLogBuilder.MissingRateAndPeriod withRateLimit(org.slf4j.Logger logger)
public void trace(java.lang.String template, java.lang.Object... args)
rateLimitedLog.info("Just saw an event of type {}: {}", event.getType(), event);
template
- the format stringargs
- the list of arguments matching the templatepublic void debug(java.lang.String template, java.lang.Object... args)
public void info(java.lang.String template, java.lang.Object... args)
public void warn(java.lang.String template, java.lang.Object... args)
public void error(java.lang.String template, java.lang.Object... args)
public RateLimitedLogWithPattern get(java.lang.String message)
java.lang.IllegalStateException
- if we exceed the limit on number of RateLimitedLogWithPattern objects
in any one period; if this happens, it's probable that an already-interpolated string is
accidentally being used as a log pattern.