`

【转】 Log4j写入数据库详解

阅读更多

 log4j是一个优秀的开源日志记录项目,我们不仅可以对输出的日志的格式自定义,还可以自己定义日志输出的目的地,比如:屏幕,文本文件,数据库,甚至能通过socket输出。本节主要讲述如何将日志信息输入到数据库(可以插入任何数据库,在此主要以MSSQL为例进行详解)。
用log4j将日志写入数据库主要用到是log4j包下的JDBCAppender类,它提供了将日志信息异步写入数据的功能,我们可以直接使用这个类将我们的日志信息写入数据库;也可以扩展JDBCAppender类,就是将JDBCAppender类作为基类。下面将通过一个实例来讲解log4j是如何将日志信息写入数据库的。
我们的需求:我们在软件开发的过程中需要将调试信息、操作信息等记录下来,以便后面的审计,这些日志信息包括用户ID、用户姓名、操作类、路径、方法、操作时间、日志信息。
设计思想:我们采用JDBCAppender类直接将日志信息插入数据库,所有只需要在配置文件配置此类就可以;要获得用户信息需要用过滤器来实现;(假如不需要用户的信息,就不需要设计过滤器,其实大部分情况下都是需要这些用户信息,尤其是在web应用开发中)在日志信息中获得用户信息,就的通过过滤器的request或session对象,从session中拿到用户信息怎样传到log4j呢,log4j为我们提供了MDC(MDC是log4j种非常有用类,它们用于存储应用程序的上下文信息(context infomation),从而便于在log中使用这些上下文信息。MDC内部使用了类似map的机制来存储信息,上下文信息也是每个线程独立地储存,所不同的是信息都是以它们的key值存储在”map”中。相对应的方法,

MDC.put(key, value); MDC.remove(key); MDC.get(key);

在配置PatternLayout的时候使用:%x{key}来输出对应的value)。有了MDC,我们可以在过滤器中先获得用户信息,再用MDC.Put(“key”)方法,log在执行sql语句时通过%x{key}来输出对应的value


实现步骤:
1、在你的项目中要确保有log4j和commons-logging这两个jar文件;
2、设置要你要插入日志信息的表结构

 

[javascript] view plaincopy
  1. if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[WDZLOG]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)  
  2. drop table [dbo].[WDZLOG]  
  3. GO  
  4.   
  5. CREATE TABLE [dbo].[WDZLOG] (  
  6.     [WDZLOGID] [int] IDENTITY (1, 1) NOT NULL ,  
  7.     [LogName] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,//用户ID  
  8.     [UserName] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,//用户姓名  
  9.     [Class] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,//类名  
  10.     [Mothod] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL //,方法名  
  11.     [CreateTime] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL ,//产生时间  
  12.     [LogLevel] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,//日志级别  
  13.     [MSG] [varchar] (555) COLLATE Chinese_PRC_CI_AS NULL //日志信息  
  14. ) ON [PRIMARY]  
  15. GO  

 

 

3、配置文件(摘自我们的项目)后面将对此配置文件进行详细讲解,它也log4j的核心部分。

[c-sharp] view plaincopy
  1. log4j.properties  
  2. log4j.rootLogger=INFO,stdout  
  3.               
  4. log4j.logger.org.springframework.web.servlet=INFO,db  
  5.   
  6. log4j.logger.org.springframework.beans.factory.xml=INFO  
  7. log4j.logger.com.neam.stum.user=INFO,db  
  8.   
  9. log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
  10. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
  11. log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p [%c] - - <%m>%n  
  12.   
  13. log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender  
  14. log4j.appender.logfile.File=${webapp.root}/WEB-INF/logs/exppower.log  
  15. log4j.appender.logfile.DatePattern=.yyyy-MM-dd  
  16. log4j.appender.logfile.layout=org.apache.log4j.PatternLayout  
  17. log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] wang- <%m>%n  
  18.  
  19. ########################  
  20.  
  21. # JDBC Appender  
  22.  
  23. #######################  
  24.  
  25.  
  26. #log4j.logger.business=INFO,db  
  27. #log4j.appender.db=com.neam.commons.MyJDBCAppender  
  28. log4j.appender.db=JDBCExtAppender  
  29.   
  30. log4j.appender.db.BufferSize=10  
  31.   
  32. log4j.appender.db.sqlname=log  
  33.   
  34. log4j.appender.db.driver=net.sourceforge.jtds.jdbc.Driver  
  35.                         
  36. log4j.appender.db.URL=jdbc:jtds:SqlServer://localhost:1433;DatabaseName=pubs  
  37.   
  38. log4j.appender.db.user=sa  
  39.   
  40. log4j.appender.db.password=sa  
  41.   
  42. log4j.appender.db.sql=insert into WDZLOG (LogName,UserName,Class,Mothod,createTime,LogLevel,MSG) values ('%X{userId}','%X{userName}','%C','%M','%d{yyyy-MM-dd HH:mm:ss}','%p','%m')  
  43.   
  44. log4j.appender.db.layout=org.apache.log4j.PatternLayout  

 

 

4、编写过滤器(ResFilter.java)

[java] view plaincopy
  1. import java.io.IOException;  
  2. import javax.servlet.Filter;  
  3. import javax.servlet.FilterChain;  
  4. import javax.servlet.FilterConfig;  
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.ServletRequest;  
  7. import javax.servlet.ServletResponse;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpSession;  
  10.   
  11. import org.apache.log4j.Logger;  
  12. import org.apache.log4j.MDC;  
  13.   
  14. import com.neam.domain.User;  
  15.   
  16. public class ResFilter implements Filter{  
  17.   
  18.        
  19.     private final static double DEFAULT_USERID= Math.random()*100000.0;    
  20.   
  21.     public void destroy() {  
  22.     }  
  23.   
  24.     public void doFilter(ServletRequest request, ServletResponse response,  
  25.            FilterChain chain) throws IOException, ServletException {  
  26.        HttpServletRequest req=(HttpServletRequest)request;  
  27.         HttpSession session= req.getSession();  
  28.         if (session==null){  
  29.             MDC.put("userId",DEFAULT_USERID);    
  30.         }  
  31.         else{  
  32.             User customer=(User)session.getAttribute("user");  
  33.             if (customer==null){  
  34.                 MDC.put("userId",DEFAULT_USERID);  
  35.                 MDC.put("userName",DEFAULT_USERID);  
  36.             }  
  37.             else  
  38.             {  
  39.                 MDC.put("userId",customer.getName());  
  40.                 MDC.put("userName",customer.getName());  
  41.             }  
  42.         }  
  43.         //logger.info("test for MDC.");  
  44.   
  45.        chain.doFilter(request, response);  
  46.     }  
  47.     public void init(FilterConfig Config) throws ServletException {  
  48. //     this.filterConfig = Config;  
  49. //     String ccc = Config.getServletContext().getInitParameter("cherset");  
  50. //     this.targetEncoding = Config.getInitParameter("cherset");  
  51.   
  52.     }  
  53. }  

 

 

5、在需要写入日志的地方引入

 

[java] view plaincopy
  1. private Log logger = LogFactory.getLog(this.getClass());  
  2.   
  3. 在具体方法中就可以写入日志  
  4. logger.info("");  
  5. logger.debug("");  
  6. logger.warn("");  
  7. logger.error("");  

 

 

 

 

配置文件详解:
log4j.properties
log4j.properties
log4j.rootLogger=INFO,stdout


//配置根Logger,其语法为:
log4j.rootLogger = [ level ] , appenderName1, appenderName2, …
level : 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。
appenderName:就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。
例如:log4j.rootLogger=info,A1,B2,C3 配置了3个输出地方我们可以设置让A1在控制台输出;B2生产日志文件;C3让日志信息插入数据库中。
本例中是将所有的日志信息在控制台打印出来。 
log4j.logger.org.springframework.web.servlet=INFO,db
//设置将spring下包的某些类的日志信息写入数据库中,并且在控制台上打印出来。(是通过log4j.rootLogger=INFO,stdout来体现的)db是将日志信息写入数据库中
log4j.logger.org.springframework.beans.factory.xml=INFO
//本实例中为了让某些包下的日志信息能写入数据库
log4j.logger.com.neam.stum.user=INFO,db
//设置自己某个模块下的日志信息既在控制台上打印而且往数据库中保存

//下面是配置在控制台上打印日志信息,在这里就不再仔细描述了
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p [%c] - - <%m>%n

//下面是配置将日志信息写入文件中,在这里也就不再仔细描述了
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.File=${webapp.root}/WEB-INF/logs/exppower.log
log4j.appender.logfile.DatePattern=.yyyy-MM-dd
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] wang- <%m>%n

########################

# JDBC Appender

#######################


#log4j.appender.db=com.neam.commons.MyJDBCAppender
//下面是配置将日志信息插入数据库,
log4j.appender.db=org.apache.log4j.jdbc.JDBCAppender
//配置输出目标为数据库(假如要将日志在控制台输出,配置为log4j.appender. stdout =org.apache.log4j.ConsoleAppender;将日志写入文件,配置为log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
这样的配置在许多地方都要有,需要可查有关资料),当然你也可以自己扩展org.apache.log4j.jdbc.JDBCAppender这个类,只需要在这里配置就可以了例如我们配置我自己扩展的MyJDBCAppender,配置为#log4j.appender.db=com.neam.commons.MyJDBCAppender

log4j.appender.db.BufferSize=10
//设置缓存大小,就是当有10条日志信息是才忘数据库插一次

log4j.appender.db.driver=net.sourceforge.jtds.jdbc.Driver
//设置要将日志插入到数据库的驱动                     
log4j.appender.db.URL=jdbc:jtds:SqlServer://localhost:1433;DatabaseName=pubs

log4j.appender.db.user=sa

log4j.appender.db.password=sa

log4j.appender.db.sql=insert into WDZLOG (LogName,UserName,Class,Mothod,createTime,LogLevel,MSG) values ('%X{userId}','%X{userName}','%C','%M','%d{yyyy-MM-dd HH:mm:ss}','%p','%m')
//设置要插入日志信息的格式和内容,%X{userId}是置取MDC中的key值,因为我们在过滤器中是将用户id和用户姓名放入MDC中,所有在这里可以用%X{userId}和%X{userName}取出用户的ID和用户姓名;'%C'表示日志信息是来自于那个类;%M表示日志信息来自于那个方法中;%d{yyyy-MM-dd HH:mm:ss}表示日志信息产生的时间,{yyyy-MM-dd HH:mm:ss}表示一种时间格式,你也可以直接写成%d;%p表示日志信息的级别(debug info warn error);
%m表示你写入的日志信息
log4j.appender.db.layout=org.apache.log4j.PatternLayout

 

分享到:
评论

相关推荐

    Log4j写入数据库详解

    log4j是一个优秀的开源日志记录项目,我们不仅可以对输出的日志的格式自定义,还可以自己定义日志输出的目的地,比如:屏幕,文本文件,数据库,甚至能通过socket输出。本节主要讲述如何将日志信息输入到数据库...

    Sybase数据库ASE事务日志的管理技巧详解

    Server Cache Memory中日志页总是先写于数据页:Log pages在commit ,checkpoint,space needed时写入硬盘。Data pages在checkpoint,space needed时写入硬盘。 系统在recovery时读每个database的syslogs表的信息,回退...

    详解MySQL数据库设置主从同步的方法

     1、主服务器(master)将变更事件(更新、删除、表结构改变等等)写入二进制日志(master log)。  2、从服务器(slave)的IO线程从主服务器(binlog dump线程)获取二进制日志,并在本地保存一份自己的二进制日志(relay ...

    oracle详解

    exp userid=test/test file=yw97_2003.dmp log=yw97_2003_3.log feedback=10000 buffer=100000000 tables=WO4,OK_YT 4.FILE和LOG,这两个参数分别指定备份的DMP名称和LOG名称,包括文件名和目录,例子见上面。 5....

    详解MySQL实现主从复制过程

    Binary log:主数据库的二进制日志 Relay log:从服务器的中继日志 第一步:master在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中。 第二步:salve开启一个I/O Thread,该线程在master打开一个...

    MySQL六大日志详解

    分别是:重做日志(redo log)、回滚日志(undo log)、二进制日志(binlog)、错误日志(errorlog)、慢查询日志(slow query log)、一般查询日志(general log),中继日志(relay log)。 其中 重做日志和回滚...

    详解监听MySQL的binlog日志工具分析:Canal

    Canal是阿里巴巴旗下的...MySQL master启动binlog机制,将数据变更写入二进制日志(binary log, 其中记录叫做二进制日志事件binary log events,可以通过show binlog events进行查看)MySQL slave(I/O thread)将mast

    Mysql Binlog数据查看的方法详解

    改变数据库的SQL语句执行结束时,将在binlog的末尾写入一条记录,同时通知语句解析器,语句执行完毕. binlog格式 基于语句,无法保证所有语句都在从库执行成功,比如update … limit 1; 基于行,将每一次改动记为binlog中...

    jpivot学习总结.doc

    4. JPivot标签库使用详解 4.1. Introduce JPivot 是一套基于 Mondrian 的 OLAP 前端展现工具,它提供了一套标签库来解决的 OLAP 的展现层问题。 在一个 JSP 页面当中,如果要使用 JPivot 标签库,除了要配置相关的...

    MongoDB安装及安装过程中出现问题解决

    好比你安装了个老婆,是不是还要装饰下,默认装饰是放在系统盘内,so,我们要在mongodb安装目录下创建两个文件( 数据库路径目录:data 和 日志路径目录:logs,logs文件中要创建一个日志文件mongo.log)和一个配置文件...

    黑马程序员 安卓学院 万元哥项目经理 分享220个代码实例

    |--动画Animation详解 |--动画之view左右抖动 |--动画之移动动画 |--动画之组合动画 |--动画之缩放动画ScaleAnimation |--反序列化对象 |--发送短信 读天气 调音量 |--回调函数的定义 |--图片之BitMap、Drawable、...

    mysql(master/slave)主从复制原理及配置图文详解

    主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从...

    MySQL5.7.18主从复制搭建(一主一从)教程详解

    主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新.当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从...

    java 编写文件上传类简单易用

    二、各过程详解 A)填写表单并提交 通过表单提交数据的方法有两种,一种是 GET 方法,另一种是 POST 方法,前者通常用于提交少量的数据,而在上传文件或大量数据时,应该选用 POST 方法。在 HTML 代码中,在 &lt;...

    cmd操作命令和linux命令大全收集

    4. explorer-------打开资源管理器 5. logoff---------注销命令 6. shutdown-------60秒倒计时关机命令 7. lusrmgr.msc----本机用户和组 8. services.msc---本地服务设置 9. oobe/msoobe /a----检查XP是否激活 ...

Global site tag (gtag.js) - Google Analytics