That helps!  A few suggestions for the tomcat deployment:
- make using log4j easier (either offer a binary version of
tomcat-juli.jar that uses log4j - no source required since I can't build
locally due to some dbcp error;  alternatively it could use
common-logging's autodetect, if log4j is available on the path, use
it...)

- adapt the main log4j formatter (I'll see if I can do that, I'll submit
it here if it works)


  Thanks for the tutorial, Ole!


     []s Gus


 

-----Original Message-----
From: Ole Ersoy [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, June 25, 2008 10:21 AM
To: Tomcat Users List
Subject: [Logging] Tutorial Contribution

Hi,

Initially I was going to add to the WIKI FAQ, but all the Logging
questions are so inter related that I decided to write a tutorial
instead.  I have not "Tested" this so there may be some inaccuracies.
I'd appreciate feedback and will update the tutorial.  As soon as the
dust settles I'll post the end result on the WIKI.  Note that there's
also a couple of FAQs added at the end.

Here's the tutorial:



This document is provided "as is", without warranty of any kind, express
or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose and noninfringement. 
In no event shall the author be liable for any claim, damages or other
liability, whether in an action of contract, tort or otherwise, arising
from, out of or in connection with this document or the use or other
dealings in this document.

PRIMER ON java.util.logging and JULI 

The goal of this primer is to demonstrate how to to log with
java.util.logging (JULI) as a backdrop to the rest of the tutorial, in
particular the sections related to configuring Tomcat logging with the
configuration file.
One may think it's wise to skip this section and proceed directly to the
section on the configuration file, but all the concepts talked about
here and necessary to understand the configuration file.  The examples
used in this section show programmatically how logging is configured.
The section on Tomcat's configuration file discusses how to accomplish
declaratively what is done programmatically in this section.

The following concepts (Classes) are important:
- LogManager
- Loggers
- Handlers
- Levels
- Root Logger
- Root Handler

The official Tomcat logging documentation refers to these above concepts
/ classes extenstively.  

Lets start with Loggers.
What's the purpose of a Logger?  A Logger is what a developer uses to
write a log statements to the console, to a file, to the network, etc.
If you wanted to log something from your web application's class
CriticalComponent using java.util.logging you would first create a
logger like this:

private String nameOfLogger = 'com.example.myapp.CriticalComponent';
or
private String nameOfLogger = CriticalComponent.class.getName();

private static Logger myLogger = Logger.getLogger(nameOfLogger);

Pay attention to how we defined the name of the Logger.  This is
important to the material explaining Tomcat's logging configuration.
You may also want to think about why the myLogger is a static field
(Hint myLogger is shared among all instances of CriticalComponent).

Now you have a logger to create logging messages from you class
CriticalComponent.
For example you could now try something like this:

public void wasssup()
{
   myLogger.info("Ah Yeah Baby - that's the end of System.out.println");
}

If you ran this code with a deployed web application you would see this
statement on the console or in catalina.out out like:

INFO; 322125105255ms; 4407662;# 1; com.example.myapp.CriticalComponent;
wasssup; Ah Yeah Baby - that's the end of System.out.println

Notice that both the name of the Logger and the method that logged the
message are mentioned in the log statement.  This is important to know
when you want to alter the configuration of the Logger.  For example you
might want to turn this logger off, because it's not that useful.

What if you wanted the output to appear in a file and on the console?
For that you need to define a 2 Handlers.  Create the two like this:

Handler fileHandler = new FileHandler("/var/log/tomcat/myapp.log");
Handler consoleHandler = new ConsoleHandler();
myLogger.addHandler(fileHandler); myLogger.addHandler(consoleHandler);

Now myLogger will log to both the console and the file
/var/log/tomcat/myapp.log.

So now we understand Loggers and Handlers, but we have not touched on
Levels, Root Loggers, and Root Handlers yet.  What are those?

Lets start with a root Logger.  A root logger is a logger whose name is
"".
What's the purpose of it.  Suppose you tried to do some logging with
myLogger like this:

myLogger.finest("Sooooo Fine");

And nothing shows up in your log, but you know that this statement is
being called.  What's going on?  The answer is that the JULI root
logger's Level is set to INFO by default (TRUE?).  The level INFO has a
corresponding integer assigned to it, which is 3 (TRUE? - Comment: In
any case I'm just using it as an example which fits with the rest of the
tutorial...so the logic works out regardless).  
When myLogger attempts to log it first checks it's level.  If myLogger's
level is greater than the level intrinsic to the method doing the
logging (finest), then the record will be logged.  In this case the
logging method finest corresponds to Level zero.  Zero is less than 3,
hence the logger does not log the message.
My logger will only log messages with a level that is greater than or
equal to 3.  So for instance if myLogger.severe("Oohhh [EMAIL PROTECTED]") is
called, it will get logged because the level intrinsic to the method
severe is greater than 3.  So you are following this, but wondering how
myLogger's level got set to 3 (INFO), since we never explicitly set it.
The answer is that it comes the root Logger.  Now suppose you created
logger named 'com.example.myapp'
and set it's level.  Would myLogger still get it's level from the root
Logger.  It would not.
The reason is that the logger named 'com.example.myapp' is now a parent
logger to myLogger, and myLogger gets it's level from it instead.  How
did the 'com.example.myapp' Logger become a parent?
It's because of it's name 'com.example.myapp'.  If it were named
'org.charity.generous', it would not be a parent logger.  Do you see the
pattern (myLogger includes 'com.example.myapp'
in its name)?  

Now that we mulled that over you have an idea of what a level is as
well.  The Level determines what gets logged.  You can set the level
directly on myLogger like this:

myLogger.setLevel(Level.WARNING);

In this case only messages with a level of WARNING or SEVERE will get
logged by myLogger.

Now remember that once something gets logged by myLogger, it's handed
over to myLogger's Handlers.  But what if we never assigned any Handlers
to myLogger.  How would it get it's Handler?

The answer is the root Handlers.  The root logger has root Handlers.  So
if you don't explicitly define any Handlers for myLogger, it will use
the Handlers attached to the root Logger.  Now if you did attach
Handler(s) to the logger named 'com.example.myapp', but not to myLogger,
then myLogger would use the Handler(s) attached to 'com.example.myapp',
instead of the Handlers attached to the root Logger.  In other words
myLogger uses the Handlers of the closest Logger ancestor, which in this
case is either the 'com.example.myapp' 
Logger or the root Logger.

So all of the above is important to understand in order to be able to
configure Tomcat logging with JULI.  Now we can talk about doing so via
the configuration file.

CONFIGURING TOMCAT JULI

* Configuring Loggers

Suppose we wanted to configure myLogger via a logging.properties file,
rather than programmatically as we did earlier, and simply set it's
Level to SEVERE.  
We would put the following in the configuration file:

-------------------------------------------------------
com.example.myapp.CriticalComponent.level = SEVERE
-------------------------------------------------------

That's how Loggers are configured.  We specified the name of the Logger
followed by followed by a period followed by the name of the property we
wanted to set, which is 'level' in this case.  If we had several classes
with corresponding loggers, and we did not want to set the logging level
for each class individually, we could set the logging level on the root
Logger like this:
-------------------------------------------------------
.level = SEVERE
-------------------------------------------------------

This will set the level on all loggers to SEVERE, unless the Logger uses
a non-default level (Either programmatically or via configuration).

So if you wished to turn logging off all together simply configure the
root logger like this and make sure that there are no child loggers that
override this
setting:
.level = OFF

* Configuring Handlers

Suppose that we also wanted to add a Handler to the Logger named 
com.example.myapp.CriticalComponent.   

We could define our handler like this:  

handlers = org.apache.juli.FileHandler

And configure it like this:
org.apache.juli.FileHandler.level = WARNING
org.apache.juli.FileHandler.directory = /var/log/tomcat/
org.apache.juli.FileHandler.prefix = mywebapp

Then assign it to our Logger like this:

com.example.myapp.CriticalComponent.handlers =
org.apache.juli.FileHandler

Now we've done the same thing declaratively in our logging.properties
file that we did programmatically earlier.

What if we wanted to make the Handler we just configured the root
Handler?  We could configure it as the root Handler like this:
.handlers = org.apache.juli.FileHandler.

Now all Tomcat Loggers that do not have a Handler assigned to them
directly, either programmatically or declaratively via the
logging.properties file, will delegate to this Handler.

CONFIGURING CONTEXT LOGGERS
So you now had a look at the example logging.properties file in the
official documentation again, and you understand most of it.

Then you get to these lines:

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager]
.level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager]
.handlers = \
   3manager.org.apache.juli.FileHandler
   
These don't follow the same syntax we've been using thus far to
configure Loggers and Handlers.

These are for configuring Context loggers.  What's a context logger?
First you need to know
a little about the ServletContext.   

For a description of what a Servlet Context is see:
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletContext.html

You'll notice specifically that it mentions that there is one
ServletContext per webapp, and that this ServletContext can be used to
perform logging.

Looking down a little further in the ServletContext.html document we see
that the ServletContext has a log method that takes a String. 

If a developer working on the manager application were to use the
ServletContext.log method, without the corresponding configuration lines
shown above, output would go to standard out, and end up on the console
or catalina.out.  However now that the ServletContext Logger has been
configured for the manager application,
ServletContext.log("...") statements made within the /manager
application will end up in manager.dd.mm.yyy.log.



FAQ
------------------------------------------------------------------------
-
How do I customize the location of the tomcat logging.properies file?
------------------------------------------------------------------------
-
Set the following property when starting tomcat:

java.util.logging.config.file

Example:
-Djava.util.logging.config.file=/etc/tomcat/logging.properties

Note that this property is not set when running catalina.sh.

The reason for this is that the download provided by the Apache Tomcat
project
knows where the file is already.  

Projects such as JPackage that repackage Tomcat for Linux typically
move the configuration to a directory dictated by the FHS standard
(http://www.pathname.com/fhs/), and therefore use the
java.util.logging.config.file
property to set the location of the logging.properties file in the
Tomcat
startup script. 

------------------------------------------------------------------------
-
What role does commons-logging play in logging?
------------------------------------------------------------------------
-
Tomcat wants to support multiple logging implementations, so it uses
commons-logging.
In case that's unclear, think of it like this.  You are a Tomcat
developer.  The car
you drive when logging is the commons-logging car.  The engine of that
car is either
JULI or log4j.  Without one of these engines, the car goes no where.
However regardless
of whether you use JULI or log4j, the steering wheel, break, gas pedal,
etc. are the same. 

Related FAQ:
What role does JULI and log4j play in logging?


------------------------------------------------------------------------
-
What role does JULI and log4j play in logging?
------------------------------------------------------------------------
-
First see:
What role does commons-logging play in logging?

Note in addition that in your own applications you could log directly
with JULI or log4j.  But once you choose one, you can't easily switch
to the other later.  If you use commons-logging you can.


Ole

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to