如何将Log日志通过Hibernate保存到数据库中?
为了记录客户操作软件的轨迹,我想将客户的操作记录有选择的保存起来。(防止到时他死不认账 ),最好是永久的保存,所以就想到保存到用户数据库(可能是不太理想,会使用用户数据库变得很大)。本来程序中就用到了Log4j进行日志输入,但是只用到了文件和控制台两种方式,一查还真有保存到数据库中的Appender---JDBCAppender。可是它只能是通过JDBC连接向数据库插入语句,我的程序的所有和数据库打交道的都是Hibernate。总不能为了这个功能再单独搞个链接吧?不理想。
把JDBCApppender的源码下来,折腾一阵子。好象有点思路了。
主要是
extends org.apache.log4j.AppenderSkeleton
implements org.apache.log4j.Appender
然后实现org.apache.log4j.AppenderSkeleton这个抽象类中的三个方法就应该可以。
append(LoggingEvent event) //这个应该就是实际向Log中加入日志的方法了
void close() //关闭资源吧
boolean requiresLayout() //日志输出格式?
最终写了一个HiberanteAppender
packagecn.com.kylinsoft.platform.utils;
importjava.util.Calendar;
importorg.apache.log4j.spi.LoggingEvent;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
importcn.com.kylinsoft.platform.bean.OperateLog;
importcn.com.kylinsoft.platform.utils.hibernate.HibernateUtil;
publicclassHibernateAppenderextendsorg.apache.log4j.AppenderSkeleton
implementsorg.apache.log4j.Appender{
privateSessionsession=null;
/**
*执行保存数据库操作
*@paramoperateLog
*/
protectedvoidexecute(OperateLogoperateLog){
try{
session=HibernateUtil.getSession();
Transactiontx=session.beginTransaction();
session.saveOrUpdate(operateLog);
tx.commit();
}catch(Exceptione){
System.err.println("can`tsavelog"+e);
}finally{
if(session!=null)
session.close();
}
}
@Override
protectedvoidappend(LoggingEventevent){
OperateLoglog=newOperateLog();
log.setLogDate(Calendar.getInstance().getTime());
log.setMes(String.valueOf(event.getRenderedMessage()));
log.setStackTrace(event.getThrowableInformation()
+event.getThreadName());
execute(log);
}
@Override
publicvoidclose(){
this.closed=true;
}
@Override
publicbooleanrequiresLayout(){
returntrue;
}
}
importjava.util.Calendar;
importorg.apache.log4j.spi.LoggingEvent;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
importcn.com.kylinsoft.platform.bean.OperateLog;
importcn.com.kylinsoft.platform.utils.hibernate.HibernateUtil;
publicclassHibernateAppenderextendsorg.apache.log4j.AppenderSkeleton
implementsorg.apache.log4j.Appender{
privateSessionsession=null;
/**
*执行保存数据库操作
*@paramoperateLog
*/
protectedvoidexecute(OperateLogoperateLog){
try{
session=HibernateUtil.getSession();
Transactiontx=session.beginTransaction();
session.saveOrUpdate(operateLog);
tx.commit();
}catch(Exceptione){
System.err.println("can`tsavelog"+e);
}finally{
if(session!=null)
session.close();
}
}
@Override
protectedvoidappend(LoggingEventevent){
OperateLoglog=newOperateLog();
log.setLogDate(Calendar.getInstance().getTime());
log.setMes(String.valueOf(event.getRenderedMessage()));
log.setStackTrace(event.getThrowableInformation()
+event.getThreadName());
execute(log);
}
@Override
publicvoidclose(){
this.closed=true;
}
@Override
publicbooleanrequiresLayout(){
returntrue;
}
}
HibernateUtil是操作Hibernate的类。其中要有一个getSession方法,
还有一个OperateLog 类。这个就是和数据库对应的实体类了
packagecn.com.kylinsoft.platform.bean;
importjava.io.Serializable;
importjava.util.Date;
publicclassOperateLogimplementsSerializable{
privateIntegerid;
privateStringuserId;
privateStringmes;
privateDatelogDate;
privateStringstackTrace;
publicOperateLog(){
}
publicvoidsetLogDate(DatelogDate){
this.logDate=logDate;
}
publicDategetLogDate(){
returnlogDate;
}
publicIntegergetId(){
returnid;
}
publicvoidsetId(Integerid){
this.id=id;
}
publicStringgetMes(){
returnmes;
}
publicvoidsetMes(Stringmes){
this.mes=mes;
}
publicStringgetStackTrace(){
returnstackTrace;
}
publicvoidsetStackTrace(StringstackTrace){
this.stackTrace=stackTrace;
}
publicStringgetUserId(){
returnuserId;
}
publicvoidsetUserId(StringuserId){
this.userId=userId;
}
}
importjava.io.Serializable;
importjava.util.Date;
publicclassOperateLogimplementsSerializable{
privateIntegerid;
privateStringuserId;
privateStringmes;
privateDatelogDate;
privateStringstackTrace;
publicOperateLog(){
}
publicvoidsetLogDate(DatelogDate){
this.logDate=logDate;
}
publicDategetLogDate(){
returnlogDate;
}
publicIntegergetId(){
returnid;
}
publicvoidsetId(Integerid){
this.id=id;
}
publicStringgetMes(){
returnmes;
}
publicvoidsetMes(Stringmes){
this.mes=mes;
}
publicStringgetStackTrace(){
returnstackTrace;
}
publicvoidsetStackTrace(StringstackTrace){
this.stackTrace=stackTrace;
}
publicStringgetUserId(){
returnuserId;
}
publicvoidsetUserId(StringuserId){
this.userId=userId;
}
}
至于hbm.xml和数据库表的结构根据这个类就可以写出来了。
差点忘了Log4j.xml文件中加入这一段
<appendername="JDBC"class="cn.com.kylinsoft.platform.utils.HibernateAppender">
<!--这个Layout应该没有什么作用,因为存入数据库的格式是固定的-->
<layoutclass="org.apache.log4j.PatternLayout">
<paramname="ConversionPattern"
value="[%d{yyyy-MM-ddHH:mm:ss}]%c:[%-5p]%x-%m%n"/>
</layout>
</appender>
<!--这个Layout应该没有什么作用,因为存入数据库的格式是固定的-->
<layoutclass="org.apache.log4j.PatternLayout">
<paramname="ConversionPattern"
value="[%d{yyyy-MM-ddHH:mm:ss}]%c:[%-5p]%x-%m%n"/>
</layout>
</appender>
主要缺点:
1、日志的格式固定的,不能改变;
2、日志表的记录,如果太大就不好处理了,得想个办法在超过一定记录数后清除,或转存到其他的表中。
如果谁有好的方法解决上面的问题,请联系wfn_libo@163.com
本文地址:http://www.45fan.com/a/question/70984.html