Hi Bruno,

On 10.03.2025 18:01, Bruno Melloni wrote:
I am wondering because after easily a decade of using log4j with Tomcat... it is now virtually impossible to find instructions (_that actually work_) for how to configure Tomcat 10 to use *Apache Log4j* as its default logger. Since both are Tomcat projects, the only explanation I could come up with is that maybe Apache Log4j is considered a dead project by Apache even if not announced as so.

The rumors about Apache Log4j death are greatly exaggerated. The easiest way to verify the status of an Apache project is to read the quarterly reports of the overseeing PMC[1].

There are two reasons, why Log4j and Tomcat are not more closely integrated:

1. Apache PMCs are very independent and there is no Foundation-wide rule that obliges a PMC to prefer dependencies produced by other Apache projects.

2. There are not many user requests to more closely integrate the two projects.

[1] https://whimsy.apache.org/board/minutes/Logging_Services.html


If you are looking for instructions on how to replace Tomcat's default logging backend with Log4j Core, there is a dedicated section[2] in our new Integrating Log4j Core with Jakarta EE Guide[3]

[2] https://logging.apache.org/log4j/2.x/jakarta.html#replace-tomcat

[3] https://logging.apache.org/log4j/2.x/jakarta.html


The above instructions only redirect server logs to Log4j Core, while web applications will use whatever logging backend they bundle. If you are looking for a tighter integration between server logs and webapp logs, I wrote a couple of Log4j Core Plugins and Tomcat Components[4] to better integrate the two. Basically what you need to do is:

1. Use a special web application classloader[5] that delegates the loading of `org.apache.logging.log4j.*` classes to the parent classloader (the standard classloader only delegates the loading of `jakarta.*` and `org.apache.tomcat.*` classes to the parent).

2. Use some strategy to distinguish between the logs sent by different web applications. There are basically two strategies available:

    * You can split your loggers in logger contexts using an appropriate Log4j Core context selector[6]. This way each web application can have its own configuration file (but doesn't need to). The naming strategy for logging configuration files is inspired by Tomcat's context configuration naming convention.

    * You can use a single logger context and use a Log4j Core context data provider[7] to enrich each message with the name of the context that generated it. This is probably the best strategy if you forward your logs to ElasticSearch or similar.

TL;DR: There is a short guide for my extensions at [8].

[4] https://oss.copernik.eu/tomcat/3.x/

[5] https://oss.copernik.eu/tomcat/3.x/components/tomcat-log4j#classloaders

[6] https://oss.copernik.eu/tomcat/3.x/components/log4j-tomcat#TomcatContextSelector

[7] https://oss.copernik.eu/tomcat/3.x/components/log4j-tomcat#TomcatContextDataProvider

[8] https://oss.copernik.eu/tomcat/3.x/guide

And even though I think I figured out a configuration that appears to work, when I call shutdown.bat (and in a few other scenarios) I get the error:

*class org.apache.logging.log4j.jul.LogManager cannot be cast to class java.util.logging.Handler (org.apache.logging.log4j.jul.LogManager is in unnamed module of loader 'app'; java.util.logging.Handler is in module java.logging of loader 'bootstrap')*

I am using Java 17, Tomcat 10.1.7 and log4j 2.20.0.

You are probably trying to use `o.a.l.l.jul.LogManager` in the `logging.properties` configuration file. To replace the default implementation of `java.util.logging.LogManager` you need to add:

LOGGING_MANAGER="org.apache.logging.log4j.jul.LogManager"

to your `setenv.sh` file. See the documentation on Log4j's website[9].


As alternative you can keep the default `o.a.juli.ClassLoaderLogManager` and use a single `org.apache.logging.log4j.jul.Log4jBridgeHandler` in your `logging.properties` file. This method introduces a considerable overhead to logging, so you should also set the `propagateLevels` property to `true` to mitigate it. See [10] for more details.

[9] https://logging.apache.org/log4j/2.x/log4j-jul.html#bridge-logmanager

[10] https://logging.apache.org/log4j/2.x/log4j-jul.html#bridge-handler


Piotr


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to