看到某个项目中的代码:
...
log.info("华夏***明细查询");
dataRcdService.saveLog(HxStr,"华夏***明细查询");
...
log.error("农行用户" + abcXyNo + "详情查询异常", e);
dataRcdService.saveLog(AbcStr,"农行用户" + abcXyNo + "详情查询异常:" + e.getMessage());
...
public void saveLog(String name, String content) {
LogRecord lr = new LogRecord();
lr.setName(name);
lr.setContent(content);
logRcdRepo.save(lr);
}
每次都要两行代码好丑啊,于是决定优化一下。
一开始想要使用aop的方式记录日志,但是有些关键信息的数据没法获取,这样就没意义了。
于是使用log4j配置数据库的方式来实现(logback也有实现方式,但是项目用的是log4j),如下:
int result = hxErpCheckRepo...; //一大堆处理
bkLog.info("query results count:>>> " + result);
bkLog.info能够在控制台打印(保存到服务器)并且记录到表。
1.log4j.properties
假定项目已经配置好log4j,增加记录数据库的配置
# 日志保存到oracle
#定义子logger,指定BankLog4j类下的log存到数据库,这样调用BankLog4j就能保存了
log4j.logger.org.zhd.bank.adaptor.utils.BankLog4j=INFO, jdbc
#输出配置
log4j.appender.jdbc=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.jdbc.threshold=info
log4j.appender.jdbc.URL=jdbc:oracle:thin:@***:1521/orcl
log4j.appender.jdbc.driver=oracle.jdbc.driver.OracleDriver
log4j.appender.jdbc.user=username
log4j.appender.jdbc.password=password
log4j.appender.jdbc.sql=insert into log_record(id,create_at,update_at,name,content) values(LOG_RECORD_SEQ.Nextval,sysdate, sysdate,'%X{name}','%X{content}')
log4j.appender.jdbc.layout=org.apache.log4j.PatternLayout
log4j.appender.jdbc.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %l - %m%n
LOG_RECORD_SEQ.Nextval就是取得下一个自增id
%X{name}定义会打印MDC里面key为name的值
2.封装的log类
public class BankLog4j {
private String name;
Logger logger= Logger.getLogger(BankLog4j.class);
public static BankLog4j getInstance(){
return new BankLog4j();
}
public void info(String content){
MDC.put("name",name);
MDC.put("content",content);
logger.info(">>>" + content);
}
public void error(String content, Throwable e){
MDC.put("name",name);
MDC.put("content",content);
if (e == null) logger.error(">>>" + content);
else logger.error(">>>" + content, e);
}
}
3.修改LogRecord
之前使用的是Table策略,不指名表,所以默认会生成一个hibernate_sequences表,然后id从中自动获取,但是这样的话log4j.appender.jdbc.sql就有问题了,他需要能够自增的id,所以修改为sequence策略
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
改为:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_sequence")
@SequenceGenerator(name = "id_sequence", initialValue = 1, allocationSize = 1, sequenceName = "LOG_RECORD_SEQ")
private Long id;
需要新建sequence
create sequence LOG_RECORD_SEQ
minvalue 1
maxvalue 9999999999999999999999999999
start with 1
increment by 1
cache 20;
4.在需要的地方使用bkLog
private Logger log = Logger.getLogger(ScheduleService.class);
private BankLog4j bkLog = BankLog4j.getInstance();
...
bkLog.error("农行用户" + abcXyNo + "详情查询异常:" + e.getMessage(), e);