Log4j JDBCAppender到日志堆栈跟踪

Log4j JDBCAppender到日志堆栈跟踪,jdbc,log4j,stack-trace,Jdbc,Log4j,Stack Trace,使用org.apache.log4j.jdbc.jdbcapender,如何将带有warn和error的stracktraces记录到模式布局中 我的日志记录得很好 logger.warn("warning description", e); logger.error("error description", e); 我将字符串描述放入表中,但是Throwable的stacktrace现在位于何处。是否还有另一个参数可以通过PatternLayout访问。目前我正在使用 "INSERT INT

使用
org.apache.log4j.jdbc.jdbcapender
,如何将带有
warn
error
的stracktraces记录到
模式布局中

我的日志记录得很好

logger.warn("warning description", e);
logger.error("error description", e);
我将字符串描述放入表中,但是Throwable的stacktrace现在位于何处。是否还有另一个参数可以通过
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`)
)
我找到了解决办法

模式布局
类替换为
增强模式布局

您还需要包括

或:

并更新了我的模式以填充这些列

"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}')"

解决方案是我们需要使用EnhancedPattern布局,通过使用它,我们可以将整个堆栈跟踪记录到DB中。但是如果我们使用它,如果Stacktrace包含逗号(,),消息将不会被记录。我已经通过过度编写getLogStatement()解决了这个问题,它在JDBC appender源代码中可用

遵循以下步骤

  • 下载。 增强的patternlayout可从log41.2.16版本获得

  • 编辑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}’)
    
  • 现在创建一个新类,该类将扩展JDBCappender并覆盖
    getLogStatement()


  • log4j 1.2.16+的增强模式布局不工作!因为它扩展了org.apache.log4j.Layout而不是org.apache.log4j.patternalyout,但在JDBCAppender中:

    public void setSql(String s) {
        sqlStatement = s;
        if (getLayout() == null) {
            this.setLayout(new PatternLayout(s));
        }
        else {
            ((PatternLayout)getLayout()).setConversionPattern(s);  //Point1
        }
    }
    
    因此,如果您像这样使用JDBCAppender:

    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}')
    
    将在点1中抛出ClassCastException:

    原因:java.lang.ClassCastException:org.apache.log4j.EnhancedPatternLayout无法强制转换为org.apache.log4j.PatternLayout
    位于org.apache.log4j.jdbc.jdbcapender.setSql(jdbcapender.java:330)



    编辑(经过深入研究):
    使用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
    

    为了扩展Mikeneeson的答案,这里有一个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
    

    @SangeetKumar您还将发现需要对设置log4j.appender.DB.layout=org.apache.log4j.EnhancedPatternLayout进行转义
    检查您的log4j版本。下载Log4j1.2.17+,就是说如果您的解决方案在Log4j1.2.16上运行,在1.2.17上,它没有运行…此解决方案工作正常,但堆栈跟踪可能有逗号或单引号,我们必须清理数据,您应该覆盖getLogStatement func,如Sangeet Kumar在这里的一个答案中所示。我知道这是一篇旧文章。我想指出答案中的链接断开了。你能为那些对这个解决方案感兴趣的人(比如我)更新链接吗?我不能从maven下载log4j额外依赖
     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
    
    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