//
//  ========================================================================
//  Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//  ========================================================================
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

[[example-logging-logback-centralized]]
=== Centralized Logging using Logback

The term _Centralized Logging_ refers to a forced logging configuration for the Jetty Server and all web applications that are deployed on the server.
It routes all logging events from the web applications to a single configuration on the Server side.

The example below shows how to accomplish this with Jetty and Slf4j, using `Logback` to manage the final writing of logs to disk.

____
[IMPORTANT]
This mechanism forces all webapps to use the server's configuration for logging, something that isn't 100% appropriate for all webapps.
An example would be having Jenkins-CI deployed as an webapp, if you force its logging configuration to the server side, you lose the ability on http://jenkins-ci.org/[Jenkins-CI] to see the logs from the various builds (as now those logs are actually going to the main server log).
____

This configuration is essentially the multiple logger configuration with added configuration to the deployers to force a `WebAppClassLoader` change to use the server classpath over the webapps classpath for the logger specific classes.

The technique used by this configuration is to provide an link:{JDURL}org/eclipse/jetty/deploy/AppLifeCycle.Binding.html[AppLifeCycle.Binding] against the link:{JDURL}/org/eclipse/jetty/deploy/AppLifeCycle.html[`"deploying"`node] that modifies the
link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html#getSystemClasspathPattern()[WebAppContext.getSystemClasspathPattern().add(String)] for the common logging classes.
See https://github.com/jetty-project/jetty-webapp-logging/blob/master/src/main/java/org/eclipse/jetty/webapp/logging/CentralizedWebAppLoggingBinding.java[org.eclipse.jetty.logging.CentralizedWebAppLoggingBinding] for actual implementation.

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.

[source, screen, subs="{sub-order}"]
....
[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  1416  100  1416    0     0   4241      0 --:--:-- --:--:-- --:--:--  4252

[master]$ curl -O https://raw.githubusercontent.com/jetty-project/logging-modules/master/centralized/webapp-logging.mod
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   660  100   660    0     0   2032      0 --:--:-- --:--:-- --:--:--  2037
[modules]$ cd ..

[mybase]$ java -jar /opt/jetty-dist/start.jar --add-to-start=logging,webapp-logging
INFO: logging         initialised in ${jetty.base}/start.ini (appended)
MKDIR: ${jetty.base}/logs
DOWNLOAD: https://repo1.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: https://repo1.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: https://repo1.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: https://repo1.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: https://repo1.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: https://repo1.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
INFO: webapp-logging  initialised in ${jetty.base}/start.ini (appended)
DOWNLOAD: https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-webapp-logging/9.0.0/jetty-webapp-logging-9.0.0.jar to lib/webapp-logging/jetty-webapp-logging-9.0.0.jar
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/jetty-webapp-logging/master/src/main/config/etc/jetty-webapp-logging.xml to etc/jetty-webapp-logging.xml
DOWNLOAD: https://raw.githubusercontent.com/jetty-project/jetty-webapp-logging/master/src/main/config/etc/jetty-mdc-handler.xml to etc/jetty-mdc-handler.xml
INFO: deploy          initialised transitively
INFO: deploy          enabled in     ${jetty.base}/start.ini
INFO: logging         initialised transitively
INFO: resources       initialised transitively
INFO: resources       enabled in     ${jetty.base}/start.ini

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

The replacement `logging.mod` performs a number of tasks.

.  `mybase` is a `${jetty.base}` directory.
.  The jetty-distribution is unpacked (and untouched) into `/opt/jetty-dist/` and becomes the `${jetty.home}` directory for this demonstration.
.  The `curl` command downloads the replacement `logging.mod` and puts it into the `${jetty.base}/modules/` directory for use by mybase only.
.  The `start.jar --add-to-start=logging,webapp-logging` command performs a number of steps to make the logging module available to the `${jetty.base}` configuration.
..  Several entries are added to the `${jetty.base}/start.ini` configuration.
*  `--module=logging` is added to enable the logging module.
*  `--module=webapp-logging` is added to enable the webapp-logging module.
..  Required `${jetty.base}` directories are created: `${jetty.base}/logs` and `${jetty.base}/resources`.
..  Required logging libraries are downloaded (if not present already) to the `${jetty.base}/lib/logging/` directory:
* `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.
..  Required webapp-logging library is downloaded (if not present already) to the `${jetty.base}/lib/webapp-logging/` directory:
* `jetty-webapp-logging.jar` - the Jetty side deployment manger app-lifecycle bindings for modifying the `WebAppClassloaders` of deployed webapps.
..  Required configuration files are downloaded (if not present already) to the `${jetty.base}/resources/` directory: `jetty-logging.properties`, and `logback.xml`.
..  Required initialization commands are downloaded (if not present already) to the `${jetty.base}/etc/` directory: `jetty-logging.xml`, `jetty-webapp-logging.xml`, and `jetty-mdc-handler.xml`.

At this point the Jetty `mybase` is 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.

All webapps deployed via the `DeploymentManager` have their `WebAppClassLoader` modified to use server side classes and configuration for all logging implementations.

The server classpath can be verified 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...).
