Jetty Logo
Version: 9.2.3.v20140905
Contact the core Jetty developers at www.webtide.com

private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery

Example: Capturing Multiple Logging Frameworks with Slf4j

This page describes how to configure Jetty for capturing multiple logging frameworks logging events into a single logging implementation handled by Slf4j.

When using Slf4j, you can configure a single logging solution for the variety of logging libraries available in common use. With careful setup, you can support all of the following logging APIs at the same time, with a single configuration file to control the output of events produces by these APIs.

Logging APIs that Slf4j supports:

To accomplish this you must make some careful choices, starting with a single underlying logging framework. This decision guides the rest of your choices about JARs to place on the Server classpath.

Table 21.1. Slf4j Logging Grid

Logging APISlf4j Binding JarSlf4j Adapter JarUnderlying Logging Framework
Logback APIn/alogback-classic.jarlogback-core.jar
Log4jlog4j-over-slf4j.jarslf4j-log4j12.jarlog4j.jar
JDK 1.4 Loggingjul-to-slf4j.jarslf4j-jdk14.jar(Core Java Classlib)
Commons Loggingjcl-over-slf4j.jarslf4j-jcl.jarcommons-logging.jar

Logging API

The Logging API that you are either capturing events from and/or using to write out those events (for example, to disk).

Slf4j Binding JAR

Special JARs, created and maintained by the Slf4j project, that pretend to be the various Logging API implementation classes, but instead just route that Logging API's events to Slf4j to handle.

There MAY be multiple Slf4j binding JARs present on the classpath at the same time.

For a single logging API, if you choose to use the Slf4j binding JAR, then you MUST NOT include the SLf4j adapter JAR or underlying logging framework in the classpath as well.

Slf4j Adapter Jar

These JARs are created and maintained by the Slf4j project and route Slf4j logging events to a specific underlying logging framework.

There MUST NOT be multiple Slf4j adapter JARs present on the classpath at the same time.

Logging events that these adapter JARs capture can come from direct use of the Slf4j API or via one of the Slf4j binding JAR implementations.

Underlying Logging Framework

This is the last leg of your configuration, the implementation that processes, filters, and outputs the logging events to the console, logging directory on disk, or whatever else the underlying logging framework supports (like Socket, SMTP, Database, or even SysLog in the case of Logback).

Caution

There MUST NOT be multiple underlying logging frameworks on the classpath. If there are, the Slf4j framework fails to load.

Note

Some third party libraries provide their own implementations of common logging APIs; be careful not to accidentally include an underlying logging framework.

For example, if you are using SpringSource you likely have a com.springsource.org.apache.log4j.jar along with a log4j.jar, which have the same classes in them. In this example, use the com.springsource.org.apache.log4j.jar version and exclude the log4j.jar, as the SpringSource version includes extra metadata suitable for using SpringSource.

The following sections use Logback as the underlying Logging framework. This requires using logback-classic.jar and logback-core.jar, and excluding any other Slf4j adapter JAR or underlying logging framework.

It also requires including the other Slf4j binding JARs in the classpath, along with some special initialization for java.util.logging.

Quick Setup of Multiple Logging capture to Logback using Jetty 9.2.1+

A convenient replacement logging module has been created to bootstrap your ${jetty.base} directory for capturing all Jetty server logging from multiple logging frameworks into a single logging output file managed by logback.

[mybase]$ mkdir modules
[mybase]$ cd modules

[modules]$ curl -O https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/logging.mod
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1293  100  1293    0     0   3693      0 --:--:-- --:--:-- --:--:--  3694
[modules]$ cd ..

[mybase]$ java -jar /opt/jetty-dist/start.jar --add-to-start=logging
INFO: logging         initialised in ${jetty.base}/start.ini (appended)
MKDIR: ${jetty.base}/logs
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar to lib/logging/slf4j-api-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/log4j-over-slf4j/1.6.6/log4j-over-slf4j-1.6.6.jar to lib/logging/log4j-over-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/jul-to-slf4j/1.6.6/jul-to-slf4j-1.6.6.jar to lib/logging/jul-to-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.6.6/jcl-over-slf4j-1.6.6.jar to lib/logging/jcl-over-slf4j-1.6.6.jar
DOWNLOAD: http://central.maven.org/maven2/ch/qos/logback/logback-core/1.0.7/logback-core-1.0.7.jar to lib/logging/logback-core-1.0.7.jar
DOWNLOAD: http://central.maven.org/maven2/ch/qos/logback/logback-classic/1.0.7/logback-classic-1.0.7.jar to lib/logging/logback-classic-1.0.7.jar
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/logback.xml to resources/logback.xml
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/jetty-logging.properties to resources/jetty-logging.properties
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/logging-modules/master/capture-all/jetty-logging.xml to etc/jetty-logging.xml
INFO: resources       initialised transitively
INFO: resources       enabled in     ${jetty.base}/start.ini

[mybase]$ java -jar /opt/jetty-dist/start.jar

That's cool and all, but tell me what that just did.

The replacement logging.mod performs a number of tasks.

  1. mybase is a ${jetty.base} directory

  2. The jetty-distribution is unpacked (and untouched) into /opt/jetty-dist/ and becomes the ${jetty.home} directory for this demonstration.

  3. The curl command downloads the replacement logging.mod and puts it into the ${jetty.base}/modules/ directory for use by mybase only.

  4. The start.jar --add-to-start=logging command performs a number of steps to make the logging module available to the ${jetty.base} configuration.

    1. The --module=logging command is added to the ${jetty.base}/start.ini configuration

    2. Required ${jetty.base} directories are created: ${jetty.base}/logs and ${jetty.base}/resources

    3. Required libraries are downloaded (if not present already):

      • slf4j-api.jar - API jar for Slf4j (used by most of the rest of the jars)

      • log4j-over-slf4j.jar - Slf4j jar that captures all log4j emitted logging events

      • jul-to-slf4j.jar - Slf4j jar that captures all java.util.logging events

      • jcl-over-slf4j.jar - Slf4j jar that captures all commons-logging events

      • logback-classic.jar - the Slf4j adapter jar that routes all of the captured logging events to logback itself.

      • logback-core.jar - the logback implementation jar, that handles all of the filtering and output of the logging events.

      These libraries are put in the ${jetty.base}/lib/logging/ directory.

    4. Required configuration files are downloaded (if not present already): jetty-logging.properties, and logback.xml

      The configuration files are put in the ${jetty.base}/resources/ directory.

    5. Required java.util.logging initialization commands are downloaded (if not present already): jetty-logging.xml

      The xml file is put in the ${jetty.base}/etc/ directory.

  5. At this point you have your mybase configured so that the jetty server itself will log using slf4j, and all other logging events from other Jetty Server components (such as database drivers, security layers, jsp, mail, and other 3rd party server components) are routed to logback for filtering and output.

You can verify the server classpath by using the start.jar --list-config command.

In essence, Jetty is now configured to emit its own logging events to slf4j, and various slf4j bridge jars are acting on behalf of log4j, java.util.logging, and commons-logging, routing all of the logging events to logback (a slf4j adapter) for routing (to console, file, etc...)

See an error or something missing? Contribute to this documentation at Github!(Generated: 2014-10-26T01:00:29-07:00)