We highly recommend using Logback as an SLF4J binding (logging implementation).

From the Logback documentation

Logback is intended as a successor to the popular log4j project, picking up where log4j leaves off.

Logback’s architecture is sufficiently generic so as to apply under different circumstances. At present time, logback is divided into three modules, logback-core, logback-classic and logback-access.

See Logback’s documentation on reasons to switch from Log4j.

If you choose to use Logback, just include a jar dependency on ch.qos.logback:logback-classic.

E.g., with sbt:

"ch.qos.logback" % "logback-classic" % VERSION

Where, VERSION represents the version of Logback you want to use.

Similarly, with Maven:


This will provide the logback-classic SLF4J implementation. And when used in addition to the logging bridges provided transitively through the finatra/inject-slf4j module will configure your SLF4J logging implementation and correctly bridge all other legacy APIs.


To configure dynamic changing log levels with TwitterServer, be sure to also include a dependency on the TwitterServer Logback library.

With sbt:

"com.twitter" % "twitter-server-logback-classic" % VERSION

See the TwitterServer documentation for more information on configuration for dynamically changing log levels.

Logback Configuration

See the Logback documentation on configuration for detailed information on configuring Logback logging.


See the logback.xml configuration file in the hello-world example project for example Logback configurations.

The example logback.xml configuration file makes use of Logback’s variable substitution


for configuring the <file/> output of the appenders. A variable’s value is specified at runtime as a Java system property, e.g.,


If a value is not provided the inlined default will be used, i.e., what is on the other side of the :-, e.g., access.log or service.log.

More information about Logback’s variable substitution may be found here.

Rerouting java.util.logging

Additional configuration is necessary to reroute the java.util.logging system. The reason is that the jul-to-slf4j bridge cannot replace classes in the java.util.logging package to do the redirection statically as it does for the other bridge implementations. Instead, it has to register a handler on the root logger and listen for logging statements like any other handler. It will then redirect those logging statements appropriately. This redirection is accomplished via SLF4J’s SLF4JBridgeHandler [documentation]. finatra/inject-modules provides a module for initializing this bridge handler via the LoggerModule. This module is added by the framework to Http and Thrift servers by default.