Need help logging with java.util.logger

C

cteb

Hi all!

I'm trying to use java.util.logger (because it's already part of the
runtime library). I've read part of the API docs and the logging guide,
but I'm still in the dark on how to accomplish the following:

* In each of my application's classes I want to keep the logger setup to
a single line like this in class Foo:
private static final Logger log = Logger.getLogger(Foo.class.getName());
However, I can set up the logging subsystem elsewhere with all the
verbosity it needs.

* I want logging output to look like this:
YYYY-MM-DD HH:mm:SS --class--------- level message
2008-09-30 14:59:34 my.namespace.Foo INFO: something happened

* Those lines should be printed to stdout and into files, one file per
day, named YYYYMMDD.log in some directory I want to specify.

Can anyone show me how to set this up? I think I can go on reading docs
for hours and still not find a good example with this common
configuration. This can't be that hard?!

Thanks!
-- c.
 
S

Simon

* In each of my application's classes I want to keep the logger setup to
a single line like this in class Foo:
private static final Logger log = Logger.getLogger(Foo.class.getName());
However, I can set up the logging subsystem elsewhere with all the
verbosity it needs.

* I want logging output to look like this:
YYYY-MM-DD HH:mm:SS --class--------- level message
2008-09-30 14:59:34 my.namespace.Foo INFO: something happened

* Those lines should be printed to stdout and into files, one file per
day, named YYYYMMDD.log in some directory I want to specify.

Can anyone show me how to set this up? I think I can go on reading docs
for hours and still not find a good example with this common
configuration. This can't be that hard?!

Did you read the docs of LogManager also? Here is what I would suggest:

Subclass java.util.logging.Formatter to produce your desired output.

Create a file named, say "logging.properties" containing lines similar to the
following:

my.namespace.handlers = java.util.logging.FileHandler,\
java.util.logging.ConsoleHandler
my.namespace.level = MY_LEVEL
java.util.logging.FileHandler.pattern = PATH_TO_YOUR_LOGFILE
java.util.logging.FileHandler.level = MY_LEVEL
java.util.logging.FileHandler.formatter = your.fully.qualified.FormatterClass
java.util.logging.ConsoleHandler.level = MY_LEVEL
java.util.logging.ConsoleHandler.formatter = your.fully.qualified.FormatterClass

Then start your application with -Djava.util.logging.config.file=logging.properties.

This does not satisfy your one file per day requirement yet. To that end you
would have to subclass FileHandler also, but this should be easy.

Or follow any of the alternatives specified in the docs of LogManager.

Cheers,
Simon
 
C

cteb

Simon said:
This does not satisfy your one file per day requirement yet. To that end you
would have to subclass FileHandler also, but this should be easy.

Thanks for your help. However, I can't get my Formatter class to run. My
logging properties file is read (I left in an error by mistake and got
error messages on the console). Unfortunately, my formatter is never
used. The regular logging output is sent to the console (stderr instead
of stdout, for some reason; in Eclipse it's red now instead of black).
This is the current state of my properties file:

==
..handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
..level=INFO
java.util.logging.FileHandler.pattern=c:/log.txt
java.util.logging.FileHandler.level=INFO
java.util.logging.FileHandler.formatter=mynamespace.LogFormatter
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=mynamespace.LogFormatter
==

mynamespace.LogFormatter is my formatting class extending
java.util.logging.Formatter. It exists, there is no unnecessary
whitespace in the file (a common mistake I found out searching for
clues). I set a break point in my application in the format(LogRecord)
method which is never reached. I also tried mynamespace.handlers and
mynamespace.level in the properties file, but nothing changes as far as
I can see. My formatter never gets called, neither for my own classes
nor for others.

Besides, log.txt is created, contains XML (!) logging information and is
always deleted after the program terminates.

I have now spent several hours on this and have almost nothing to show
for it. Really frustrating. Any ideas?

BTW, this is a Tomcat application if it makes any difference.
Or follow any of the alternatives specified in the docs of LogManager.

I read
http://java.sun.com/j2se/1.5.0/docs/api/java/util/logging/LogManager.html
But it doesn't help me with my core problems (see above).
 
S

Simon

cteb said:
Thanks for your help. However, I can't get my Formatter class to run. My
logging properties file is read (I left in an error by mistake and got
error messages on the console). Unfortunately, my formatter is never
used. The regular logging output is sent to the console (stderr instead
of stdout, for some reason; in Eclipse it's red now instead of black).

This is as expected. Why would you expect log messages to go to stdout? stdout
should be used for the output or result of your program.
This is the current state of my properties file:

==
.handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
.level=INFO
java.util.logging.FileHandler.pattern=c:/log.txt
java.util.logging.FileHandler.level=INFO
java.util.logging.FileHandler.formatter=mynamespace.LogFormatter
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=mynamespace.LogFormatter
==

I'm afraid there was an error in the properties file I posted. .handlers should
be whitespace separated and not comma separated. I don't believe this is causing
your problems though since both the FileHandler and the ConsoleHandler are
created according to your description.
mynamespace.LogFormatter is my formatting class extending
java.util.logging.Formatter. It exists, there is no unnecessary
whitespace in the file (a common mistake I found out searching for
clues). I set a break point in my application in the format(LogRecord)
method which is never reached. I also tried mynamespace.handlers and
mynamespace.level in the properties file, but nothing changes as far as
I can see. My formatter never gets called, neither for my own classes
nor for others.

Is it constructed? Does it have a default constructor? Did you try
java.util.logging.SimpleFormatter instead?
Besides, log.txt is created, contains XML (!) logging information and is
always deleted after the program terminates.

No idea why this is happening. FileHandler typically deletes files only as a
result of file rotation.
I have now spent several hours on this and have almost nothing to show
for it. Really frustrating. Any ideas?

I just looked up how FileHandler obtains the formatter. It calls
LogManager.getFormatterProperty(). This is the code:

Formatter getFormatterProperty(String name, Formatter defaultValue) {
String val = getProperty(name);
try {
if (val != null) {
Class clz = ClassLoader.getSystemClassLoader().loadClass(val);
return (Formatter) clz.newInstance();
}
} catch (Exception ex) {
// We got one of a variety of exceptions in creating the
// class or creating an instance.
// Drop through.
}
// We got an exception. Return the defaultValue.
return defaultValue;
}

Did you see that? See the sophisticated exception handling? Well. I'm stunned.

My wild guess would be that the constructor of your Formatter throws an
exception resulting in an InvocationTargetException or
ExceptionInInitializerError in clz.newInstance(). Try to print something in the
first line of your constructor to stderr to see whether constructor is called at
all.

Otherwise I have no idea so far. Maybe post the code.
BTW, this is a Tomcat application if it makes any difference.

Don't know.

Cheers,
Simon
 
A

Arne Vajhøj

cteb said:
I'm trying to use java.util.logger (because it's already part of the
runtime library). I've read part of the API docs and the logging guide,
but I'm still in the dark on how to accomplish the following:

* In each of my application's classes I want to keep the logger setup to
a single line like this in class Foo:
private static final Logger log = Logger.getLogger(Foo.class.getName());
However, I can set up the logging subsystem elsewhere with all the
verbosity it needs.

* I want logging output to look like this:
YYYY-MM-DD HH:mm:SS --class--------- level message
2008-09-30 14:59:34 my.namespace.Foo INFO: something happened

* Those lines should be printed to stdout and into files, one file per
day, named YYYYMMDD.log in some directory I want to specify.

Can anyone show me how to set this up? I think I can go on reading docs
for hours and still not find a good example with this common
configuration. This can't be that hard?!

The following show an example of the custom format part.

package october;

import java.util.logging.Logger;

public class LogFun {
private static Logger log = Logger.getLogger(LogFun.class.getName());
public static void main(String[] args) {
log.info("I hope it works");
}
}

package october;

import java.util.logging.Formatter;
import java.util.logging.LogRecord;

public class CustomFormatter extends Formatter {
@Override
public String format(LogRecord rec) {
return String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %2$s
%3$s: %4$s",
rec.getMillis(), rec.getSourceClassName(),
rec.getLevel(), rec.getMessage());
}
}

october.LogFun.level = INFO
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = october.CustomFormatter

-Djava.util.logging.config.file=logging.properties

2008-10-04 22:16:58 october.LogFun INFO: I hope it works

Arne
 
A

Arne Vajhøj

Sabine said:
I'd encapsulate it in a class of my own and keep a static instance in
the main class of my application.

Not exactly how an extendable logging framework is supposed
to be used.

(but it may still be easier to implement !)

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,222
Members
46,810
Latest member
Kassie0918

Latest Threads

Top