Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a Logger for a subclass?

I have a subclass and a superclass. In the superclass I have a method that logs something. When I create an instance of the subclass the logger creates a logging message for the super class. Why is this Happening?

Code example:

SuperClass.java

import java.util.logging.Level;
import java.util.logging.Logger;

public abstract class SuperClass {
    public void logAndPrintClass(){
        String name = this.getClass().getName();
        System.out.println(name);
        Logger logger = Logger.getLogger(name);
        logger.log(Level.INFO, "Logmessage");
    }
}

SubClass.java

public class SubClass extends SuperClass {
}

TestLogBubClass.java

public class TestLogBubClass {

    public static void main(String[] args){
        SuperClass obj = new SubClass();
        obj.logAndPrintClass();
    }
}

Output:

SubClass
Mar 15, 2013 6:30:04 PM SuperClass logAndPrintClass
INFO: Logmessage

As you can see the name of the class is correctly printed, but incorrectly represented in the log message.

like image 438
pieter Avatar asked Mar 15 '13 17:03

pieter


1 Answers

This reason is in the JavaDoc for LogRecord:

Note that if the client application has not specified an explicit source method name and source class name, then the LogRecord class will infer them automatically when they are first accessed (due to a call on getSourceMethodName or getSourceClassName) by analyzing the call stack.

The call stack in this case ends at a method defined by SuperClass, so the LogRecord assumes that it's the class being invoked. If you want to see this in action, execute this code:

public class Example {

    public static class Superclass {
        public void foo() {
            new Exception().printStackTrace();
        }
    }

    public static class Subclass extends Superclass {
        // nothing here
    }

    public static void main(String[] argv)
    throws Exception
    {
        Superclass s = new Subclass();
        s.foo();
    }
}

Edit: I don't use j.u.l, but was hoping that there would be an easy way to configure the output (like every other logger implementation provides). It appears that you'll have to implement your own Formatter class, and specify it using the java.util.logging.ConsoleHandler.formatter property.

I'd recommend if possible switching to SLF4J. You can bridge all existing j.u.l code through SLF4J to an actual logger that gives you more control over its output (like Log4J or Logback).

like image 92
parsifal Avatar answered Oct 26 '22 03:10

parsifal