Fluent API

Next to the traditional info(), error(), etc. Logger methods, Log4j API also provides a fluent interface for logging.

Rationale

Developers use Log4j traditionally with logging statements like:

LOGGER.error("Unable to process request due to {}", errorCode, exception);

This style has certain drawbacks:

  • It is confusing whether the last argument, exception, is a parameter of the message to be formatted, or is separately attached to the log event.

  • One must know in which order error() arguments should be passed to specify, say, a marker.

The fluent interface (also referred to as the fluent API) has been added to Log4j API to increase code legibility and avoid ambiguities. For instance, the above error() call can be expressed using the fluent API as follows:

LOGGER
    .atError() (1)
    .withThrowable(exception) (2)
    .log("Unable to process request due to {}", errorCode); (3)
1 The log level is set to ERROR
2 The associated exception is attached
3 The log message is formatted with the errorCode parameter

With this syntax, it is clear that the exception is part of the log event and errorCode is a parameter of the message.

Usage

The fluent API entry point is LogBuilder, which can be obtained by using one of the following Logger methods:

  • atTrace()

  • atDebug()

  • atInfo()

  • atWarn()

  • atError()

  • atFatal()

  • always()

  • atLevel(Level)

LogBuilder allows attaching a marker, a Throwable, and a location to the log event by means of following methods:

  • withMarker()

  • withThrowable()

  • withLocation()

After that, developers can call the log() method to finalize and send the log event.

In the following example, we log a parameterized message at INFO level, and attach a marker and an exception to the log event:

LOGGER
    .atInfo() (1)
    .withMarker(marker) (2)
    .withThrowable(exception) (3)
    .log("Unable to process request due to {}", errorCode); (4)
1 The log level is set to INFO
2 marker is attached to the log event
3 exception is attached to the log event
4 A message with errorCode parameter is provided and the statement is finalized

Location information

The fluent API allows users to instruct the location information to be eagerly populated in the log event using the withLocation() method:

LOGGER
    .atInfo()
    .withLocation() (1)
    .log("Login for user with ID `{}` failed", userId);
1 Instructing to eagerly populate the location information

Capturing location information using withLocation() is orders of magnitude more efficient compared to letting the Logger to figure it out indirectly.

You are strongly advised to use withLocation() if you are certain that the populated location information will be used. Otherwise – that is, if the log event might either get dropped due to some filtering or its location information not get used – it will only slow things down.