Coder Social home page Coder Social logo

surjansr / rate-limited-logger Goto Github PK

View Code? Open in Web Editor NEW

This project forked from swrve/rate-limited-logger

0.0 0.0 0.0 380 KB

an SLF4J-compatible, simple, fluent API for rate-limited logging in Java

Home Page: https://github.com/Swrve/rate-limited-logger/blob/master/README.md

License: Apache License 2.0

Java 98.58% Shell 1.42%

rate-limited-logger's Introduction

RateLimitedLogger CircleCI badge

An SLF4J-compatible, simple, fluent API for rate-limited logging in Java.

Logging is vital for production-ready, operable code; however, in certain situations, it can be dangerous. It is easy to wipe out throughput of a performance-critical backend component by several orders of magnitude with disk I/O in a performance hotspot, caused by a misplaced log call, or input data changing to something slightly unexpected.

With RateLimitedLogger, however, this risk is avoided. A RateLimitedLog object tracks the rate of log message emission, imposes an internal rate limit, and will efficiently suppress logging if this is exceeded. When a log is suppressed, at the end of the limit period, another log message is output indicating how many log lines were suppressed.

This style of rate limiting is the same as the one used by UNIX syslog; this means it should be comprehensible, easy to predict, and familiar to many users, unlike more complex adaptive rate limits.

RateLimitedLogger wraps your existing SLF4J loggers, so should be easy to plug into existing Java code.

Binaries:

This module is available in the Maven Central repository at http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22rate-limited-logger%22

WARNING: version 2.0.0 drops support for Java 6 and 7, and is Java 8-only. It also requires (minor) code changes to use the java.time classes instead of Joda-Time. If you still need support for Java 6 or 7, use version 1.1.0 or earlier.

Maven:

  <dependency>
      <groupId>com.swrve</groupId>
      <artifactId>rate-limited-logger</artifactId>
      <version>2.0.2</version>
  </dependency>

Gradle:

  compile group: 'com.swrve', name: 'rate-limited-logger', version: '2.0.2'

Sample code:

  private static final Logger logger = LoggerFactory.getLogger(getClass());

  private static final RateLimitedLog rateLimitedLog = RateLimitedLog
            .withRateLimit(logger)
            .maxRate(5).every(Duration.ofSeconds(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.

More documentation

Javadoc can be found at http://swrve.github.io/rate-limited-logger/javadoc/2.0.2/

Sample output

  22:16:03.584 [main] INFO Demo - message 1
  22:16:03.604 [main] INFO Demo - message 2
  22:16:03.634 [main] INFO Demo - message 3
  22:16:04.986 [RateLimitedLogRegistry-0] INFO Demo - (suppressed 39 logs similar to 'message {}' in PT1.0S)

Interpolation

Each log message has its own internal rate-limiting AtomicLong counter. In other words, if you have 2 log messages, you can safely reuse the same RateLimitedLog object to log both, and a high rate of one will not cause 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 or if the log-level threshold isn't reached.)

A RateLimitedLog object has a limited capacity for the number of log messages it'll hold; if over 1000 different strings are used as the message template for a single RateLimitedLog object, it is assumed that the caller is accidentally using an already-interpolated string containing variable data in place of the template, and the current set of logs will be flushed in order to avoid an OutOfMemory condition. This has a performance impact, but at least it won't lose data!

Performance

In tests using JMH with Java 7 on a 2012 Macbook Pro, using RateLimitedLog with logger.info("string") ran in, on average, 73 nanoseconds per op, with a P99.99 of 2000 ns/op and a P99.999 of 12000 ns/op, once the rate limit was exceeded.

Where performance is critical, note that you can obtain a reference to the LogWithPatternAndLevel object for an individual log template and level, which will then avoid a ConcurrentHashMap and AtomicReferenceArray lookup:

  ref = logger.get("string", Level.INFO)
  ref.log()

Using this approach, the average post-ratelimit time dropped to 56 nanoseconds per op, with a P99.99 of 1000 ns/op and a P99.999 of 8992 ns/op.

More details: https://github.com/Swrve/rate-limited-logger/tree/master/jmh-tests

Thread-Safety

The RateLimitedLogger library is thread-safe. Under heavy load, though, it is possible for more log messages to be exceeded than the limit specifies, for a short period after the limit is exceeded (typically on the order of a duration of a few milliseconds).

Dependencies

All versions are minimum versions -- later versions should also work fine.

  • Java 8
  • SLF4J API 1.7.7
  • Findbugs Annotations 1.0.0
  • Findbugs JSR-305 Annotations 2.0.2

version 1.1.0 of RateLimitedLogger supports Java 7, but requires Guava 15.0 and Joda-Time 2.3 in addition to the above.

License

(c) Copyright 2014-2018 Swrve Mobile Inc or its licensors. Distributed under version 2.0 of the Apache License, see "LICENSE".

Building

Build all JARs, test, measure coverage:

  ./gradlew all

Credits

rate-limited-logger's People

Contributors

comtef avatar jmason avatar marcomorain avatar nicklaswallgren avatar olegiakovlev avatar pine avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.