You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by chuanjiang lo <lo...@gmail.com> on 2006/12/26 10:02:25 UTC
Loading sequence of log4j
Hi all
I have this start up servlet that does the initializing some system
parameters.
<load-on-startup>1</load-on-startup>
And i place this servlet on the first priority
In the servlet i have something..
System.setProperty("admin-console-abs-home",
getServletContext().getRealPath("")+getServletConfig().getInitParameter("adminConsoleLog"));
So the log4j.xml uses something like
<param name="File" value="${admin-console-abs-home}"/>
Sometimes the Start up servlet runs first and initalize the property. But at
times log4j starts first and giving an error
log4j:ERROR setFile(null,true) call failed.
So how can i ensure that log4j initalizes only after my start up servlet
finishes initalizing?
Re: Loading sequence of log4j
Posted by Maarten Bosteels <mb...@gmail.com>.
Be aware that system properties are shared by all webapps running inside one
tomcat instance.
That means, if you call System.setProperty("foo","bar") in a listener of
webapp1
all other webapps will get "bar" when they call System.getProperty("foo")
Not all servlet containers behave this way.
Maarten
On 12/26/06, Jacob Kjome <ho...@visi.com> wrote:
>
>
> Don't use a init servlet. The servlet spec makes no guarantee as to
> when the servlet initialization will happen. It may or may not be at
> container startup. Use a serlvet context listener. It has methods
> that are guaranteed to be called at application startup and
> application shutdown. Here's what I suggest...
>
> Assuming you are using Tomcat...
>
> 1. Put log4j.jar in WEB-INF/lib and a dummy Log4j config file (see
> below) in WEB-INF/classes. The dummy config file is meant to cover
> for autoconfiguration if it runs before your manual configuration
> runs, avoiding various bogus logging, warning messages from Log4j, or
> other errors.
>
> 2. Put your real config file under WEB-INF, but not in WEB-INF/classes
>
> 3. Implement a servlet context listener and implement the
> contextInitialized() method (off the top of my head, I think that's
> what it is called). Set you system property first and then manually
> configure log4j, pointing it to your real config file somewhere under
> WEB-INF.
>
> BTW, I don't recommend logging to a directory directly under the
> application directory. The servlet spec makes no guarantee that you
> have write access to the file system other than the provided
> System.getProperty("java.io.temp") directory. I suggest you set the
> system property via the command line using a -D parameter when you
> start up the appserver. With Tomcat, you can provide this in the
> CATALINA_OPTS system property...
>
> CATALINA_OPTS=-Dadmin-console-abs-home=/my/path/to/logs
>
> If you do this, you can bypass the dummy Log4j config file and skip
> manual initialization. Just put your real config file in
> WEB-INF/classes and let Log4j auto-configure itself, since the system
> property is now guaranteed to be there before Log4j initializes itself.
>
>
>
> Here's an example of a dummy Log4j config file to suppress Log4j
> errors until you perform your manual initialization......
>
> <?xml version="1.0" encoding="UTF-8" ?>
> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
>
> <!-- This file is meant to satisfy/supress auto-configuration of the
> default logger repository
> when log4j.jar is included in WEB-INF/lib. This assumes that
> manual configuration will be
> performed later, usually on a non-default logger repository as
> specified by a repository selector.
> The purpose of supression is to avoid Log4j auto-configuration
> finding a Log4j config file in a
> parent classloader when it can't find one locally, which can
> lead to either bogus
> (but generally harmless) configuration of the default
> repository or even a nasty stacktrace
> if an incompatible Log4j config file is found (such as when
> using Log4j-1.2.x in WEB-INF/lib
> and Log4j-1.3 in the server's classpath. The XML formats are
> generally incompatible!).
> This file should be copied to WEB-INF/classes as "log4j.xml"
> when building the .war file. -->
> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
> debug="false" threshold="debug">
> <root>
> <level value="off"/>
> </root>
> </log4j:configuration>
>
>
> Jake
>
> At 03:02 AM 12/26/2006, you wrote:
> >Hi all
> >
> >I have this start up servlet that does the initializing some system
> >parameters.
> >
> > <load-on-startup>1</load-on-startup>
> >And i place this servlet on the first priority
> >
> >In the servlet i have something..
> >System.setProperty("admin-console-abs-home",
> >getServletContext().getRealPath("")+getServletConfig().getInitParamete
> >r("adminConsoleLog"));
> >
> >So the log4j.xml uses something like
> ><param name="File" value="${admin-console-abs-home}"/>
> >
> >Sometimes the Start up servlet runs first and initalize the property. But
> at
> >times log4j starts first and giving an error
> >log4j:ERROR setFile(null,true) call failed.
> >
> >So how can i ensure that log4j initalizes only after my start up servlet
> >finishes initalizing?
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
>
>
Re: Loading sequence of log4j
Posted by Jacob Kjome <ho...@visi.com>.
At 04:04 AM 12/27/2006, you wrote:
>On 12/27/06, chuanjiang lo <lo...@gmail.com> wrote:
>>
>> I am using PropertyConfigurator.configure in the Listener class
>>
>> PropertyConfigurator.configure(event.getServletContext
>> ().getRealPath("")+"/WEB-INF/foo.xml");
>>
2 things...
1. Never ever use this. Always load as a resource. As I stated
before, the servlet spec makes no guarantee that you will be a "real
path". If your webapp is served directly from the .WAR file instead
of an "exploded" WAR, getRealPath("/") will return null. Instead use
context.getResource("/WEB-INF/foo.xml"). This will return a URL,
which you can pass to the configure() method that takes a URL. See...
http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/javax/servlet/ServletContext.html#getResource(java.lang.String)
2. You can't use PropertyConfigurator with an XML config file. Use
DOMConfigurator for XML config files
>> Log4j is picking up foo.xml, However it seems like the logging events does
>> not behave as what foo.xml specifies. Nothing has changed.
>> Appreciate any kind advice.
>
>
>
>Learnt the mistake here.
>I should be using DOMConfigurator.configure()
>
Depends on what your config is. If this works, it means you have a
log4j.xml somewhere in the classpath and it is using that for
configuration. This is clearly not what you want because your config
file is named "foo.xml" and it doesn't even exist in the
classpath. You are picking up someone elses config file. What you
should be doing is calling configure(myFooXMLURL) with the URL you
loaded (see above).
>One thing i notice for PropertiesConfigurator
>
>for e.g.
> Properties props = new Properties();
>props.put("admin-console-abs-home", path);
> in = this.getClass().getClassLoader().getResourceAsStream("foo.properties
>");
>props.load(in);
> PropertyConfigurator.configure(props);
>
>In this case in foo.properties, we are able to use ${admin-console-abs-home}
>as a variable.
>Is there any method for DOMConfigurator?
>
The only difference between the 2 configurators, as far as property
references are concerned, is that you can't define the property
inside the XML file where you can inside the properties
file. However, in both cases, you can reference the property inside
the respective config files. so, your property reference of
${admin-console-abs-home} will work in both cases.
Also note what one responder mentioned. If you defined a system
property, it is available to all applications. I suggest that any
property you set either generically named *and* generically points to
a single location where you are ok with any app running within the
container logging to this directory OR name your properties very
specifically, such as "fooApp.log.home", where "fooApp" is the name
of a specific application. Naming your properties specifically
reduces the chance that you will clash with other apps that might be
setting or depending on their own properties.
What I suggest is that you just log to tomcat's default logging
directory. Tomcat already sets ${catalina.home} and ${catalina.base}
properties. I suggest using the latter (read up on Tomcat to find
out why). This will simplify your life. If you refer to these
properties to provide the directory for logging, then you don't need
to mess with any manual log4j config process nor do you need to set a
custom -D parameter to specify your logging home. Just put your
log4j.xml or log4j.properties (use those names, specifically) in
WEB-INF/classes and log4j.jar in WEB-INF/lib and you are done.
Jake
Jake
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: Loading sequence of log4j
Posted by chuanjiang lo <lo...@gmail.com>.
On 12/27/06, chuanjiang lo <lo...@gmail.com> wrote:
>
> I am using PropertyConfigurator.configure in the Listener class
>
> PropertyConfigurator.configure(event.getServletContext
> ().getRealPath("")+"/WEB-INF/foo.xml");
>
> Log4j is picking up foo.xml, However it seems like the logging events does
> not behave as what foo.xml specifies. Nothing has changed.
> Appreciate any kind advice.
Learnt the mistake here.
I should be using DOMConfigurator.configure()
One thing i notice for PropertiesConfigurator
for e.g.
Properties props = new Properties();
props.put("admin-console-abs-home", path);
in = this.getClass().getClassLoader().getResourceAsStream("foo.properties
");
props.load(in);
PropertyConfigurator.configure(props);
In this case in foo.properties, we are able to use ${admin-console-abs-home}
as a variable.
Is there any method for DOMConfigurator?
Re: Loading sequence of log4j
Posted by chuanjiang lo <lo...@gmail.com>.
On 12/27/06, chuanjiang lo <lo...@gmail.com> wrote:
>
>
>
> Appreciate your advice.
>
> How do i manually configure the log4j config file to point to WEB-INF?
>
>
>
I am using PropertyConfigurator.configure in the Listener class
PropertyConfigurator.configure(event.getServletContext
().getRealPath("")+"/WEB-INF/foo.xml");
Log4j is picking up foo.xml, However it seems like the logging events does
not behave as what foo.xml specifies. Nothing has changed.
Appreciate any kind advice.
Re: Loading sequence of log4j
Posted by chuanjiang lo <lo...@gmail.com>.
On 12/27/06, Jacob Kjome <ho...@visi.com> wrote:
>
>
> 3. Implement a servlet context listener and implement the
> contextInitialized() method (off the top of my head, I think that's
> what it is called). Set you system property first and then manually
> configure log4j, pointing it to your real config file somewhere under
> WEB-INF.
Appreciate your advice.
How do i manually configure the log4j config file to point to WEB-INF?
Re: Loading sequence of log4j
Posted by Jacob Kjome <ho...@visi.com>.
Don't use a init servlet. The servlet spec makes no guarantee as to
when the servlet initialization will happen. It may or may not be at
container startup. Use a serlvet context listener. It has methods
that are guaranteed to be called at application startup and
application shutdown. Here's what I suggest...
Assuming you are using Tomcat...
1. Put log4j.jar in WEB-INF/lib and a dummy Log4j config file (see
below) in WEB-INF/classes. The dummy config file is meant to cover
for autoconfiguration if it runs before your manual configuration
runs, avoiding various bogus logging, warning messages from Log4j, or
other errors.
2. Put your real config file under WEB-INF, but not in WEB-INF/classes
3. Implement a servlet context listener and implement the
contextInitialized() method (off the top of my head, I think that's
what it is called). Set you system property first and then manually
configure log4j, pointing it to your real config file somewhere under WEB-INF.
BTW, I don't recommend logging to a directory directly under the
application directory. The servlet spec makes no guarantee that you
have write access to the file system other than the provided
System.getProperty("java.io.temp") directory. I suggest you set the
system property via the command line using a -D parameter when you
start up the appserver. With Tomcat, you can provide this in the
CATALINA_OPTS system property...
CATALINA_OPTS=-Dadmin-console-abs-home=/my/path/to/logs
If you do this, you can bypass the dummy Log4j config file and skip
manual initialization. Just put your real config file in
WEB-INF/classes and let Log4j auto-configure itself, since the system
property is now guaranteed to be there before Log4j initializes itself.
Here's an example of a dummy Log4j config file to suppress Log4j
errors until you perform your manual initialization......
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!-- This file is meant to satisfy/supress auto-configuration of the
default logger repository
when log4j.jar is included in WEB-INF/lib. This assumes that
manual configuration will be
performed later, usually on a non-default logger repository as
specified by a repository selector.
The purpose of supression is to avoid Log4j auto-configuration
finding a Log4j config file in a
parent classloader when it can't find one locally, which can
lead to either bogus
(but generally harmless) configuration of the default
repository or even a nasty stacktrace
if an incompatible Log4j config file is found (such as when
using Log4j-1.2.x in WEB-INF/lib
and Log4j-1.3 in the server's classpath. The XML formats are
generally incompatible!).
This file should be copied to WEB-INF/classes as "log4j.xml"
when building the .war file. -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false" threshold="debug">
<root>
<level value="off"/>
</root>
</log4j:configuration>
Jake
At 03:02 AM 12/26/2006, you wrote:
>Hi all
>
>I have this start up servlet that does the initializing some system
>parameters.
>
> <load-on-startup>1</load-on-startup>
>And i place this servlet on the first priority
>
>In the servlet i have something..
>System.setProperty("admin-console-abs-home",
>getServletContext().getRealPath("")+getServletConfig().getInitParamete
>r("adminConsoleLog"));
>
>So the log4j.xml uses something like
><param name="File" value="${admin-console-abs-home}"/>
>
>Sometimes the Start up servlet runs first and initalize the property. But at
>times log4j starts first and giving an error
>log4j:ERROR setFile(null,true) call failed.
>
>So how can i ensure that log4j initalizes only after my start up servlet
>finishes initalizing?
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org