How do you reduce Java logging boilerplate code?

2019-03-11 03:10发布

Every class that wants to use java.util.logging generally needs to declare a logger like this:

public class MyClass {
    private static Logger _log = Logger.getLogger(MyClass.class.getName());
}

How do you avoid this MyClass.class.getName() boilerplate code?

标签: java logging
10条回答
Deceive 欺骗
2楼-- · 2019-03-11 03:16

Have a look at using point cuts in your code

I have not looked back since using them with spring.

Here is an article on using AspectJ

http://www.developer.com/java/other/article.php/3109831

查看更多
在下西门庆
3楼-- · 2019-03-11 03:16

If you go for package-level loggers, with the addition of a boilerplate class per package, you can write:

private static final Logger log = Logs.log;

There are hacks to read the class name of the caller (in fact the logging implementation has a hack to detect the current method), but I wouldn't recommend that.

查看更多
萌系小妹纸
4楼-- · 2019-03-11 03:18

Depending on your logging needs, you could create a "LoggingService" class with static methods for logging to various "channels". I have found that I really don't need logging granularity down to the class level. You can name your loggers what every works best for you. We have been using this in large, enterprise applications for several years and the granularity has really not been an issue for us.

The logging service initialized in a static initializer block...so to log a message:

LoggingService.logError("blah");

No boilerplate code in each class.

Here is an example logging service:

public class LoggingService {

/**
 * A log for informational messages.
 */
static private Logger infoLog;

/**
 * A log for data access messages.
 */
static private Logger dataAccessLog;

/**
 * A log for debug messages.
 */
static private Logger debugLog;

/**
 * A log for error messages.
 */
static private Logger errorLog;

/**
 * A log for all XML related messages.
 */
static private Logger xmlLog;

/**
 * A log for all trace messages.
 */
static private Logger traceLog;

/**
 * A log for all warning messages.
 */
static private Logger warnLog;

static {

    //This is the bootstrap for the logging service.
    //Setup each logger
    infoLog = Logger.getLogger("com.company.logging.info");
    dataAccessLog = Logger.getLogger("com.company.logging.dataaccess");
    debugLog = Logger.getLogger("com.company.logging.debug");
    errorLog = Logger.getLogger("com.company.logging.error");
    xmlLog = Logger.getLogger("com.company.logging.xml");
    traceLog = Logger.getLogger("com.company.logging.trace");
    warnLog = Logger.getLogger("com.company.logging.warn");

    // This must be set so isErrorEnabled() will work.
    errorLog.setLevel(Level.ERROR);
    warnLog.setLevel(Level.WARN);
}
static public void logDataAccess(String pMessage) {
    dataAccessLog.info(pMessage);
}

static public void logInfo(String pMessage) {
    infoLog.info(pMessage);
}

static public void logDebug(String pMessage) {
    debugLog.debug(pMessage);
}

static public void logTrace(String pMessage) {
    traceLog.debug(pMessage);
}

static public void logWarn(String pMessage) {
    warnLog.warn(pMessage);
}

static public void logError(String pMessage) {
    errorLog.error(pMessage);
}

static public void logError(String pMessage, Throwable pThrowable) {
    errorLog.error(pMessage, pThrowable);
}

static public void logXml(String pMessage, XmlBean pContainer) {

    if (!xmlLog.isInfoEnabled()) return;

    xmlLog.info(pMessage + " : " + JAXBHelper.marshal(pContainer));
}

static public boolean isInfoEnabled() {
    return infoLog.isInfoEnabled();
}

static public boolean isDataAccessEnabled() {
    return dataAccessLog.isInfoEnabled();
}

static public boolean isDebugEnabled() {
    return debugLog.isDebugEnabled();
}

static public boolean isErrorEnabled() {
    if (errorLog.getLevel().toInt() >= Level.ERROR_INT) {
        return true;
    }
    return false;
}

static public boolean isTraceEnabled() {
    return traceLog.isDebugEnabled();
}

static public boolean isXmlEnabled() {
    return xmlLog.isInfoEnabled();
}

static public boolean isWarnEnabled() {
    return warnLog.isEnabledFor(Level.WARN);
}

}

查看更多
成全新的幸福
5楼-- · 2019-03-11 03:24

Take a look at SLF4J

查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-03-11 03:25

Actually, the common practice of using class names for logger names is lazy more than anything.

The much better practice is to name loggers by the task context. This involves somewhat more thought process and planning but in the end, the result is much more meanigful granularity, where you can toggle logging levels for actual tasks rather than classes.

查看更多
够拽才男人
7楼-- · 2019-03-11 03:25

If you make the logger nonstatic, you can at least inherit it:

public class SomeBaseClass
{
    protected Logger logger = Logger.getLogger(getClass());
}

public class SubClass extends SomeBaseClass
{
    public void doit() { logger.debug("doit!!!!"); }
}

That's how I've always done it.

查看更多
登录 后发表回答