2011-07-18 63 views
2

使用org.apache.log4j.jdbc.JDBCAppender,我怎樣才能得到記錄與warnerrorPatternLayout stracktraces。的Log4j JDBCAppender登錄蹤跡

我喜歡記錄

logger.warn("warning description", e); 
logger.error("error description", e); 

我得到的字符串描述到表中,但的Throwable的堆棧跟蹤是現在在哪裏。是否有另一個參數,我可以通過PatternLayout訪問。目前我使用

"INSERT INTO app_logs (app, log_date, log_level, location, loc, message) VALUES ('my-apps-name', '%d{ISO8601}','%p', '%C.java', '%C{1}.java:%L', '%m')" 

到表

TABLE `app_logs` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `app` varchar(255) DEFAULT NULL, 
    `log_date` varchar(255) DEFAULT NULL, 
    `log_level` varchar(255) DEFAULT NULL, 
    `location` varchar(255) DEFAULT NULL, 
    `loc` varchar(255) DEFAULT NULL, 
    `message` text, 
    PRIMARY KEY (`id`) 
) 

回答

11

我找到了解決辦法。

EnhancedPatternLayout類替換PatternLayout類。

org.apache.log4j.EnhancedPatternLayout

您還需要包括apache-log4j-extra dependency

或者include it in your pom

<dependency> 
    <groupId>log4j</groupId> 
    <artifactId>apache-log4j-extras</artifactId> 
    <version>1.1</version> 
</dependency> 

您現在可以訪問%拋出

%throwable{short}%throwable{1}將輸出f第一行堆棧 跟蹤。 throwable{none}throwable{0}將抑制堆棧跟蹤。 %throwable{n}將輸出n行堆棧跟蹤,如果一個正整數 或省略最後的-n行,如果一個負整數。

我加入到我的表,

TABLE `app_logs` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `app` varchar(255) DEFAULT NULL, 
    `log_date` varchar(255) DEFAULT NULL, 
    `log_level` varchar(255) DEFAULT NULL, 
    `location` varchar(255) DEFAULT NULL, 
    `loc` varchar(255) DEFAULT NULL, 
    `message` text, 
    `throwable` text, 
    `stacktrace` text, 
    PRIMARY KEY (`id`) 
) 

和更新,我的模式來填充這些列。

"INSERT INTO app_logs (app, log_date, log_level, location, loc, message, throwable, stacktrace) VALUES ('my-apps-name', '%d{ISO8601}','%p', '%C.java', '%C{1}.java:%L', '%m', '%throwable{short}', '%throwable{100}')" 
+0

這個解決方案工作正常,但隨後的堆棧跟蹤可能有逗號或單引號,我們必須消毒您應該重寫getLogStatement func的數據,如Sangeet Kumar在其答案之一中所示。 – Gaurav

+0

我知道這是一箇舊帖子。希望指出答案中的鏈接被破壞了。您能否更新鏈接以便對那些對此解決方案感興趣的人(如我)獲益? – Chiseled

+0

應該修復。 – MikeNereson

3

解決方案是我們需要使用EnhancedPattern Layout,通過使用它我們可以將整個堆棧跟蹤記錄到DB中。但有一個問題,如果我們使用這個如果堆棧跟蹤包含逗號(,),該消息不會得到logged.I有超過寫getLogStatement(),這是提供JDBC附加器源代碼

請按照下面的解決這個步驟

  1. 下載Log4j1.2.17。 增強的patternlayout可從log41.2獲得。16版本

  2. 編輯log4j屬性文件

    log4j.rootLogger = WARN, DB 
    log4j.appender.DB=abc.xyz.MyJdbcAppender 
    log4j.appender.DB.URL=jdbc:mysql://localhost/DBNAME 
    log4j.appender.DB.driver=com.mysql.jdbc.Driver 
    log4j.appender.DB.user=user_name 
    log4j.appender.DB.password=password 
    log4j.appender.DB.layout=org.apache.log4j.EnhancedPatternLayout 
    log4j.appender.DB.conversionPattern=Insert into MylogFile(logid,loglevel,logcriteria,message,stacktrace,date) values (mysequence.nextval,’%p’,’%c’, 
    ‘%m’,’%throwable{40},’%d{ABSOLUTE}’) 
    
  3. 現在創建一個新的類,將延長JDBCappender並覆蓋getLogStatement()

    Public MyJdbcAppender extends JDBCAppender{ 
    protected String getLogStatement(LoggingEvent event) { 
    if(null!=event.getThrowableInformation() && event.getThrowableInformation().getThrowable() instance of SQLException){ 
    SQLException myexce= new SQLException(event. 
    getThrowableInformation().getThrowable().getMessage(). 
    replaceAll(「’」,」 「),event.getThrowableInformation().getThrowable()); 
        LoggingEvent clone = new LoggingEvent(
        event.fqnOfCategoryClass, 
        LogManager.getLogger(event.getLoggerName()), 
        event.getLevel(), 
    event.getLevel(),event.getMessage(),myexce); 
    return getLayout().format(clone); 
    } 
    return getLayout().format(event) 
    } 
    } 
    
+0

您不需要將所有這些都放在代碼標籤中。 –

+0

@SangeetKumar你還可以找到你需要逃避''' – MikeNereson

2

的log4j 1.2.16+的EnhancedPatternLayout不工作!如果你使用JDBCAppender這樣

public void setSql(String s) { 
    sqlStatement = s; 
    if (getLayout() == null) { 
     this.setLayout(new PatternLayout(s)); 
    } 
    else { 
     ((PatternLayout)getLayout()).setConversionPattern(s); //Point1 
    } 
} 

所以:

log4j.appender.JDBC=org.apache.log4j.jdbc.JDBCAppender  
log4j.appender.JDBC.layout=org.apache.log4j.EnhancedPatternLayout 
log4j.appender.JDBC.sql=INSERT INTO email_send_error(insert_date, level, location, message, stacktrace) VALUES (now(), '%p', '%C,%L', '%m', '%throwable{short}') 

將拋出ClassCastException因爲它擴展org.apache.log4j.Layout而非org.apache.log4j.PatternLayout,但在JDBCAppender在點1:

產生的原因:java.lang.ClassCastException:org.apache.log4j.EnhancedPatternLayout不能轉換到org.apache.log4j.PatternLayout
在org.apa che.log4j.jdbc.JDBCAppender.setSql(JDBCAppender.java:330)



EDIT(經過深入研究):
使用log4j.appender.JDBC.layout.ConversionPattern而不是log4j.appender.JDBC.sql,將避免上述ClassCastException異常:

log4j.appender.JDBC.layout.ConversionPattern=INSERT INTO email_send_error(insert_date, level, location, message, stacktrace) VALUES (now(), '%p', '%C,%L', '%m', '%throwable{short}') 

,不要忘了扔異常記錄到日誌記錄器:

logger.error(String errorMsg, Throwabe e); // Dont forget e 
+0

只是說,如果你的解決方案上的log4j 1.2.16運行,在1.2.17它不運行... – sixro

3

要在MikeNereson的回答延伸,這裏是一個log4j.properties奏效:

log4j.rootLogger=DEBUG,DB 
log4j.appender.DB.driver=com.mysql.jdbc.Driver 
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender 
log4j.appender.DB.URL=jdbc:mysql://server/db 
log4j.appender.DB.user=user 
log4j.appender.DB.password=pwd 
log4j.appender.DB.layout.ConversionPattern=INSERT INTO app_logs (app, log_date, log_level, location, loc, message, throwable, stacktrace) VALUES ('appname', '%d{ISO8601}','%p', '%C.java', '%C{1}.java:%L', '%m', '%throwable{short}', '%throwable{100}') 
log4j.appender.DB.layout=org.apache.log4j.EnhancedPatternLayout 
log4j.category.ke.co=ERROR 
log4j.category.ke.co.appender-ref=DB 
+1

設置log4j.appender.DB。 layout = org.apache.log4j.EnhancedPatternLayout產生一個ClassCastException org.apache.log4j.EnhancedPatternLayout不能轉換爲org.apache.log4j.PatternLayout – sixro

+1

檢查你的Log4j版本。下載Log4j1.2.17 + – JStark