log4j配置输出到数据库+自定义字段

时间:2023-03-09 19:41:54
log4j配置输出到数据库+自定义字段

Log4j.properties配置

log4j.rootLogger = info,stdout,D,E,A3

log4j.appender.Threshold=info

### 控制台输出###

log4j.appender.stdout = org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target = System.out

log4j.appender.stdout.layout = org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern = %d{yyyy MMM dd HH\:mm\:ss,SSS}%m%n

### DEBUG 文件保存至D://PDFPolling/Log/error.log ###

log4j.appender.D = org.apache.log4j.DailyRollingFileAppender

log4j.appender.D.File = D\://PDFPolling/Log/log.log

log4j.appender.D.Append = true

log4j.appender.D.Threshold = DEBUG

log4j.appender.D.layout = org.apache.log4j.PatternLayout

log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### ERROR 文件保存至 D://PDFPollingLog/error.log ###

log4j.appender.E = org.apache.log4j.DailyRollingFileAppender

log4j.appender.E.File =D://PDFPolling/Log/error.log

log4j.appender.E.Append = true

log4j.appender.E.Threshold = ERROR

log4j.appender.E.layout = org.apache.log4j.PatternLayout

log4j.appender.E.layout.ConversionPattern =%-d{yyyy-MM-dd HH\:mm\:ss}  [ %t\:%r ] - [ %p ]

###保存至数据库###2017.12.18注释掉  rootCategory 旧;rootLogger 新=rootCategory的子类

##定义输出sql语句到控制台,文件,数据库(仅供样式参考,实际由于输出info级别的,此处定义debug无法输出)

##log4j.rootCategory=ERROR,A3

log4j.logger.Java.sql.Connection=debug

log4j.logger.java.sql.Statement=debug

log4j.logger.java.sql.PreparedStatement=debug,stdout,D,E,A3

##定义sql语句输入到stdout控制台,DE文件,A3数据库,sql语句是debug级别的,而一开始定义的rootlogger是info级别的,所以这里其实定义不起什么作用;如果要sql语句输出到控制台,可以将rootlogger设置为debug级别输出

#定义A3输出到数据库

log4j.appender.A3=org.apache.log4j.jdbc.JDBCAppender

log4j.appender.A3.URL=jdbc\:sqlserver\://127.0.0.1\:53565;DatabaseName\=PDFP

log4j.appender.A3.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver

log4j.appender.A3.user=sa

log4j.appender.A3.password=000000

#定义A3的布局和执行的SQL语句

log4j.appender.A3.Append = true

log4j.appender.A3.Threshold = WARN

log4j.appender.A3.layout=org.apache.log4j.PatternLayout

log4j.appender.A3.layout.ConversionPattern=INSERT INTO

TPDFLOG(CREATEDATE,THREAD,GRADE,CLASS,MESSAGE,PID,CURRENTSTATE) values('%d','%t','%-5p','%c','%m','%X{pid}',%X{currentstate})

输出日志到数据库

注意,开头log4j.rootLogger = info,stdout,D,E,A3定义了输出info级别到stdout控制台,D,E日志文本,A3数据库,但是在定义输出到A3数据库时,又定义了:log4j.appender.A3.Threshold = WARN表示最低输出级别;

也就是说:开头一句定义了info级别以上的输出到A3,后来又特定对A3定义了最低输出级别为WARN,实际上只有WARN以上级别的日志才会输出给A3;可以理解为,rootlogger是一般性定义,而threshold是特定性定义,实际级别是输出2者重叠的部分!

在异常表里面自定义字段

如果想异常表与业务表关联起来,必须在异常表类添加与业务表关联的自定义字段;

INSERT INTO

TPDFLOG(CREATEDATE,THREAD,GRADE,CLASS,MESSAGE,PID,CURRENTSTATE) values('%d','%t','%-5p','%c','%m','%X{pid}',%X{currentstate})

注意,pid,和currentstate是要在日志在输入给数据库之前,必须先设置好,在logger.ERROR(“…”)之前:

MDC.put("pid", pid);

MDC.put("currentstate", 1);//1准备  2生成PDF 3上传 4归档

这里用到了MDC,一开始在MDC里面存入这2个自定义字段的值,之后当捕获到异常时,log4j根据级别准备执行上述sql语句以存储信息到数据库中对应的数据表,PID,CURRENTSTATE就是自定义的字段,sql语句中从MDC取值为'%X{pid}',%X{currentstate},前者string,后者Integer;

Ps:MESSAGE是当你在java中执行logger.ERROR(“相关信息”)时,ERROR括号中的部分,也就是’%m’, 其他的

'%d','%t','%-5p','%c'同理,log4j会自动取值;

因为sql语句中要从MDC中的自定义字段取值,所以当你logger.error准备存储日志给数据库之前,必须保证MDC

有对应的自定义字段的key-value,如果没有设置,那么在log4j存储到数据库时,会执行sql异常导致存储到数据库失败;