On Sat, 21 Apr 2001, Ceki [iso-8859-1] Gülcü wrote:

> 
> Hello,
> 
> I am toying with the idea of migrating catalina logging to log4j. Let
> me begin by saying that I am far from being familiar with catalina
> internals but I am getting there slowly.
> 
> After a short initial study and some experimentation, here are some
> tentative conclusions:
> 
> 1) The way logging is done currently in catalina is not optimal or, in
> plain English, sucks. Like most project using their own logging API,
> there are real benefits in using a more specialized package like log4j
> instead of the home-brewed solution. More on this below.
> 

:-)

IMHO the logging API in Catalina has always been a placeholder for a
"real" one.  Prior to Log4J becoming an Apache project, I had been
assuming that the "real" one would be the outcome of the "Standard Java
Logging API" JSR.

At the moment, I'm +1 on using Log4J for Tomcat 4.0 logging, but we should
talk through some of the details first.

> 2) Since catalina uses its own class loader, it would be possible to
> have catalina use log4j for logging without affecting other parts of
> Tomcat. This is probably not entirely true since Tomcat uses a logging
> hierarchy. I'll ignore this issue for the time being until I
> understand the implications. More importantly, existing servelets
> using log4j will be unaffected because they will be using a
> classloader in a different branch of the cl-tree.
> 

The hierarchy is important, and becomes more so as the number of virtual
hosts and/or webapps scales up.  But you are correct about the class
loading implications -- any use of Log4J inside Catalina (that is, loaded
from "$CATALINA_HOME/server/classes" or "$CATALINA_HOME/server/lib/*.jar")
is totally transparent to web apps.

Consider an ISP installation -- are you going to force individual
customers to use different logger categories to ensure that their messages
do not get intermixed, or are you going to let each customer have an
entire logging "universe" of their own (and "customer" can be at either
the virtual host or the webapp level)?

One fairly simple way to integrate Log4J would be to write an
implementation of org.apache.catalina.Logger that uses it.  This will
undoubtedly not suffice for a final solution, because it does not expose
all of the logging flexibility that Log4J provides.  But it might serve as
a starting point for experimentation (and learning how we might deal with
the hierarchy as well as configuration from bean properties so that
server.xml parsing does it for you automatically).

> Benefits of the move to log4j would be:
> 
> - No more need to do
> 
>   if(debug > 1)
>     log("Some message");
> 
> instead one would write
> 
>   log.debug("Some message");
> 
> where log is an instance of org.apache.log4j.Category.
> 

Although not evident in your example above, there is a potentially
substantial performance penalty for changing to this approach for some
kinds of messages.

Consider the following simple case (taken from StandardWrapperValve):

        if (debug >=1)
            log("Processing " + errorPage);

If that is changed as Ceki suggests:

        log.debug("Processing " + errorPage);

then the string concatenation in this expression is done every single
time, whether you decide to log the result or not.  In the current code,
the expression is only evaluated if you have turned debugging on
(presumably that means you are not concerned about performance impacts
when you are debugging).

How do Log4J users deal with this kind of thing?

> - No more need to have a log() method in each catelina class, as in
> 
>    private static void log(String message) {
>         System.out.print("Bootstrap: ");
>         System.out.println(message);
>     }
> 
> in Bootstrap.java. Log4j would use the category name to identify the
> source of the log statement.
> 
> -  Instead of
> 
>        try {
>       } catch (IOException e) {
>           System.out.println("Cannot create URL for " +
>                               filenames[i]);
>            e.printStackTrace(System.out);
>       }
> 
> one would write
> 
>      try {
>       } catch (IOException e) {
>           log.error("Cannot create URL for " + filenames[i], e);
>       }
> 
> One advantage is that the code becomes shorter. More importantly, the
> error can be reported to any defined log4j appender attached to "log"
> category instance not just to System.out.
> 

Categories are your friend.

> - The user would configure logging in Tomcat using a separate
> configuration file, simplifying the actual Tomcat configuration. I am
> assuming that the DTD for sevlet.xml is not part of the Servlet spec
> so it can be modified without fear of contradicting the spec.
> 

In fact, there is no such thing as a DTD for server.xml because there
cannot be -- the set of elements and attributes is extensible.  But
dealing with hierarchical logging still needs to be addressed, and some
mechanism to configure Log4J loggers within server.xml seems like it might
be feasible.

> Anyway, I am still studying the problem but it looks pretty
> encouraging for the moment. Your comments are welcome. Ceki
>      
> 
> 
> 
> --
> Ceki Gülcü
> 
> 

Craig


Reply via email to