Friday, July 26, 2019

Google Flogger



  • Logging at disabled levels is effectively free. Finally, you can add as many fine-grained log statements to your code as you want, without worry.
  • Flogger also has very high performance for enabled log statements.
  • A fluent API accommodates a variety of present and future features without combinatorial explosion, and without requiring separate logging façades.
  • Less reliance on long parameter lists makes it harder to misuse and yields more self-documenting code.

When possible, log objects, not strings {#structured}
It's good to remember that a logging backend might not necessarily be outputting only plain text files. For a statement such as

logger.atInfo().log("Received message is: %s", proto)
the backend has the opportunity to do more interesting things with the data in its original, structured form.

On the other hand, with either of these calls:

logger.atInfo().log("Received message is: %s", proto.toString())
logger.atInfo().log("Received message is: " + proto);

Don't create a Throwable just to log it {#stack-trace}

There is no need to do this:
logger.atInfo().withCause(new Exception()).log("Message");
You should do this instead:
logger.atInfo().withStackTrace(<SIZE>).log("Message");
where <SIZE> is one of the StackSize enum constants, SMALLMEDIUMLARGE or FULL.

Make the logger the first static field in a class


Fortunately we know whether or not logging is disabled at the point that the level selector was called (and this is always the first thing we do). So if logging is disabled we can chose to return a different implementation of the logging context which simply discards all its arguments for every subsequent method call (a “No-Op” instance). Conveniently this instance is naturally immutable and thread safe, so we can return the same singleton instance every time, which avoids an allocation when logging is disabled.
This means that as well as being a more functional API, using a fluent API means that in the vast majority of cases a disabled log statement can avoid needing to allocate anything.

These improvements include reducing the cost of disabled log statements, increasing overall readability, and allowing extensibility

More specifically, logging frameworks typically utilize varargs to accommodate the unknown number of parameters in a logging method call rather than having hundreds or even thousands of different and unpredictable method signatures. This use of varargs results in additional bytecode, particularly to allocate an Object[] for storing the varargs. While additional bytecode doesn’t typically warrant concern, it becomes particularly important in applications with very fine-grained logging statements or logging statements that occur in loops.
Flogger avoids this cost through the design of its API. The fluent call chain always begins with a selector for a particular log level, for instance atInfo(). This selector returns an implementation to log at that level and in the case of disabled log statements, a singleton, no-op implementation, can be returned.


https://medium.com/@anilkkurmi/flogger-java-logger-a-fluent-logging-api-for-java-developer-6a03b131cd51
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
        logger.atWarning().log("warning");

        logger.atInfo().log("info");

        logger.at(Level.SEVERE)
                .atMostEvery(50, TimeUnit.SECONDS)
                .log("SEVERE", LazyArgs.lazy(() -> doSomeCostly()));

logger.atWarning().withCause(e).log("warning");
logger.atInfo().every(100).log("Info logs %s", arg);

4. It also supports Extensibility
If you wanted to create separate logs per user or per session id. It is super easy to do that with the flogger
long sessionId;
logger.at(INFO).forUserId(sessionId).log("My message: %s", param);
5. Better runtime checking for disabled logging
if (logger.atFine().isEnabled()) {
  Foo foo = doComplexThing();
  logger.atFine().log("stats=%s", foo.toString());
}




Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts