Log4j Accelerator.

Setup

TL;DR

A significant amount of logging code is "wasted" at runtime. Some folks turn to alternative frameworks to make these statements cheaper. Log4j Accelerator lets you use the industry-leading, state-of-the-art logging framework Log4j 2, while drastically reducing the cost of these "wasted" statements, all without significant sacrifices in functionality.

Details

Logging is a critical part of application development. Log statements fall into two categories: active and inactive. Active statements are those that provide value at runtime. Typically, these are INFO, WARN, and ERROR, but they include anything that devs want to see in the logs. Active statements add business value, and so development teams are happy to pay the performance cost of them. Inactive statements are those that are in the code, but do not result in data being appended to logs. It is common for developers to add TRACE and DEBUG logging to their code to assist in diagnosing. However, these statements are typically inactive, due to the toll they take on throughput, the increased log size, and the reduced signal-to-noise ratio in log files. These inactive statements cost real money, but provide no business value. Log4j Accelerator reduces the cost of inactive statements to tolerable levels.

Observation shows that approximately 4 percent of code is dedicated to logging. Consequently, even moderately sized applications will have thousands of logging statements embedded within their code. Given their number, it becomes imperative to manage these log statements without the need to modify them manually.
Log4j 2 Manual

Advanced logging frameworks like Log4j have a rich configuration and filter mechanism that allows developers to specify, at runtime, which messages should or shouldn't be logged. However, the dynamic nature of this configuration makes it difficult for the JVM to optimize. As a result, developers still pay a high runtime cost for inactive log statements. Log4j Accelerator works by switching the dynamic configuration to static configuration, thereby enabling the JVM to optimize inactive log statements to previously un-achievable levels.

Implications

In switching configuration from dynamic to static, a few features are sacrificed:

  1. Context-wide Filters will no longer work
  2. Changing log levels after startup may not work

In practice, most applications don't use these features. For example, microservices are more likely to be restarted with a new default log level than to have it dynamically changed at runtime. Nevertheless, there are mitigations for these feature reductions.

Context-wide Filters work by analyzing every log event and matching it against a set of criteria. It is impossible to make this evaluation static. However, it is often reasonable to push Context-wide Filters down to be Logger, Appender, or Appender Reference Filters.

Log levels are assigned at multiple points in Log4j. They can be attached to a Logger, an Appender, or an Appender Reference. With Log4j Accelerator, Logger levels cannot be changed after startup, except by skipping many of the possible optimizations. Instead, it is best to set the Logger level at startup, and change Appender or Appender Reference levels dynamically if needed.