使用org.apache.log4j.jdbc.JDBCAppender
,如何将warn
和error
的跟踪记录记录到PatternLayout
。
我正在记录
logger.warn("warning description", e);
logger.error("error description", e);
我将String描述放入表中,但是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`)
)
答案 0 :(得分:11)
我找到了解决方案。
将PatternLayout
类替换为EnhancedPatternLayout
类。
org.apache.log4j.EnhancedPatternLayout
您还需要添加apache-log4j-extra dependency
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId>
<version>1.1</version>
</dependency>
您现在可以访问%throwable
%throwable{short}
或%throwable{1}
将输出第一行堆栈 跟踪。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}')"
答案 1 :(得分:3)
解决方案是我们需要使用EnhancedPattern Layout,通过使用它,我们可以将整个堆栈跟踪记录到DB中。但是如果我们使用这个问题,如果Stacktrace包含逗号(,),则消息将不会被记录。我已经通过编写getLogStatement()来解决这个问题,这可以在JDBC appender中找到源代码
按照以下步骤
下载Log4j1.2.17。 增强的patternlayout可从log41.2.16 ver
编辑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()
:
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)
}
}
答案 2 :(得分: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
答案 3 :(得分:2)
log4j 1.2.16+的EnhancedPatternLayout不起作用!因为它扩展了org.apache.log4j.Layout而不是org.apache.log4j.PatternLayout,但是在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}')
将在Point1中抛出ClassCastException:
引起:java.lang.ClassCastException:org.apache.log4j.EnhancedPatternLayout无法强制转换为org.apache.log4j.PatternLayout
在org.apache.log4j.jdbc.JDBCAppender.setSql(JDBCAppender.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