• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Using log4j in ServletContextListener

 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's a lesson learned from the "school of hard knocks"...

SUMMARY: If you use an initialization servlet to initialize log4j, you may have trouble using log4j in a ServletContextListener. Instead, initialize log4j by putting a log4j.properties file in WEB-INF/classes.

Here are details of the "hard knock"...

PROBLEM: My logger was not logging. I had created a log4j Logger as a static variable in a ServletContextListener. I called the logger's debug() method in the listener's contextInitialized() method. The debugging messages were not logged. Instead, these error messages appeared in the Tomcat log:

log4j:WARN No appenders could be found for logger (ServletContextListener1).
log4j:WARN Please initialize the log4j system properly.

DIAGNOSIS: I was using an initialization servlet (named Log4jInit) to initialize log4j for the webapp. This is described in the log4j manual as "the most flexible way for initializing log4j." The idea is that the container loads the servlet when it starts up, and the code to initialize log4j can be placed in the servlet's init() method. However, Tomcat loaded the ServletContextListener before it loaded Log4jInit, so log4j was not configured in time for the ServletContextListener.

ACTION: Instead of using an initialization servlet, just create a log4j.properties file and place it in the WEB-INF/classes directory of the webapp. This is another technique suggested by the log4j manual, and much easier than using an initialization servlet! It seems that log4j is automatically initialized using this log4j.properties file, before the ServletContextListener is loaded.

RESULT: The log4j logger now works correctly when called from within the ServletContextListener's contextInitialized() method.
 
Ranch Hand
Posts: 161
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Now that is a good idea, John, and definately food for thought.

I would like to show my appreciation for this idea, by contributing to some additional food for thought.

To place the log4j initialization code into a file outside of the web application, and then use a JNDI environment variable in tomcat so that it is indirected from the web application, the log4j init gets the path to its config file as the value of a string environment variable.
This saves me time when i have to build a war file, i can just move it from dev instance (debug on) to the prod instance (debug off), since the logging, (among other things) is now configured in a server instance, and not the web app module.
I guess it is what JNDI DataSources are to database connections, for the log4j configuration.

I had been doing this with a log4j init servlet for a while now, and was just putting up with the logging not working until the app got booted up, it was just not obvious to me that this should be in a context listener.

but now here is it in a servlet context listener. It is all jndi and log4j api stuff, so was pretty quick to move over.



to make this work in tomcat, i add the following to the web.xml:



and to the META-INF/context.xml file, for tomcat to auto map JNDI resorces on deployment of a war:




and in the tomcat instance's server.xml:


where the value of the environment variable (file:/...) is the full property path to the log4j initialization file, outside of your web application. For me, this is also my system configuration for the tomcat instance folder.
 
reply
    Bookmark Topic Watch Topic
  • New Topic