`
bnmnba
  • 浏览: 288187 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

用log4j向数据库写日志

 
阅读更多

 

Log4j写入数据库详解原文:http://blog.csdn.net/ziruobing/article/details/3919501

 

文章内容:

 

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、设置要你要插入日志信息的表结构

 

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

3、配置文件(摘自我们的项目)后面将对此配置文件进行详细讲解,它也log4j的核心部分。(请注意:数据库连接相关的属性值后面能有空格

 

 

log4j.properties  
log4j.rootLogger=INFO,stdout  
              
log4j.logger.org.springframework.web.servlet=INFO,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.logger.business=INFO,db
#log4j.appender.db=com.neam.commons.MyJDBCAppender
log4j.appender.db=org.apache.log4j.jdbc.JDBCAppender
  
log4j.appender.db.BufferSize=10
  
#log4j.appender.db.sqlname=log
  
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')  
  
log4j.appender.db.layout=org.apache.log4j.PatternLayout
 

 

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

 

import java.io.IOException;  
import javax.servlet.Filter;  
import javax.servlet.FilterChain;  
import javax.servlet.FilterConfig;  
import javax.servlet.ServletException;  
import javax.servlet.ServletRequest;  
import javax.servlet.ServletResponse;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpSession;  
  
import org.apache.log4j.Logger;  
import org.apache.log4j.MDC;  
  
import com.neam.domain.User;  
  
public class ResFilter implements Filter{  
  
       
    private final static double DEFAULT_USERID= Math.random()*100000.0;    
  
    public void destroy() {  
    }  
  
    public void doFilter(ServletRequest request, ServletResponse response,  
           FilterChain chain) throws IOException, ServletException {  
       HttpServletRequest req=(HttpServletRequest)request;  
        HttpSession session= req.getSession();  
        if (session==null){  
            MDC.put("userId",DEFAULT_USERID);    
        }  
        else{  
            User customer=(User)session.getAttribute("user");  
            if (customer==null){  
                MDC.put("userId",DEFAULT_USERID);  
                MDC.put("userName",DEFAULT_USERID);  
            }  
            else  
            {  
                MDC.put("userId",customer.getName());  
                MDC.put("userName",customer.getName());  
            }  
        }  
        //logger.info("test for MDC.");  
  
       chain.doFilter(request, response);  
    }  
    public void init(FilterConfig Config) throws ServletException {  
//     this.filterConfig = Config;  
//     String ccc = Config.getServletContext().getInitParameter("cherset");  
//     this.targetEncoding = Config.getInitParameter("cherset");  
  
    }  
}  
 

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

 

 

private Log logger = LogFactory.getLog(this.getClass());  
  
在具体方法中就可以写入日志  
logger.info("");  
logger.debug("");  
logger.warn("");  
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添加日志记录到数据库和文件中,log4j提供了非常强大的日志记录功能,为了弄这代码我整整研究了两天,访问时直接在地址栏输入日志添加的action就可以,没有写页面。

    log4j使用实战

    log4j推荐和slf4j一起用,关于log4j和slf4j, 参考:https://blog.csdn.net/haoranhaoshi/article/details/89929470上半部分。 log4j.appender.File.File=${user.dir}/logs/hmiservice.log ${user.dir}可以得到当前...

    实现Log4j连接池

    log4j功能强大,但是将日志写入数据库,感觉其性能相当差,究其原因是:log4j在每写一次日志的时候都建立和释放一个数据库连接,系统的性能消耗在频繁建立昂贵的连接上。本例简单的实现Log4j连接池,一起学习,...

    PB下文件日志/数据库日志功能(源码)

    PB下文件日志/数据库日志功能,类似java的log4j功能,作用就不说了,见识过log4j功能的人应该都深有体会。 功能模块化,调用简单。

    log4pb, pb的日志组件, 后台线程记录日志

    log4pb调用演示例子, 思想仿log4j // 2. 集成对象到application, // 3. 组件文件: log4pb90.pdb + callback.pbd, // 4. SQL目录包含一些数据库对象,目前支持postgresql和MS SQL(修改下表log4pb_log可支持其他...

    log4j properties总结篇

    对log4j的一个总结,写的很不错,很全,包括把日志写入到控制台,文件,数据库,Socket等等

    SpringBoot Logback日志记录到数据库的实现方法

    主要介绍了SpringBoot Logback日志记录到数据库的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    Nodejs Express 通过log4js写日志到Logstash(ELK)

    Log4j 是一个使用 Java 语言编写的,可靠、快速、灵活的日志框架(API),使用 Apache Software License 授权。它被移植到 C、C++、C#、Perl、Python、Ruby 和 Eiffel 语言中。 Log4j 是高度可配置的,在运行期使用...

    lombok-plugin.zip

    我们在写数据库表的映射类的时候,需要写很多的getter/setter方法,我们可以使用Lombok这个jar包中的注解来简化开发。 @Data : 注解在类上, 为类提供读写属性, 此外还提供了 equals()、hashCode()、toString() 方法 ...

    Druid jar 阿里数据库

    包含了druid官方druid-1.0.4.jar druid-1.0.4-javadoc.jar ...4) SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。

    2014-09-18-AOP_LOG4J

    写这个日志的框架的主要想法是,先前在开发的时候logger都是到处都有不便于管理,于是想到了利用AOP加注解的方式统一管理,异常主要分为业务异常和系统异常, 业务异常应该由程序员在写业务的时候在可能发生业务异常...

    springMVC+mongoDB基础项目框架

    1、这个项目是 springMVC+mongoDB,用的 mongoTemplate 做和数据库的链接, 日志用的log4j 2、项目中集成了 完整的单元测试,和基本的添加和查询,具体的api可以查看mongoTemplate 的api 3、经过单元测试添加和查询...

    Druid是一个JDBC组件,它包括三部分 高效可管理的数据库连接池.rar

    4) SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid...

    SpringBoot前后端分离 - 预约挂号系统

    - 日志技术:Log4j - 数据库连接池:druid - 前端技术:LayUI, axios,Echarts,Ztree 等 - Web容器:Apache Tomcat 9 - 项目管理工具:Maven3.6 - 思维导图设计工具:XMIND 8 - 开发工具: IDEA2020, WebStorm2020 -...

    一款后台管理系统和门户网站的源码和数据库及架构说明文件

    技术选型: 后端 核心框架:Spring Framework 4.2.5.RELEASE ...日志管理: SLF4J 1.7.21、I Log4j 编辑器: ueditor 工具类: Apache Commons、 Jackson 2.8.5、POI 3.15 view层:JSP 数据库: mysql

    druid-0.2.9.jar

    1) 可以监控数据库访问性能,Druid内置提供了一个功能强大的...4) SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。

    oracle数据库经典题目

    数据库模式与用户之间的区别在于:用户是数据库的使用者和管理者,用户具有帐户状态、访问权限和操作权限等属性。模式是一系列逻辑数据结构或对象的集合,是数据库中对象的组织和管理单位。 2. 简要游标的作用和...

    iBase4J分布式系统-其他

    9、日志:log4j2打印日志,业务日志和调试日志分开打印。同时基于时间和文件大小分割日志文件。10、QQ、微信、新浪微博第三方登录。11、工具类:excel导入导出,汉字转拼音,身份证号码验证,数字转大写人民币,FTP/...

    蓝莓商城(这个商城用到的技术挺新的,不是我写的,来赚点分数)

    日志管理: slf4j 1.7.5+ log4j2 Mybatis 分页插件: pagehelper 6.1.2 短信验证服务: 阿里云短信服务 任务调度: quartz 数据库连接池: druid 安全管理框架: shiro 验证码库: kaptcha 三.前端技术 JS框架:Jquery ...

    阿里巴巴的开源项目JDBC连接池、监控组件 Druid.zip

     4) SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过...

Global site tag (gtag.js) - Google Analytics