Need help logging with java.util.logger

Discussion in 'Java' started by cteb, Sep 30, 2008.

  1. cteb

    cteb Guest

    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.
    cteb, Sep 30, 2008
    #1
    1. Advertising

  2. cteb

    Simon Guest

    > * 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
    Simon, Sep 30, 2008
    #2
    1. Advertising

  3. cteb

    cteb Guest

    Simon wrote:

    > 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).
    cteb, Oct 2, 2008
    #3
  4. cteb

    Simon Guest

    cteb wrote:
    > 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
    Simon, Oct 2, 2008
    #4
  5. cteb

    Arne Vajhøj Guest

    cteb wrote:
    > 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
    Arne Vajhøj, Oct 5, 2008
    #5
  6. Sabine Dinis Blochberger wrote:
    > cteb wrote:
    >> 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?!
    >>

    > 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
    Arne Vajhøj, Oct 5, 2008
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stefan Siegl
    Replies:
    0
    Views:
    941
    Stefan Siegl
    Aug 27, 2003
  2. janne
    Replies:
    0
    Views:
    9,448
    janne
    Sep 10, 2004
  3. CD1
    Replies:
    3
    Views:
    18,493
  4. Gugle
    Replies:
    3
    Views:
    1,221
    Gugle
    Dec 12, 2006
  5. Royan
    Replies:
    1
    Views:
    1,415
    Andrea Francia
    Apr 1, 2008
Loading...

Share This Page