| //// |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| https://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| //// |
| = Logging Separation |
| Ralph Goers <rgoers@apache.org> |
| |
| There are many well known use cases where applications may share an |
| environment with other applications and each has a need to have its own, |
| separate logging environment. This purpose of this section is to discuss |
| some of these cases and ways to accomplish this. |
| |
| [#UseCases] |
| == Use Cases |
| |
| This section describes some of the use cases where Log4j could be used |
| and what its desired behavior might be. |
| |
| === Standalone Application |
| |
| Standalone applications are usually relatively simple. They typically |
| have one bundled executable that requires only a single logging |
| configuration. |
| |
| === Web Applications |
| |
| A typical web application will be packaged as a WAR file and will |
| include all of its dependencies in WEB-INF/lib and will have its |
| configuration file located in the class path or in a location configured |
| in the web.xml. Be sure to follow the link:webapp.html[instructions to |
| initialize Log4j 2 in a web application]. |
| |
| === Java EE Applications |
| |
| A Java EE application will consist of one or more WAR files and possible |
| some EJBs, typically all packaged in an EAR file. Usually, it is |
| desirable to have a single configuration that applies to all the |
| components in the EAR. The logging classes will generally be placed in a |
| location shared across all the components and the configuration needs to |
| also be shareable. Be sure to follow the link:webapp.html[instructions |
| to initialize Log4j 2 in a web application]. |
| |
| === "Shared" Web Applications and REST Service Containers |
| |
| In this scenario there are multiple WAR files deployed into a single |
| container. Each of the applications should use the same logging |
| configuration and share the same logging implementation across each of |
| the web applications. When writing to files and streams each of the |
| applications should share them to avoid the issues that can occur when |
| multiple components try to write to the same file(s) through different |
| File objects, channels, etc. |
| |
| === OSGi Applications |
| |
| An OSGi container physically separates each JAR into its own |
| ClassLoader, thus enforcing modularity of JARs as well as providing |
| standardized ways for JARs to share code based on version numbers. |
| Suffice to say, the OSGi framework is beyond the scope of this manual. |
| There are some differences when using Log4j in an OSGi container. By |
| default, each JAR bundle is scanned for its own Log4j configuration |
| file. Similar to the web application paradigm, every bundle has its own |
| LoggerContext. As this may be undesirable when a global Log4j |
| configuration is wanted, then the |
| link:extending.html#ContextSelector[ContextSelector] should be |
| overridden with `BasicContextSelector` or `JndiContextSelector`. |
| |
| [#Approaches] |
| == Approaches |
| |
| === The Simple Approach |
| |
| The simplest approach for separating logging within applications is to |
| package each application with its own copy of Log4j and to use the |
| BasicContextSelector. While this works for standalone applications and |
| may work for web applications and possibly Java EE applications, it does |
| not work at all in the last case. However, when this approach does work |
| it should be used as it is ultimately the simplest and most |
| straightforward way of implementing logging. |
| |
| === Using Context Selectors |
| |
| There are a few patterns for achieving the desired state of logging |
| separation using ContextSelectors: |
| |
| 1. Place the logging jars in the container's classpath and set the |
| system property `log4j2.contextSelector` to |
| `org.apache.logging.log4j.core.selector.BasicContextSelector`. This will |
| create a single LoggerContext using a single configuration that will be |
| shared across all applications. |
| 2. Place the logging jars in the container's classpath and use the |
| default ClassLoaderContextSelector. Follow the |
| link:webapp.html[instructions to initialize Log4j 2 in a web |
| application]. Each application can be configured to share the same |
| configuration used at the container or can be individually configured. |
| If status logging is set to debug in the configuration there will be |
| output from when logging is initialized in the container and then again |
| in each web application. |
| 3. Follow the link:webapp.html[instructions to initialize Log4j 2 in a |
| web application] and set the system property or servlet context |
| parameter `log4j2.contextSelector` to |
| org.apache.logging.log4j.core.selector.JndiContextSelector. This will |
| cause the container to use JNDI to locate each web application's |
| `LoggerContext`. Be sure to set the `isLog4jContextSelectorNamed` |
| context parameter to true and also set the `log4jContextName` and |
| `log4jConfiguration` context parameters. |
| |
| The exact method for setting system properties depends on the container. |
| For Tomcat, edit `$CATALINA_HOME/conf/catalina.properties`. Consult the |
| documentation for other web containers. |