2008-10-17 26 views
15

是要一般使用的java.util.logging每類需要聲明一個像這樣的記錄:如何減少Java日誌模板代碼?

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

你如何避免這種MyClass.class.getName()樣板代碼?

+1

你應該把記錄器實例決賽。 – 2008-10-17 16:47:39

+0

我使用@Trace註釋來執行方法調用跟蹤,即記錄所有參數和結果/異常。有了這個庫:https://github.com/nicholas22/jpropel – 2011-10-09 10:16:50

回答

12

我有一個在Eclipse中設置的模板,因此我只需鍵入聲明的一部分,然後Eclipse將爲我自動完成其餘部分。

${:import(org.apache.log4j.Logger)} 
private final static Logger log = Logger.getLogger(${enclosing_type}.class); 
${cursor} 

所以,我只需要鍵入logger,打Ctrl+Space,其次是Enter和Eclipse的其餘填補了我,並增加了進口報關以及。

這不會減少樣板代碼的數量,但至少可以減少按鍵的數量。

2

如果您使用1.2 +版本的log4j,則不需要getName(),getLogger()接受Class參數。但至於其他方面,如果您希望每個班級都有一個具有自己類別的靜態日誌成員,則沒有任何方法。

+0

除了編寫一個getLogger類的getLogger接口並調用getName之外,還有其他方法嗎? – 2008-10-17 15:59:18

+0

你沒有編寫一個等價的方法,你使用log4j方法org.apache.log4j.Logger#getLogger(Class clazz),它自log4j 1.2以來就存在了。 – 2008-10-17 18:43:40

0

您可以簡化這一點,因爲getLogger重載也只是上課。像這樣:

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

記錄器可以像您想要的那樣隨意或不靈活。你可以爲每個類抓取一個新的記錄器,就像你上面的例子一樣,並且有一個記錄器層次結構,你可以通過類來控制和打開/關閉記錄。或者如果你的項目很小或者是一個原型等,你可以直接調用Logger.getRootLogger() - 但是你將失去微調你記錄和不記錄日誌的靈活性。你可以有一個基類,其中記錄生活,讓每個人都稱之爲一個,但同樣,你失去了一些靈活性:

public class MyBase { 
    protected static Logger _log = Logger.getLogger(MyClass.class); 
} 

public class MyClass extends MyBase { 
    .... 
    _log.info("Stuff...."); 
} 

底線,如果你想保持微調配置你的日誌的能力在後期的項目中(對於一個類開啓更精細的級別調試),那麼您可能需要在每個課程中都貼上樣板。

+0

您的基類正在使用錯誤的類創建記錄器。 但是,如果你修好了,子類是不是會記錄超類的記錄器? – davetron5000 2008-10-17 15:58:25

-1

如果使非靜態的記錄,至少可以繼承它:

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

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

這是我怎麼總是做了。

+0

不會記錄所有針對SomeBaseClass的消息嗎? – 2008-10-17 15:59:14

+0

不,getClass()將返回對象的運行時類 – 2008-10-17 16:45:16

2

如果你去包級記錄儀,增加每包一個樣板類的,你可以這樣寫:

private static final Logger log = Logs.log; 

有黑客讀取調用者的類名(事實上日誌實現有一個黑客來檢測當前的方法),但我不會建議。

3

根據您的需求記錄的文章,你可以創建一個靜態方法「LoggingService」類用於記錄各種「渠道」。我發現我真的不需要將日誌粒度降低到課程級別。您可以將您的記錄器命名爲每種最適合您的產品。我們已經在大型企業應用程序中使用了這個技術好幾年了,粒度對我們來說確實不是問題。

在靜態初始化塊初始化...因此,以記錄消息的日誌服務:

LoggingService.logError(「嗒嗒」);

每個班級都沒有樣板代碼。

下面是一個例子日誌服務:

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); 
} 

}

3

看看其實,使用類名的記錄器名稱的通常的做法是懶惰的比什麼都重要。

更好的做法是通過任務上下文命名記錄器。這涉及到更多的思考過程和計劃,但最終的結果是更加平均的粒度,您可以在其中切換實際任務而不是類的日誌記錄級別。

1

可以減少和其他許多樣板代碼與龍目島

https://github.com/rzwitserloot/lombok

@Slf4j 
    public class LogExample { 
} 

public class LogExample { 
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class); 
}