You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Ceki Gülcü <cg...@qos.ch> on 2001/04/21 23:02:52 UTC

Catalina and log4j

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. 

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.

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.

- 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.

- 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.

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



--
Ceki Gülcü


Re: Catalina and log4j

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Sat, 21 Apr 2001, Glenn Nielsen wrote:

> Ceki,
> 
> This is welcome news!
> 
> It isn't clear to me whether the standard servlet API logging methods
> could use log4j behind the scense to do logging.  This would be very
> nice, especially if you could configure log4j logging for each scope
> (Engine, Host, DefaultContext, Context) in server.xml. And even
> configure different destinations for different types of message
> levels.
> 

Whatever logging mechanism is used by
org.apache.catalina.core.ApplicationContext *is* the implementation of the
servlet API logging methods.  Right now, it defers to the Logger of the
corresponding Context, but that would be easy to change if we wanted to
forcibly separate application-generated messages from Catalina-generated
messages.

On the other hand, I've found that having the two message streams be
intermixed can be useful as well - it would be nice to have it either way.

> Regards,
> 
> Glenn
> 

Craig


Re: Catalina and log4j

Posted by Glenn Nielsen <gl...@voyager.apg.more.net>.
Ceki,

This is welcome news!

It isn't clear to me whether the standard servlet API logging methods could use log4j
behind the scense to do logging.  This would be very nice, especially if you could
configure log4j logging for each scope (Engine, Host, DefaultContext, Context) in
server.xml.
And even configure different destinations for different types of message levels.

Regards,

Glenn

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

-- 
----------------------------------------------------------------------
Glenn Nielsen             glenn@more.net | /* Spelin donut madder    |
MOREnet System Programming               |  * if iz ina coment.      |
Missouri Research and Education Network  |  */                       |
----------------------------------------------------------------------

Re: Catalina and log4j

Posted by Ceki Gülcü <cg...@qos.ch>.
At 21:40 21.04.2001 -0700, you wrote:


>On Sat, 21 Apr 2001, Glenn Nielsen wrote:
>
>> Ceki Gülcü wrote: 
>>
>>> One important point to remember is that each
>>> webapp classloader could load a fresh copy of log4j so that each
>>> webapp has its own logging universe. >
>> 
>> This would significantly increase the memory footprint required for
>> logging in the JVM. I would prefer that log4j be global.
>> 
>
>Log4J is nothing compared to having multiple XML parsers in memory :-)
>
>Actually, it is technically feasible to do this either way -- if you put
>the Log4J JAR file in common/lib instead of server/lib it becomes
>available to the webapps as well.  The disadvantage is that the static
>variables really are global instead of once per web app (which they would
>be if each webapp installed its own copy), so they would share the same
>set of Log4J categories, appenders, and so on.

One of the reasons for adding multiple-hierarchy support to log4j was to allow each webapp or virtual host to support logging independently of other webapps or virtual hosts. Given that each webapp has its own classloader AFAIK there is no need to use a custom hierarchy which is significantly more difficult to manage than the default hierarchy. So the support for multiple hierarchies is there but perhaps not needed, at least not for the logging done by the webapps.

Ceki


Re: Catalina and log4j

Posted by Glenn Nielsen <gl...@voyager.apg.more.net>.
"Craig R. McClanahan" wrote:
> 
> On Sat, 21 Apr 2001, Glenn Nielsen wrote:
> 
> > Ceki Gülcü wrote:
> >
> >> One important point to remember is that each
> >> webapp classloader could load a fresh copy of log4j so that each
> >> webapp has its own logging universe. >
> >
> > This would significantly increase the memory footprint required for
> > logging in the JVM. I would prefer that log4j be global.
> >
> 
> Log4J is nothing compared to having multiple XML parsers in memory :-)
> 
> Actually, it is technically feasible to do this either way -- if you put
> the Log4J JAR file in common/lib instead of server/lib it becomes
> available to the webapps as well.  The disadvantage is that the static
> variables really are global instead of once per web app (which they would
> be if each webapp installed its own copy), so they would share the same
> set of Log4J categories, appenders, and so on.
> 

Comments about per webapp vs global installation of jar's:

Tomcat 4 defers to the web application ClassLoader first before
loading classes from the parent classloaders, as suggested by the
Servlet 2.3 spec.  Bloating of JVM memory usage due to alot of 
web applications all having WEB-INF/lib/foo.jar installed could cause
a problem with scaling if there are 100's of web applications installed.

In our use of Tomcat 4 we will be installing all of the most commonly
used taglib jar files and API's in $CATALINA_HOME/lib so they can be shared by 
multiple web applications.  Of course the customer can always override
this by installing the jar file locally in WEB-INF/lib, but we will try
to encourage them to use the globally installed versions if they can.

Ideas for log4j:

log4j itself could be installed for Tomcat in $CATALINA_HOME/server/lib.

Logging categories, priorities, and destinations could be configured
in server.xml scoped at the Engine, Host, DefaultContext, and Context
levels.

The normal servletAPI log methods would use log4j under the hood.

The Tomcat 4 global log4j instance would not be visible to individual
web applications.

In addition, create a JNDI Factory for log4j so that a logging category
for a web application can be exported to it using a JNDI logging resource 
named something like "jndi:/comp/env/log".  That resource would only make 
available to the web application the few methods needed to determine if
a logging priority was enabled and to log a message at a priority.  This
would allow a web application to use log4j without making log4j internals
visible to the web application.

A manager servlet could even be written to allow changing of log priorities
for the web application.  And a tag library provided for use in JSP pages.

Regards,

Glenn

----------------------------------------------------------------------
Glenn Nielsen             glenn@more.net | /* Spelin donut madder    |
MOREnet System Programming               |  * if iz ina coment.      |
Missouri Research and Education Network  |  */                       |
----------------------------------------------------------------------

Re: Catalina and log4j

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Sat, 21 Apr 2001, Glenn Nielsen wrote:

> Ceki G�lc� wrote: 
>
>> One important point to remember is that each
>> webapp classloader could load a fresh copy of log4j so that each
>> webapp has its own logging universe. >
> 
> This would significantly increase the memory footprint required for
> logging in the JVM. I would prefer that log4j be global.
> 

Log4J is nothing compared to having multiple XML parsers in memory :-)

Actually, it is technically feasible to do this either way -- if you put
the Log4J JAR file in common/lib instead of server/lib it becomes
available to the webapps as well.  The disadvantage is that the static
variables really are global instead of once per web app (which they would
be if each webapp installed its own copy), so they would share the same
set of Log4J categories, appenders, and so on.

> Regards,
> 
> Glenn
> 

Craig McClanahan


Re: Catalina and log4j

Posted by Ceki Gülcü <cg...@qos.ch>.
At 23:04 21.04.2001 -0500, you wrote:
>Ceki Gülcü wrote:
>> 
>> 
>> One important point to remember is that each webapp classloader could load a fresh copy of log4j so that each webapp has its own logging universe.
>> 
>
>This would significantly increase the memory footprint required for logging in the JVM.
>I would prefer that log4j be global.

Right, but it is not our choice to make. The user (i.e. the servlet developer) *can* choose to load a fresh copy per webapp although this is not at all mandatory. It is the users prerogative, a bit like the XML parser I guess. 

Cheers, Ceki  


Re: Catalina and log4j

Posted by Glenn Nielsen <gl...@voyager.apg.more.net>.
Ceki Gülcü wrote:
> 
> 
> One important point to remember is that each webapp classloader could load a fresh copy of log4j so that each webapp has its own logging universe.
> 

This would significantly increase the memory footprint required for logging in the JVM.
I would prefer that log4j be global.

Regards,

Glenn

----------------------------------------------------------------------
Glenn Nielsen             glenn@more.net | /* Spelin donut madder    |
MOREnet System Programming               |  * if iz ina coment.      |
Missouri Research and Education Network  |  */                       |
----------------------------------------------------------------------

Re: Catalina and log4j

Posted by Ceki Gülcü <cg...@qos.ch>.
At 20:02 21.04.2001 -0700, you wrote:

>Since I had so shamelessly copied Craig's Services model out of Catalina to use it in another project that never made it, I actually have some experience with this.  I had really appreciated the logging in the Catalina framework, because it was always there, and it was configurable per component.  My cohort converted the whole thing to use Log4J in two days, and I was even happier after that.  We had started with the retrofitting solution, but it was easier in the end to define a standard way to get the Category, and then cut and paste that code everywhere we needed it.  So, I would say go for the whole hog, as it is not very hard ;-)
>
>I'd even offer to help ;-)

Excellent. 


Re: Catalina and log4j

Posted by Scott Sanders <sa...@totalsync.com>.
>> 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).
> 
> 
> My current impression is that this can be counter productive. It will probably require less effort to move to log4j in one step (assuming the step is well planned) than trying to retrofit log4j to the existing  logger. My intention was to prepare a solid migration plan and follow it through.
> 
> Come to think of it, the retrofitting solution would not be difficult but the result will probably not be very convincing. 
> 
> 

Since I had so shamelessly copied Craig's Services model out of Catalina 
to use it in another project that never made it, I actually have some 
experience with this.  I had really appreciated the logging in the 
Catalina framework, because it was always there, and it was configurable 
per component.  My cohort converted the whole thing to use Log4J in two 
days, and I was even happier after that.  We had started with the 
retrofitting solution, but it was easier in the end to define a standard 
way to get the Category, and then cut and paste that code everywhere we 
needed it.  So, I would say go for the whole hog, as it is not very hard 
;-)

I'd even offer to help ;-)


>> 
>> Categories are your friend.

+1!

Scott Sanders


Re: Catalina and log4j

Posted by Ceki Gülcü <cg...@qos.ch>.
At 15:51 21.04.2001 -0700, you wrote:


>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.

Sure.

>> 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)?

In log4j the fundamental notion is the named category hierarchy. A hierarchy is a tree of categories. This allows for a lot of flexibility with practically no pain. However, log4j also supports multiple hierarchies
organized as a forest, or independent hierarchy trees. This offers a new dimension of flexibility that the vast majority of applications do not need. Also, the additional flexibility comes at the cost of additional complexity. In a nutshell, each Tomcat context could have its own hierarchy, or in other words, its own logging universe. A priori, I would avoid using multiple hierarchies with the hope that we can get away with the single hierarchy approach. 

One important point to remember is that each webapp classloader could load a fresh copy of log4j so that each webapp has its own logging universe.

Let me stop here since I do not understand Tomcat well enough to present a clear-cut solution. 

>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).

My current impression is that this can be counter productive. It will probably require less effort to move to log4j in one step (assuming the step is well planned) than trying to retrofit log4j to the existing  logger. My intention was to prepare a solid migration plan and follow it through.

Come to think of it, the retrofitting solution would not be difficult but the result will probably not be very convincing. 

>> 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).

Sure. Scott already answered this one.

>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.

Right. This is all a bit vague. Let me study the Tomcat code some more (a lot more) and come back with a concrete proposal.  Regards, Ceki



Re: Catalina and log4j

Posted by Ceki Gülcü <cg...@qos.ch>.
At 17:45 21.04.2001 -0700, you wrote:
>My two cents as a Log4J User.
>
>I use Log4J in my servlets and I think it great. Logging has never been so easy.
>One issue though, the Configurator class holds it data in a Static variable so
>two servlets inside the same JVM will each over write the others config. Even
>since I implemented Log4J I was worried that my servlets may not play well
>with others when trying to deploy at an ISP. 

John,

As far as I know, the PropertyConfigurator and the DOMConfigurator do not hold any static info. You are free to use them as many times as you want. By default, the log4j configurators act on the default hierarchy although it is possible to specify a custom hierarchy. Having said that, if you configure the same hierarchy multiple times, then each reconfiguration will be merged with the existing configuration. This is known to confuse people but it offers real advantages.

If that is not the behavior that you desire, then you can call h.resetConfiguration(), for some hierarchy object h, before reconfiguring. Similarly, use Category.getDefaultHierarchy().resetConfiguration() for resetting the default hierarchy before reconfiguring.

>Also will you be able to support
>one Servlet using a PropertyConfigurastion as opposed to a XMLConfigurator.


Mixing configurators is not a problem.
 

>A word to the wise, one of our biggest hurdles was where or when to use each
>level. i.e. Debug,Info,warn.. It is easy to always use Info or Debug which defeats
>the purpose of separate levels. We had to create a standards document that defined
>where to implement each. It was surprising how often I need to look at the document
>to make the right choice.

Log4j has a rather limited set of priorities specifically to avoid the sort confusion you describe. One of the most important lessons I learned during my formal engineering education was to avoid functionality that could not be clearly understood by a competent audience. My hereto assumption was that DEBUG, INFO, WARN, ERROR and FATAL was the largest set of priorities with no possible confusion. You seem to think otherwise. I would be very interested in peeking at your standards document and perhaps include it in the log4j distribution with your permission of course.

TIA, Ceki




Re: Catalina and log4j

Posted by John Gentilin <ge...@eyecatching.com>.
My two cents as a Log4J User.

I use Log4J in my servlets and I think it great. Logging has never been so easy.
One issue though, the Configurator class holds it data in a Static variable so
two servlets inside the same JVM will each over write the others config. Even
since I implemented Log4J I was worried that my servlets may not play well
with others when trying to deploy at an ISP. Also will you be able to support
one Servlet using a PropertyConfigurastion as opposed to a XMLConfigurator.

A word to the wise, one of our biggest hurdles was where or when to use each
level. i.e. Debug,Info,warn.. It is easy to always use Info or Debug which defeats
the purpose of separate levels. We had to create a standards document that defined
where to implement each. It was surprising how often I need to look at the document
to make the right choice.

Regards
John G

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

--

--------------------------------------
John Gentilin
Eye Catching Solutions Inc.
18314 Carlwyn Drive
Castro Valley CA 94546

    Contact Info
gentijo@eyecatching.com
Phone 1-510-881-4821
--------------------------------------



Re: Catalina and log4j

Posted by Ceki Gülcü <cg...@qos.ch>.
At 16:37 21.04.2001 -0700, you wrote:


>On Sat, 21 Apr 2001, Scott Sanders wrote:
>
>> What he meant was:
>> 
>>    if(log.isDebugEnabled())
>>      log.debug("Processing " + errorPage);
>> 
>> ;-)
>
>I can certainly see that, but it sure blows the "shorter code" advantage
>that was touted :-).  It also seems a little redundant -- if I want to
>make this message happen at the "warning" level instead, do I need to
>change two things?
>
>  if (log.isEnabledFor(Priority.WARN))
>    log.warn("Processing " + errorPage);

There is no Category.isWarnEnabled method for two reasons. 

1) Warning or error log statements are invoked much less frequently than debug of info statements.

2) Warning and error statements are usually enabled.

>Performance of this is not really relevant for things that happen once
>(context startup) or only rarely (unusual exceptions).  It matters a lot
>on stuff that happens for every single request.  And I would submit that
>"if (debug >= x)" will run faster that any method call to double check
>whether a logging level is enabled or not.

Undeniably, simplicity has its merits. 


>Moral of the story -- let's be very careful in how we instrument the code
>with logging calls.

Indeed. Ceki



Re: Catalina and log4j

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Sat, 21 Apr 2001, Scott Sanders wrote:

> What he meant was:
> 
>    if(log.isDebugEnabled())
>      log.debug("Processing " + errorPage);
> 
> ;-)

I can certainly see that, but it sure blows the "shorter code" advantage
that was touted :-).  It also seems a little redundant -- if I want to
make this message happen at the "warning" level instead, do I need to
change two things?

  if (log.isEnabledFor(Priority.WARN))
    log.warn("Processing " + errorPage);

Performance of this is not really relevant for things that happen once
(context startup) or only rarely (unusual exceptions).  It matters a lot
on stuff that happens for every single request.  And I would submit that
"if (debug >= x)" will run faster that any method call to double check
whether a logging level is enabled or not.

Moral of the story -- let's be very careful in how we instrument the code
with logging calls.


> Scott Sanders
> 
> 

Craig


Re: Catalina and log4j

Posted by Scott Sanders <sa...@totalsync.com>.
>> - 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?

What he meant was:

   if(log.isDebugEnabled())
     log.debug("Processing " + errorPage);

;-)

Scott Sanders


Re: Catalina and log4j

Posted by "Craig R. McClanahan" <cr...@apache.org>.

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