logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jacob Kjome <h...@visi.com>
Subject Re: SV: ContextClassLoaderSelector
Date Sun, 13 Apr 2003 16:12:26 GMT

Ok, all changes I've mentioned are done and in CVS.

Jake

At 07:29 PM 4/12/2003 -0500, you wrote:
>At 06:31 PM 4/12/2003 -0400, you wrote:
>>Jacob Kjome wrote:
>>>I think you've missed the point of what is being done with 
>>>"javax.servlet.context.tempdir".
>>
>>Yes, I assumed you were using it for it's intended purpose.
>
>I figured as much.  This unorthodox usage was just a last ditch effort to 
>try to make things more automatic, require less configuration, and avoid 
>some maintenance issues.  I'd never log to a temp directory.  The 
>configuration defaults to logging to the WEB-INF/logs directory of the 
>context being deployed.  This assumes that the context isn't being 
>deployed directly from a .war file where there is no File IO possible.  In 
>that case, one can set the context-param "log4j-log-home" to any arbitrary 
>location which will override the default.
>
>>>  It is absolutely, utterly, guaranteed that any and all containers 
>>> claiming to have support for the servlet spec *will* provide a 
>>> temporary directory that is unique for each web application.  If they 
>>> don't, they aren't compliant.  I have no worries about that.
>>>Here is what you are missing.  I don't care about using the actual 
>>>directory.  I just care about the directory name.  What I was trying to 
>>>accomplish was a way that one didn't have to keep multiple configuration 
>>>files in sync with the name of some property...and I also needed to have 
>>>some pretty decent assurance that that name wouldn't exist already as a 
>>>system property.  Since webapps must have unique context path names, 
>>>that turns out to be a pretty good way to name system properties.
>>>However, the servlet spec doesn't provide any direct way to obtain the 
>>>servlet context path (eg...  /mycontext) via the ServletContext, which 
>>>is all I have to work with in the servlet context listener.  However, I 
>>>can grab the value of the system property 
>>>"javax.servlet.context.tempdir".  As it turns out, the way Tomcat name 
>>>tempdirs is very consistent.  For instance, a context with the path of 
>>>"/mycontext" would have a tempdir named something like this...
>>>C:\Java\Apache\Jakarta\tomcat-4.1.24\work\Standalone\localhost\mycontext
>>>So, I just grab the string following the last index of the value 
>>>returned by File.separator and, low and behold, I've obtained the name 
>>>of the currently running context.
>>
>>Is this any different from ServletContext.getServletContextName() 
>>(available in 2.3) or would that be equivalent when available?
>
>I sure wish getServletContextName() would work.  However, what that 
>returns is the value of the <display-name> tag in the web.xml.  So, what 
>it will return will be somewhat arbitrary or null if not provided.  As 
>such, It isn't useful here.  I also don't want to overload the usage of 
><display-name> for something specific to the configuration of the Log4j 
>InitContextListener.
>
>>>I take that and append ".log.home", use that as a system property name, 
>>>and set the physical path to  where logs should be written for that 
>>>context which could either be the default of the WEB-INF/logs of the 
>>>webapp or a user defined path.
>>>What breaks down in other servlet containers is that the string 
>>>following the last index of the value returned by File.separator for a 
>>>context with a path of "/mycontext" might be 
>>>"some-other_random-string_having-nothing_to-do_with-the_name-of_the-context_path".

>>>Now, in one sense, this is fine because it is unique since we don't want 
>>>to accidentally overwrite a system property being used by some other 
>>>application.  However, it is far from predictable and might change with 
>>>each deployment of the webapp in some containers.  We need to be able to 
>>>put something we can count on in log4j.xml such as the following an know 
>>>it will just work...
>>><param name="File" value="${mycontext.log.home}/main.log" />
>>>In summation, I require...
>>>1.  a name that is reasonably guaranteed to be unique in the VM
>>>     - this is achieved by using the name of the context path which must 
>>> be unique within the container so a system property named after 
>>> something that is already unique is pretty well guaranteed to be itself
>>>2.  not have to specify this name in multiple configuration files.  Only 
>>>log4j.xml.
>>>    -  It is extra work to have to change things in two places.  To 
>>> avoid this, instead of requiring the use to have to provide a 
>>> context-param with the name of the system variable, I just have the 
>>> configuration derive it on its own.  This also prevents arbitrary 
>>> naming that might not be as unque in the VM as one might hope.
>>>3.  the name must be predictable
>>>    - one has to reference a system property name in log4j.xml that they 
>>> can be assured will exist at runtime, otherwise it is of no use.
>>>Defining a naming scheme based on [context path].log.home is entirely 
>>>predictable and the dynamically derived system variable name works for 
>>>this every time under Tomcat.
>>
>>Let me ask some stupid questions, since I do not really know the purpose 
>>of the ContextClassLoaderSelector:
>
>Ok
>
>>How does this work outside of a servlet container?  Or is it only 
>>intended to run inside a container?
>
>The only "intended" purpose of ContextClassLoaderSelector is to run inside 
>a servlet container.  It also assumes a certain classloader hierarchy 
>where each webapp runs in its own classloader.  I haven't really tested 
>this outside of Tomcat and can't guarantee it works anywhere else, 
>although I think it should.  However, there is also a ContextJNDISelector 
>which takes advantage of the standard JNDI interface that is guaranteed to 
>be provided by all servlet containers and J2EE containers in general.
>
>Now, the idea of both of these is to allow for a distinct logging 
>environment for each webapp with log4j.jar sitting in a parent classloader 
>(not in WEB-INF/lib of a webapp).  Normally, all apps would end up sharing 
>the same logger repository.  However, with logger repositories keyed on 
>particular classloaders or particular JNDI namespaces, one can obtain 
>separate logger repositories for each webapp context.
>
>Read this for more info...
>http://www.qos.ch/logging/sc.html
>
>>   What are the other configuration files you refer to?
>
>Note that the configuration is for the servlet context listener 
>"InitContextListener" which does the configuration.  the repository 
>selectors are just classes that implement the log4j RepositorySelector 
>interface.  They don't have any configuration at all.
>
>The configuration files involved with the InitContextListener are web.xml 
>and log4j.xml (or whatever log4j configuration file you specify).  The 
>web.xml contains <context-param> elements that define specific parameters 
>that the InitContextListener reads.  Based on that, it configures log4j 
>and installs a repository selector.  Note that once one app sets the 
>repository selector, the other apps are destined to use that one since 
>log4j can have only one repository selector defined.  You should read the 
>Javadoc for the InitContextListener and each of the repository selectors I 
>mentioned as they describe all of this in pretty good detail.  You can 
>find it in the jakarta-log4j-sandbox module in CVS.
>
>>   Might there be a way to point both places to the same config file?
>
>I'm not sure I understand what you are getting at here?  The web.xml file 
>is responsible for providing information to the InitContextListener.  The 
>only thing log4j.xml needs is the name of the system property.  It is the 
>name of the system property that needs to stay in sync.  If, for instance, 
>you had this line in the configuration of a FileAppender...
>
><param name="File" value="${mycontext.log.home}/main.log" />
>
>Then you'd better make darned sure that the web.xml has a <context-param> 
>that looks something like this (this is what I need to add, BTW)...
>
><context-param>
>     <param-name>log4j-system-variable-name</param-name>
>     <param-value>mycontext.log.home</param-value>
></context-param>
>
>Of course that isn't an issue in Tomcat since the dynamically generated 
>system variable name will be exactly "mycontext.log.home" without having 
>to specify it in web.xml, but for other servlet containers, specifying the 
>context-param may be necessary.  If it is necessary, then if you change it 
>in one place, you'd better change it in the other.  That is why I tried 
>(and partially succeeded) to avoid having this context-param at all.  But, 
>alas, it must be provided.  Also, you need to make sure this name is 
>unique within the JVM running the container.  Again, using the naming 
>scheme [context path].log.home should provide a unique name.
>
>>   What happens if tomcat changes the way it implements the temporary 
>> directory mechanism?
>
>Which is exactly why I need to provide the new context-param allowing for 
>optional override of the dynamic generation of the system variable 
>name.  This should be done sometime this weekend.
>
>Jake

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message