Google recently announced the release of a new open-source Java logging framework called Flogger. Acknowledging that "[t]he field of open-source Java logging APIs is already extremely crowded", Google asserts that Flogger offers "many benefits over existing logging APIs". These improvements include reducing the cost of disabled log statements, increasing overall readability, and allowing extensibility.
Flogger, a portmanteau of fluent and logger, argues that one of its main benefits is "[l]ogging at disabled levels is effectively free." Whereas other logging frameworks may generate bytecode for disabled logging statements, Flogger aims to completely avoid it.
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.
Readability is another area that Flogger is making strides to improve. According to Google, Flogger allows for more "self-documenting log statements" through the use of its more expressive fluent API. As an example, consider a typical logging statement which logs an error along with its exception
log.error("The arg, '{}' caused an error", arg, exception)
This same statement can be expressed in Flogger using
logger.atError()
.withCause(exception)
.log("The arg, ‘%s’ caused an error", arg);
In addition to the improvements in readability, Flogger was designed with extensibility in mind and allows for custom extensions. Using Flogger, it’s "possible to locally extend the logging API and add methods in the fluent chain".
At this time, documentation and examples of custom extensions are limited but one such example, given by Google, is creating a UserLogger
that logs on a per-user basis that gets written out separately from the main log.
logger.at(INFO)
.forUserId(id)
.log("Message: %s", param);
Additional information about Flogger can be found on its Github page along with a getting started guide and documentation on best practices.