• 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

Changing log4j.properties in unexploded WAR file

 
Greenhorn
Posts: 27
Google Web Toolkit Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm trying to discover if there is a way to put the log4j.properties in some place other than WEB-INF/classes. Is there a way to do this in Tomcat? Is there a solution that is generic to other servlet containers as well?

I'm anticipating a customer or support tech who wants unpackWARs="true" but also wants the log written to someplace other than ${java.io.tmpdir}, say a home directory or a local log directory (which will certainly differ between sites based on various Linux distros, Windows, local admin procedures, etc.).

Using the Log4jInit servlet in "Default Initialization under Tomcat" (in http://logging.apache.org/log4j/1.2/manual.html) as a guide, I've tried to find a way to set the log4j-init-file parameter in my app's META-INF/context.xml. However it seems that <load-on-startup>1</load-on-startup> preempts whatever I my set in the app context.

Assuming I can't change the location of log4j.properties to outside of my WAR and in a manner that can account for different server configurations, what is the merit of using a initialization servlet? What benefits does a servlet provide? Do I need it, say, for rereading log4j.properties (with doGet()) if in troubleshooting we need to change the log level?
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is no merit in using an initialization servlet. That's because life-cycle listeners were added to Java EE several years ago, and that's what you should be using now.

However, moving on from that diversion: Initializing log4j doesn't have to use a config file which is automatically searched for in the classpath. You can initialize it by specifying the location of a config file, or you can initialize it by writing code which creates appenders and so on. I believe this is described in the log4j tutorial, but it's a long time since I read the tutorial so it may not be covered as well as I think it is.

As for trouble-shooting, you can certainly use a servlet to modify the log level, but I think it's more common to use JMX to do that sort of thing these days.
 
Thad Humphries
Greenhorn
Posts: 27
Google Web Toolkit Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:There is no merit in using an initialization servlet. That's because life-cycle listeners were added to Java EE several years ago, and that's what you should be using now.



Of course, a ServletContextListener. Done. Thanks.

Paul Clapham wrote:As for trouble-shooting, you can certainly use a servlet to modify the log level, but I think it's more common to use JMX to do that sort of thing these days.



As for changing the log level through JMX, how can that be done? When I run jconsole, I don't see my logger. Must I put something into my listener to have jconsole see my logger? How do I connect jconsole and my app that is using log4j.
 
Paul Clapham
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Thad Humphries wrote:As for changing the log level through JMX, how can that be done? When I run jconsole, I don't see my logger. Must I put something into my listener to have jconsole see my logger? How do I connect jconsole and my app that is using log4j.



Sorry, I have used JMX in other contexts but not in Tomcat. All I know is that you can use JMX in Tomcat -- but to tell you the truth I don't even know for sure that you can use it to administer things in a web app, as opposed to just administering the server. So I guess that advice wasn't all that helpful. It might be worth looking into though, to see if it's a possible route for you to take.
 
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One of the Great Confusions of Our Time. I went round and round and round on this one myself.

I'm out of practice on the topic, but unless I got totally confused, JMX for webapps is not an issue. The webapps must contain the appropriate MBeans, and (IIRC) they have to register them with the JVM in order to be served up, but whether a given MBean belongs to the server or to a deployed app doesn't matter, as (I think!) the MBean "belongs" to the JVM.
 
Thad Humphries
Greenhorn
Posts: 27
Google Web Toolkit Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:One of the Great Confusions of Our Time. I went round and round and round on this one myself.

I'm out of practice on the topic, but unless I got totally confused, JMX for webapps is not an issue. The webapps must contain the appropriate MBeans, and (IIRC) they have to register them with the JVM in order to be served up, but whether a given MBean belongs to the server or to a deployed app doesn't matter, as (I think!) the MBean "belongs" to the JVM.



Thanks, Tim. It took some hunting, but I've hit on something that is working, and it is generic enough to use on my next app.

Here's my LogListener. The administrator can use the default properties file from the WAR or define his own. Since the log properties file can be set in the application context, it can be elsewhere--outside of Tomcat--and the WAR remain unpacked. This listener also registers the logger with JMX so that the log level can be set while the app is running (see screenshot).

jconsole.png
[Thumbnail for jconsole.png]
jconsole screenshot showing where to see log level
 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
getRealPath() gives me hives. It isn't guaranteed to return a path at all, and especially if the WAR is unexploded.

Personally, I prefer to store parameters like this as env-entry definitions so that they can be set (overridden) from the Tomcat Context definition and retrieved by the webapp via JNDI.

I definitely would avoid using relative path names - they are extremely untrustworthy in a webapp environment. Most likely, I'd expect a general path value and use a "magic" value such as "*" to indicate use of the internal log4j property definitions.

 
Thad Humphries
Greenhorn
Posts: 27
Google Web Toolkit Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:getRealPath() gives me hives. It isn't guaranteed to return a path at all, and especially if the WAR is unexploded.

Personally, I prefer to store parameters like this as env-entry definitions so that they can be set (overridden) from the Tomcat Context definition and retrieved by the webapp via JNDI.

I definitely would avoid using relative path names - they are extremely untrustworthy in a webapp environment. Most likely, I'd expect a general path value and use a "magic" value such as "*" to indicate use of the internal log4j property definitions.



You're right, Tim. And as soon as I turn from my Linux box and work a short while on a Windows laptop, I'm reminded that checking for the first character equal to "/" to indicate an absolute path isn't portable across all platforms. Thanks.
 
Your mother was a hamster and your father was a tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic