commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <craig...@apache.org>
Subject Re: [CLI] new design possibly?
Date Fri, 07 Feb 2003 23:19:26 GMT


On Fri, 7 Feb 2003, Nicola Ken Barozzi wrote:

> Date: Fri, 07 Feb 2003 23:03:00 +0100
> From: Nicola Ken Barozzi <nicolaken@apache.org>
> Reply-To: Jakarta Commons Developers List <commons-dev@jakarta.apache.org>
> To: commons-dev@jakarta.apache.org
> Subject: Re: [CLI] new design possibly?
>
>
>
> Craig R. McClanahan wrote, On 07/02/2003 22.45:
> >
> > On Fri, 7 Feb 2003, Nicola Ken Barozzi wrote:
> >
> >
> >>Date: Fri, 07 Feb 2003 22:28:24 +0100
> >>From: Nicola Ken Barozzi <nicolaken@apache.org>
> >>Reply-To: Jakarta Commons Developers List <commons-dev@jakarta.apache.org>
> >>To: commons-dev@jakarta.apache.org
> >>Subject: Re: [CLI] new design possibly?
> >>
> >>
> >>Craig R. McClanahan wrote, On 07/02/2003 18.23:
> >>
> >>>On Fri, 7 Feb 2003, Nicola Ken Barozzi wrote:
> >>>
> >>>>Looks like an AOP-like system to intercept all logs of a package could
> >>>>help, but I'm lost here.
> >>>>
> >>>If you implement your own LogFactory, this is pretty straightforward,
> >>>since it is your LogFactory instance that creates all the Log instances
> >>>(even those declared static).
> >>
> >>What if other packages decide to make their factory? Can I somehow be
> >>sure that I'm the top one deciding things?
> >
> > Ultimately, the person deploying the application makes an explicit choice
> > of which factory class wins.  You could, I suppose, design a log factory
> > that was itself a wrapper around an arbitrary other LogFactory
> > implementation -- if so, you'd configure both the choice of your wrapper
> > as the "official" factory for commons-logging to use, and how it kwnows
> > what other factory should be wrapped.
>
> Ok, so it all comes down to how I configure it right?
>

Yes.

> >>Also, what about different classloaders. Would a single LogFactory work
> >>with all of them?
> >
> > That's a really important question, especially in things like a servlet
> > container.  The current implementation of LogFactory.getFactory()
> > configures a LogFactory instance per class loader.  It also has support
> > for using the thread context class loader to make this determination,
> > instead of the class loader used to load commons-logging itself.  This
> > makes things work nicely in an environment like Tomcat, where you can have
> > the API classes (commons-logging-api.jar) in a shared parent class loader,
> > yet allow each app (loaded by a separate child class loader) configure its
> > own LogFactory and logging configuration.
>
> How are they configured? (excuse my ignorance)
>

Do you mean "how does a webapp configure it's own usage of
commons-logging"?  That's typically done by supplying a
commons-logging.properties in /WEB-INF/classes, or in a JAR file inside
/WEB-INF/lib (either of which makes it visible to the webapp class
loader).  The discovery mechanisms in LogFactory are very carefully
crafted to make this work in a way that allows for independent
configuration at the per-class-loader level.

> >>Just trying to understand better.
> >>
> >>
> >>>I once had to integrate some libraries using commons-logging into an app
> >>>that wanted to funnel log messages into logs (in the underlying
> >>>environment) with different names than those used by the calling packages.
> >>>This was accomplished by a trivially simple LogFactory implementation that
> >>>performed the log name mapping and delegated to the existing impl for the
> >>>work of actually creating the instance.
> >>>
> >>>The same approach would work (for example) to return a Log instance that
> >>>was decorated AOP-style with extra functionality.
> >>
> >>Hmmm, seems cool.
> >>
> >>
> >>>No, it's not the strict IOC pattern that Avaloners really like.  But
> >>>there's more than one useful design pattern in the world, and the factory
> >>>create pattern is pretty popular too :-).
> >>
> >>Yes, and speaking personally (not too loud ;-) I use it too with things
> >>that are not coarse-grained components.
> >
> > :-)
> >
> >>Is simply does not make sense to
> >>micromanage every logger and handle it to all children IMHO.
> >
> > One of the things I like about the way commons-logging is commonly used
> > today (declaring an instance or static variable per-using-class) is that
> > you *don't* have to configure anything, or remember to call setLogger() to
> > avoid NPEs.  It "just works" (tm), automatically adapting to how you've
> > configured commons-logging, with no per-object configuration required.
>
> Sometimes it's just to easy though, and you get more logging that you
> would want.

That's where you leave the realm of commons-logging and go configure the
underlying logger's logging levels.  The most commonly used
implementations like Log4J and JDK 1.4 logging have the notion of
hierarchical level setting, so that you can pick and choose which things
you are interested in.

For example, I develop a Struts-based app (the framework itself uses
commons-logging, as well as other commons packages that do to).  Normally,
I've got the following settings in my JDK 1.4 logging configuration file:

    org.apache.commons.level = INFO
    org.apache.struts.level = INFO

but if I want to investigate a particular issue with the PropertyUtils
class, I can change it to:

    org.apache.commons.level = INFO
    ort.apache.commons.beanutils.PropertyUtils.level = FINEST
    org.apache.struts.level = INFO

and get just those messages.  I think LogKit has this notion as well,
doesn't it?

In no case did I have to do anything to modify the code that is actually
USING commons-logging.  As we discussed earlier, I can even lump all the
log messages into the same Log instance (for example), by providing a
custom LogFactory that returned a singleton Log instance to all users,
again without modifying the code that uses it (or even having a setLog()
method.

>
> The bottom line is that I want to be sure in an easy way that no logging
> is performed, unless requested.
>

If you do no configuration at all, the default LogFactory implementation
used to default to a NoOpLog logger that simply threw everything away.  It
turns out, though, that most commons-logging users aren't like you in this
preference :-) -- they wanted logging turned on by default, writing to
System.err at an INFO level of detail, so that's the current default
behavior if you don't configure anything.

To turn off logging entirely, just configure
org.apache.commons.logging.impl.NoOpLog as the default Log implementation
class.

> logging.properties has caused headaches to many, I'm wondering if it's
> the right thing/way to pursue.
>

It seems to work pretty well in the environment that I'm the most
interested in (multiple webapps in a servlet container).  It's also the
way Ceki chose to configure Log4J, and lots of other packages seem to find
it usable.

Craig

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message