logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Douglas E Wegscheid <Douglas_E_Wegsch...@whirlpool.com>
Subject Re: A default getLogger method
Date Tue, 27 Jan 2009 13:54:43 GMT
if you want parameterized messages, use slf4j ;)

--

Thread.currentThread() isn't there until Java 5 (though new Throwable
().getStackTrace() works fine on 1.4.2).

a more serious problem: it doesn't work if you call getLogger() from a 
method in a superclass, then instantiate a subclass of that superclass and 
do not override the method with the getLogger() class. The stack trace 
will show the superclass.

-- FakeLogger.java --

package org.wegscheid.traceback;

public class FakeLogger {
  public static FakeLogger getFakeLogger() {
    StackTraceElement[] stack = Thread.currentThread().getStackTrace();
    //stack = new Throwable().getStackTrace();
    for (int i = 0; i < stack.length; i++) {
      if (stack[i].getClassName().endsWith("FakeLogger")) {
        return new FakeLogger(stack[i+1].getClassName());
      }
    }
    return null;
  }
 
  String loggerName = null;
  public FakeLogger (String s) {
    super();
    loggerName = s;
  }
  public String toString () {
    return "FakeLogger:" + loggerName;
  }
  public void log(String s) {
    System.out.println(toString() + ": " + s);
  }
}

-- SuperClass.java --

package org.wegscheid.traceback;

public class SuperClass {
  public static void main (String[] args) {
    SuperClass t1 = new SuperClass();
    SuperClass.staticWhatClassAmI();
    t1.whatClassAmI();
    System.out.println ("these should be from SubClass...");
    SuperClass t2 = new SubClass();
    SubClass.staticWhatClassAmI();
    t2.whatClassAmI();
    System.out.println ("these should be from SuperClass...");
    SuperClass.staticWhatClassAmI();
    t1.whatClassAmI();
  }
 
  static FakeLogger fakeLogger = FakeLogger.getFakeLogger();
  static void staticWhatClassAmI() {
    fakeLogger.log("invoked from static method");
  }
 
  void whatClassAmI() {
    fakeLogger.log("invoked");
  }
 
  static class SubClass extends SuperClass {
  }
 
}

-- output from SuperClass.main() --

FakeLogger:org.wegscheid.traceback.SuperClass: invoked from static method
FakeLogger:org.wegscheid.traceback.SuperClass: invoked
these should be from SubClass...
FakeLogger:org.wegscheid.traceback.SuperClass: invoked from static method
FakeLogger:org.wegscheid.traceback.SuperClass: invoked
these should be from SuperClass...
FakeLogger:org.wegscheid.traceback.SuperClass: invoked from static method
FakeLogger:org.wegscheid.traceback.SuperClass: invoked

--

you can fix this by extra code in the subclass, but it's an easy thing to 
forget to do:

package org.wegscheid.traceback;

public class SuperClassFixed {
  public static void main (String[] args) {
    SuperClassFixed t1 = new SuperClassFixed();
    SuperClassFixed.staticWhatClassAmI();
    t1.whatClassAmI();
    System.out.println ("these should be from SubClass...");
    SuperClassFixed t2 = new SubClassFixed();
    SubClassFixed.staticWhatClassAmI();
    t2.whatClassAmI();
    System.out.println ("these should be from SuperClass...");
    SuperClassFixed.staticWhatClassAmI();
    t1.whatClassAmI();
  }
 
  static FakeLogger fakeLogger = FakeLogger.getFakeLogger();
 
  static void staticWhatClassAmI() {
    fakeLogger.log("invoked from static method");
  }
 
  void whatClassAmI() {
    fakeLogger.log("invoked");
  }
 
  static class SubClassFixed extends SuperClassFixed {
    static {
      fakeLogger = FakeLogger.getFakeLogger(SubClassFixed.class);
    }
  }
 
}

-- output from SuperClassFixed.main() --

FakeLogger:org.wegscheid.traceback.SuperClassFixed: invoked from static 
method
FakeLogger:org.wegscheid.traceback.SuperClassFixed: invoked
these should be from SubClass...
FakeLogger:org.wegscheid.traceback.SuperClassFixed$SubClassFixed: invoked 
from static method
FakeLogger:org.wegscheid.traceback.SuperClassFixed$SubClassFixed: invoked
these should be from SuperClass...
FakeLogger:org.wegscheid.traceback.SuperClassFixed$SubClassFixed: invoked 
from static method
FakeLogger:org.wegscheid.traceback.SuperClassFixed$SubClassFixed: invoked

-- 

but now the 2nd set of logging calls for t1 are showing the wrong class... 



 if you set the logger in the subclass, you screw up the superclass' 
logger (static class variables are shared with subclasses, yes?). static 
loggers in a subclass/superclass situation are messy, I haven't been able 
to figure out a good way to do static loggers in that siutation. Any 
ideas?

Douglas E Wegscheid
Lead Technical Analyst, Whirlpool Corporation
(269)-923-5278

"A wrong note played hesitatingly is a wrong note. A wrong note played 
with conviction is interpretation."

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message