Generic way of getLogger from log4j.Logger

别来无恙 提交于 2019-12-20 11:52:06

问题


Instead of specifying the class name on each class:

log = Logger.getLogger(Foo.class);
log = Logger.getLogger(Bar.class);
log = Logger.getLogger(Test.class);

Will it be OK to use :

log = Logger.getLogger(this.getClass());

What will be the implications?


回答1:


If you create a subclass, the log messages will get logged to the subclass's logger.

package pkgone;
public class SuperType {
    private Logger log = Logger.getLogger(this.getClass());
    public void someAction() {
        log.info("Doing something");
    }
}

.

package pkgtwo;
import pkgone.SuperType;
public class SubType extends SuperType {
    // for instances of SubType, the log object in SuperType
    // will get initialized with SubType's class object
}

.

// some code somewhere that uses SubType
SubType obj = new SubType();
obj.someAction();

In the above example, "Doing something" will get logged to the pkgtwo.SubType logger instead of pkgone.SuperType logger, which may or may not be what you want.




回答2:


Try this way to look up a generic class...

private static final Log LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass());

The best part is you can use this method statically.




回答3:


If you don't want to repeat to make the logger and want to avoid write a wrong class name, there's @Log of Project Lombok.

If you don't mind using one more library in your project, you can simply add a logger with a simple annotation.

import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;

@Log
public class LogExample {    
  public static void main(String... args) {
    log.error("Something's wrong here");
  }
}



回答4:


Sure that seems fine.

Be aware that one implication is that if you may have trouble using the log from a static context - It may not be initialized or it may not be visible




回答5:


+1 for sublass instances that call a super method, the logger will be the sub class.

Also if you are applying this as a logging template for your classes, if your class is abstract - your this.getClass will fail as you do not have an instance of this class.




回答6:


Using log factory from Apache commons:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;

public class SomeNewClass {
...
private final Log logger = LogFactory.getLog(this.getClass());
...
}

Don't have to do anything else. Not sure LogFactory was available at time of question post. If you don't want to use LogFactory you could also simply use private final with the getClass().

private final Logger log = Logger.getLogger(this.getClass()); 

No reason to create subclasses unless you want a heirarchy of your logging which could also be done with manipulation of the log configuration file (log4j.xml if that's what you are using). You just can't use this.getClass() when the logger is defined as static. Without static or private final you leave the logger open to dangerous possible changes which you don't want.




回答7:


public final class AppLogger {

private AppLogger() {
}


public static final void logInfo(Class<?> clazz, String logMessage) {
    Logger logger = Logger.getLogger(clazz);
    if (logger.isInfoEnabled()) {
        logger.info(logMessage);
    }
}

public static final void logInfo(Class<?> clazz, String logMessage, Throwable th) {
    Logger logger = Logger.getLogger(clazz);
    if (logger.isInfoEnabled()) {
        logger.info(logMessage, th);
    }
}

}

Create this class and then add this to your calling class. Applogger.logInfo(Class.class,String var);




回答8:


There is no implications as I know. As per Matt comment, I guess, thats the right behaviour which everyone wants it.



来源:https://stackoverflow.com/questions/10725402/generic-way-of-getlogger-from-log4j-logger

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!