At 09:25 PM 5/21/2005 +0000, you wrote:
>Jacob, thank you for the response. Your prolificacy as evinced by the
>archives is borne out :-)
>
>>classes in jars that are put in WEB-INF/lib are run in exactly the same
>>classloader as those in WEB-INF/classes. You need not do all the checking
>>of appenders and such. In fact, you are probably making bad assumptions on
>>behavior which is why you only ever see the System.out message. Simply
>>do...
>>
>>logger.info("log message");
>
>I've confirmed that this 'auto discovery and configuration' works.
>
>However, from my reading of the "short" version of the online manual, which
>states that "Under certain well-defined circumstances however, the static
>inializer of the Logger class will attempt to automatically configure
>log4j", but which subsequently severally exemplifies explicitly indicating
Zowie, that's quite a string of words. I have no idea what it means????
>the log4j configuration file, I came away with the idea that explicitly
>indicating the configuration file is preferable. Let's assume I prefer
>explicit indication.
>
I'll have to trust you because of the confusion noted above, but are you
saying that autoconfiguration works, but your explicit configuration
doesn't? In that case, I'd be a bit wary that you are actually
configuring things properly in explicit configuration. You do realize that
autoconfiguration is probably happening anyway. This is because the static
initializer will come into play before you config servlet does. And the
fact that you have log4j.properties in the classpath (WEB-INF/classes)
means that autoconfiguration will find the file. If you insist on explicit
configuration, then I would recommend you put log4j.properties somewhere
other than the classpath, such as under WEB-INF, but not
/classes. However, this also presents a dilemma, because there may exist a
Log4j config file somewhere in a higher classloader. To shortcircuit that,
I recommend putting a minimal log4j.xml file in WEB-INF/classes that sets
the root logger to OFF or something like that. Then, if there is any
logging happening, you can attribute it purely to the explicit configuration.
>>
>>No need to have the extra logMessage() method either. You are hardcoding
>>Level.INFO, so why not just use logger.info() directly in getBar()?
>
>Perhaps, but this shouldn't change working semantics, no?
>
No, but as written, the code is completely unnecessary, unless you plan to
do something other than simply log a message in there.
>>If you see no output from this, then you haven't configured things
>>properly.
>
>I do see output--WEB-INF/classes use the logger; WEB-INF/lib doesn't. I'm
>trying to discover where I've erred.
>
Ok, here's the thing. I hinted at it before, but did not spell it out. I
told that "you are probably making bad assumptions on
behavior which is why you only ever see the System.out message". Allow me
be more explicit...
>if ( logger != null && logger.getAllAppenders().hasMoreElements()
1. You define the logger above. It won't be null. The check is
unnecessary, but causes no harm. So far so good
2. You attempt to get the appenders on the current logger and assume that
hasMoreElements() will tell you if there is an appender defined for that
logger. However, I believe this assumption is incorrect. Inherited
appenders won't show themselves here. You added an appender to the root
logger. I would hasten to bet that
getRootLogger.getAllAppenders.hasMoreElements() would return
true. However, as no appenders were explicitly added to the current
logger, hasMoreElements() will return false on the current logger (someone
please correct me if I'm wrong here).
Again, you over engineered and it bit you. Had you started simple, you
would have realized the source of failure once you added this more
complicated behavior after first seeing the simple behavior work. That's
what I mean by KISS.
I just re-read your original message and saw noticed when you said "Now, I
want to use this already-initialized logger". Are you under the impression
that loggers are initialized individually? When you perform
configuration, you are configuring the behavior of a "logger
repository". The loggers that are mentioned in your config file don't
necessarily have to exist. It just that, if they do, they will behave as
you configured them. They will only exist upon first use of the logger. I
wouldn't call that "initialization" in the same way as the "logger
repository" is initialized, though. Keep in mind, loggers have names that
you assign. The most common way to name them is based on the package
hierarchy, which makes it easy to take advantage of logger
inheritance. However, this is only a naming convention. You could define
a logger in two separate classes, both named "foo" and both would point to
the same logger instance (as long as they are in the same logger repository).
>>BTW, are you doing anything special in your InitServlet? If not, just let
>>autoconfiguration work for you. It will find log4j.properties and perform
>>configuration in a static initializer by default. No need to do this
>>manually unless you are doing something special. You are really over
>>engineering this. KISS.
>
>No, nothing special in the init servlet but, again, let's say I prefer
>explicitly indicating the config file to use. Imay need this dynamic
>ability later, and removing it is as simple as a web.xml edit.
>
>The reason I first call logMessage() is so that it is the one "gateway" to
>logging (I would, of course, arrange for calls to it not to use the
>log4j-specific "Level" parameter). Also, remember that Bar is a separate
>"library", and I don't want its logs going to log4j when not used in a
>webapp. Hence the check for configuredness, etc.
It is difficult to check for Log4j configuredness, at least under
Log4j-1.2.x. However, there is some code out there that can help...
See the isConfigured() method at
http://wiki.apache.org/logging-log4j/UsefulCode
> Lastly, I don't have my
>source files explicitly sprinkled with logging calls--calls to logging are
>woven in by AspectJ after the fact; again, AFAICT, this shouldn't change
>semantics.
>
No, this should not matter in the least.
>I would like to KISS; but the S is relative :-)
>
Sure, but I think starting with logger.info() is pretty obviously more
simple than what you are trying to do. The point is, start simple. Add
complexity as needed. If you start complex and things don't work, how can
you pinpoint the cause of the failure?
>So, in summary, I'm glad "autoconfigure" works, and it's a starting point
>for me to get to where I want to go. But I'm still unclear why the setup I
>described below doesn't work. I'd be grateful for any insight.
>
If the only difference between the "working" version of your setup and the
non-working version is the use of autoconfiguration or not with absolutely
everything else exactly the same, then I would tend to suspect your
explicit configuration.
Jake
>Regards,
>
>--A
>
>
>> >I want its components, packed in separate jars, to use the same
>>logger(s),
>> >if possible. My configuration is shown below:
>> >
>> >j2ee web app
>> >=======
>> > webroot/
>> > WEB-INF/
>> > classes/
>> > log4jInitServlet (uses log4j props file)
>> > log4j.properties
>> > com.foo/ (classes in this package use logger)
>> >
>> >So far so good. I'm able to initialize a logger, and to log from any of
>>the
>> >classes in "classes/".
>> >
>> >Now, I want to use this already-initialized logger to log from classes
>> >deployed in jar files in WEB-INF/lib/ . Is this possible? Thus far my
>> >attempts have been unsuccessful.
>> >
>> >For example, I have a separate java project, whose classes reside in
>>package
>> >"com.bar", and which have been jar-ed and placed in WEB-INF/lib. One of
>> >those classes is something like this:
>> >
>> >package com.bar;
>> >
>> >import org.apache.log4j.*;
>> >
>> >class Bar {
>> > static Logger logger = Logger.getLogger(Bar.class.getName());
>> >
>> > public void getBar() {
>> > logMessage( "called getBar", Level.INFO);
>> > }
>> >
>> > private void logMessage(String msg, Level lvl) {
>> > if ( logger != null && logger.getAllAppenders().hasMoreElements()
>>)
>> > logger.log(lvl, msg);
>> > else
>> > System.out.println("sysout:" + msg + " : " + lvl.toString());
>> > }
>> >}
>> >
>> >The idea is that Bar provides some functionality to the webapp, and I
>>want
>> >calls to it logged. Again, though, I'd like Bar's logging to use the
>>same
>> >logger(s) already-initialised by the webapp. My props file is as below:
>> >
>> >log4j.rootLogger=ERROR, A1
>> >log4j.appender.A1=org.apache.log4j.ConsoleAppender
>> >log4j.appender.A1.layout=org.apache.log4j.PatternLayout
>> >
>> ># Set levels
>> >log4j.logger.com.foo=INFO
>> >log4j.logger.com.bar=DEBUG
>> >
>> >However, all log output from bar says "sysout", meaning it isn't using
>>the
>> >logger.
>
>_________________________________________________________________
>Express yourself instantly with MSN Messenger! Download today - it's FREE!
>http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: [EMAIL PROTECTED]
>For additional commands, e-mail: [EMAIL PROTECTED]
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]