Piers, I've configured two webapps with the log4j2 configuration outside of the *war files. The approach I'll describe is working in Tomcat 8.5 and Tomcat 9.
First I create a LogListener class for the webapp: public class LogListener implements ServletContextListener { private static final Logger LOGGER = LogManager.getLogger(); private Log4jServletContextListener listener = new Log4jServletContextListener(); @Override public void contextDestroyed(ServletContextEvent event) { listener.contextDestroyed(event); } @Override public void contextInitialized(ServletContextEvent event) { String loggerPath = "WEB-INF/classes/log4j2.xml"; ServletContext context = event.getServletContext(); String fileString = context.getInitParameter("log4jConfiguration"); if (fileString != null && fileString.length() > 0 && !fileString.equals("*")) { if ((new File(fileString)).exists()) { loggerPath = fileString; } } event.getServletContext().setInitParameter( Log4jWebSupport.LOG4J_CONFIG_LOCATION, loggerPath); listener.contextInitialized(event); LOGGER.info("logging properties from " + loggerPath); } } I declare the LogListener in web.xml and add some filtering: <listener> <!-- This listener *must* be first for log4j to work. --> <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class> </listener> <listener> <!-- This listener is required to set the log4jConfiguration fallback. --> <listener-class>com.mycorp.server.rest.listeners.LogListener</listener-class> </listener> <!-- See https://logging.apache.org/log4j/2.x/manual/webapp.html --> <filter> <filter-name>log4jServletFilter</filter-name> <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class> </filter> <filter-mapping> <filter-name>log4jServletFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> <dispatcher>ASYNC</dispatcher> </filter-mapping> <context-param> <param-name>isLog4jAutoInitializationDisabled</param-name> <param-value>true</param-value> </context-param> Finally, in the Tomcat context file, META-INF/context.xml, I add the log4jConfiguration that LogListener wants: <Parameter description="Configure Log4j2 logging." name="log4jConfiguration" override="false" value="/Users/admin/local/etc/my_logger.xml"/> When I start Tomcat, the first entry in the log is 12:23:23.439 INFO LogListener.contextInitialized() - logging properties from /Users/admin/local/etc/my_logger.xml At one time I had this working in Jetty, but I no longer remember where to set its context. We've installed these apps on numerous servers, both Linux (of various distros) and macOS. AFAIK, they're also running on a number of Windows servers as well. Logging works everywhere. On Wed, Mar 20, 2024 at 12:09 PM Piers Uso Walter <piers.wal...@ilink.de> wrote: > Hi Piotr, > > Thanks for your email. > > Here is what I’m trying to do: > The previous version of our app stores the log4j configuration within the > war file. > This works fine but is annoying if one wants to change any logging setting > (unpacking the war, changing the configuration, repacking the war, > redeploying). > > For the next version of our app, I would like to move the log4j > configuration to a place outside of the war. > For Tomcat I would like to use $catalina.home/conf/ilink/GW-log4j2.xml > and for Wildlfy I would like to use > $jboss.home.dir/conf/ilink/GW-log4j2.xml > (with $catalina.home and $jboss.home.dir being system properties that are > defined in the two servers) > > Since the configuration file path is only known at runtime I cannot use > the servlet initialization parameter ‘log4jConfiguration’ in web.xml. > So I looked at log4j's automatic configuration [1]. > This led me to the idea to use a ServletContextListener to determine if > the app is running in WIldFly or in Tomcat and then setting the system > property $log4j.configurationFile accordingly. > > But as you point out, the ServletContextListener is executed too late. > That explains why it does not work in my case 2 (when the Tomcat service > is restarted). > I still don’t understand why it does work in my case 1 (when the app is > being redeployed in a running Tomcat), but that is not so important as this > does not seem to be the correct approach anyway. > > Also, thanks for pointing out what should have been obvious: that other > web apps on the same server will be affected when I set the > `log4j2.configurationFile` property. > Not a good idea. > > Am I trying something unusual here when I attempt to make the app decide > where the log4j configuration file is located? > Is there any other way in which I can achieve this? > Is there an API for this? > > Thanks, > Piers > > [1] > https://logging.apache.org/log4j/2.x/manual/configuration.html#automatic-configuration > > > > > Am 15.03.2024 um 07:45 schrieb Piotr P. Karwasz <piotr.karw...@gmail.com > >: > > > > Hi Piers, > > > > On Thu, 14 Mar 2024 at 14:08, Piers Uso Walter <piers.wal...@ilink.de> > wrote: > >> However, what I was trying to achieve by using a servlet context > listener was to be able to set the location of the log4j configuration file > at run time. > >> I’m trying to make the app compatible with different app servers where > configuration files are typically placed in different locations. > >> So I’m figuring out at run time which app server the app is running in, > and based on that I know where to expect the log4j configuration file. > > > > Can provide more details as to where the path to the configuration > > file is actually stored? If you change the `log4j2.configurationFile` > > property, other web apps on the same server will be affected, which > > might be an unpleasant surprise to users. There are less invasive ways > > to do that. > > > > I also wonder if maintaining container specific code is worth the > > effort. Many application servers have a detailed guide to configuring > > logging (e.g. WildFly[1]). Users might be unwilling to learn yet > > another way to configure logging. > > > > Sure, Tomcat is an exception, that is why I maintain a small set of > > Log4j Core plugins and Tomcat extensions[2] to help users > > administering logging at a global level. > > > > Piotr > > > > [1] https://docs.wildfly.org/31/Admin_Guide.html#Logging > > [2] https://github.com/copernik-eu/log4j-tomcat > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org > > For additional commands, e-mail: log4j-user-h...@logging.apache.org > > > > -- "Hell hath no limits, nor is circumscrib'd In one self-place; but where we are is hell, And where hell is, there must we ever be" --Christopher Marlowe, *Doctor Faustus* (v. 111-13)