Logback

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.

Similarily, with Maven:

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>VERSION</version>
</dependency>

This will provide the logback-classic SLF4J implementation which 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.

Logback Configuration

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

Examples

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

${log.access.output:-access.log}
${log.service.output:-service.log}

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

-Dlog.service.output=myservice.log

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.

Mapped Diagnostic Context Filter

Finatra offers an integration with Logback’s Mapped Diagnostic Context (MDC) for consistent logging of useful information. For example, the hello-world configuration references the contextual key “traceId” which will be logged with every statement sent to the appender. It is the responsibility of the application to populate the MDC with this contextual information. In this case, the “traceId” is added by including either the http TraceIdMDCLoggingFilter or thrift TraceIdMDCLoggingFilter.

In order to use the Mapped Diagnostic Context, an application must first initialize the MDC Finagle adapter provided by Finatra. This initialization is provided by including either the http LoggingMDCFilter or thrift LoggingMDCFilter in your filter chain.

Make sure to place the LoggingMDCFilter before any other filters which will add MDC entries or expect MDC entries to be present.

See Logback’s documentation for more information the MDC functionality.