Re: Implementing logging separation with log4j2 for Spring Boot 3 apps and Tomcat 10

"Piotr P. Karwasz" <[email protected]> Tue, 14 Jan 2025 22:38:43 +0100
Newsgroups gmane.comp.jakarta.log4j.user
Message-ID <[email protected]>
--------------Aapbv2c7QfurYjHvopoAIlt1
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

Hi Arbi,

On 10.01.2025 23:27, Arbi Sookazian wrote:
>   body {height: 100%; color:#000000; font-size:12pt; font-family:arial,helvetica,sans-serif;}Hi,
> We have multiple Spring Boot 3 WEB apps (exploded WAR files) that need to log to separate/distinct log files on the same Tomcat 10 server.  I was able to implement this successfully on Tomcat 7, log4j2, Spring 4.x using the following doc:https://logging.apache.org/log4j/2.3.x/manual/logsep.html and org.apache.logging.log4j.core.selector.JndiContextSelector.  I'm running into the following exception with the log4j-web-2.23.1.jar with the Tomcat 10/spring boot deployments:

The documentation you are referencing is for the EOL 2.3.x release. The 
new documentation on integrating Log4j with a Jakarta EE server is here:

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

The most important difference between your previous Java EE 6 
application is that starting with Jakarta EE 9, you need to add the 
`log4j-jakarta-web` artifact instead of the `log4j-web` artifact[1] for 
your web applications.

To have separate logger context for each web application, you can either:

1. Embed Log4j in each application. Due to the standard delegation model 
of servlet containers you'll have as many Log4j Core copies as you have 
applications and each one can have a configuration file. Even if you 
don't use web.xml, you can setup a separate `log4jConfiguration` context 
parameter in Tomcat's context descriptor[2].

2. If you wish to have a global Log4j Core installation, you could use 
my custom Log4j extensions for Tomcat ([3], this is not an ASF project). 
The collection of extensions contains everything necessary for a global 
installation:

* A Tomcat classloader that prefers the global `log4j-api` instead of 
the one bundled with your applications.[4]

* A Tomcat-specific context selector to replace the JNDI selector[5]. 
Unlike the JNDI selector, the TomcatContextSelector uses the thread 
context classloader, so does not require additional setup.

* (optionally) A bridge between Tomcat JULI and Log4j API, if you want 
to also forward Tomcat's logs to Log4j API[6].

 > I'm currently trying without a web.xml and I'm noticing only one 
log4j2-spring.xml file is being loaded by the log4j2 classloader.

The support for `log4j2-spring.xml` is not provided by Log4j, but by 
Spring Boot. Spring Boot is very opinionated on the naming of logging 
configuration files (i.e., it does not fall back to the standard Log4j 
Core initialization procedure). You could try setting the 
`logging.config` Spring Boot property[7] to a different value for each 
application. The Tomcat context descriptor is probably the best place to 
do it.

Piotr

[1] 
https://logging.apache.org/log4j/2.x/jakarta.html#log4j-jakarta-web-installation

[2] 
https://tomcat.apache.org/tomcat-11.0-doc/config/context.html#Context_Parameters

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

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

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

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

[7] 
https://docs.spring.io/spring-boot/appendix/application-properties/index.html#application-properties.core.logging.config

--------------Aapbv2c7QfurYjHvopoAIlt1--