`
bnmnba
  • 浏览: 294991 次
  • 性别: 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`是一个广泛使用的Java日志框架,它提供了灵活的日志配置,能够帮助开发者记录程序运行过程中的各种信息。本文将深入探讨如何利用`log4j`实现按照日期每天写入不同日志文件的功能,以及涉及到的相关知识点。 ...

    log4j写日志

    **标题:“log4j写日志”** 在Java开发中,日志记录是不可或缺的一部分,它帮助开发者追踪程序运行过程中的错误、调试信息以及性能数据。Log4j是一款广泛使用的日志框架,由Apache软件基金会开发,它为Java应用程序...

    无法打出log4j日志的问题排查

    在IT行业中,日志记录是调试和监控应用程序的关键部分,特别是对于Java开发者而言,Log4j是一个非常常用的日志框架。当我们遇到“无法打出log4j日志的问题”,这通常是由于配置、环境或代码实现中的某些错误导致的。...

    打log4j日志-ibatis的sql输出

    本文主要探讨如何使用Log4j框架来记录Ibatis的SQL执行情况,以便更好地理解和优化数据库操作。 首先,Log4j是Apache的一个开源项目,它提供了一个灵活的日志系统,允许开发者定义日志级别、输出格式以及输出位置,...

    log4j日志的数据库管理

    在使用Log4j与数据库结合管理日志前,首先需要正确配置DBCP。以下是一系列关键步骤: 1. **准备mysql的JDBC驱动程序**:JDBC(Java Database Connectivity)是Java中用来连接数据库的标准接口,而JDBC驱动程序则是...

    log4j.rar java写LOG日志的驱动

    **四、Log4j与其他日志框架的对比** 虽然Log4j在日志处理方面表现出色,但随着技术的发展,其他框架如Logback、SLF4J(Simple Logging Facade for Java)也逐渐受到关注。SLF4J作为一个日志门面,提供了统一的API,...

    tomcat8 slf4j+log4j2 写日志.zip

    本教程将针对“tomcat8 slf4j+log4j2 不写日志”的问题提供解决方案,以确保你的应用程序能够正确地记录日志。 首先,我们需要了解SLF4J(Simple Logging Facade for Java)和Log4j2。SLF4J是一个用于日志记录的...

    Log4j实现日志操作

    这篇博客将深入探讨如何使用Log4j进行日志操作。** 首先,我们需要理解Log4j的基本组件。Log4j由三部分组成:配置器(Configurator)、日志记录器(Logger)和输出处理器(Appender)。配置器负责设置日志行为,...

    apache-log4j-2.0-rc1-src

    2. **配置文件**:Log4j使用配置文件(如log4j2.xml或log4j2.json)来定义日志输出的位置、格式和级别。这些配置可以动态更新,无需重启应用。 3. **Appenders**:Appenders是Log4j用来输出日志信息的组件,例如...

    mybatis查询入门(log4j控制台sql语句日记输出的)

    【标题】"mybatis查询入门(log4j控制台sql语句日记输出的)"涉及的知识点主要集中在MyBatis框架的基础使用以及如何通过Log4j在控制台输出SQL语句,以便于调试和优化数据库操作。MyBatis是一个轻量级的Java持久层框架...

    Flume-ng在windows环境搭建并测试+log4j日志通过Flume输出到HDFS.docx

    在本文中,我们将介绍如何在 Windows 环境下搭建 Flume-ng,并使用 Log4j 将日志输出到 HDFS。 一、Flume-ng 安装与配置 首先,需要下载 Flume-ng 并解压到指定目录。然后,需要设置环境变量,新建 FLUME_HOME ...

    log4j教程

    2. **日志目的地配置**:Log4j支持将日志信息输出到多种目的地,包括控制台、文件、数据库等,甚至可以通过网络发送日志。这意味着开发者可以根据实际需求选择最合适的日志存储方式,比如在生产环境中可能更倾向于将...

    log4j生成文件及文件夹

    此外,Log4j还支持自定义日志格式和输出目标,包括文件、数据库、网络等。 **动态日志文件名的生成:** 在Log4j中,我们可以通过配置来实现动态日志文件名。一个常见的需求是根据日期或时间戳来命名日志文件,以...

    log4j手册reference文档

    - **与System.out.println的区别:** 相比直接使用System.out.println输出调试信息,log4j提供了更细粒度的日志控制,并且支持运行时配置。 - **与其他日志框架的对比:** 如logback、SLF4J等,虽然这些框架之间在...

    log4j使用实战

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

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

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

    写的ssh+log4j的Simple

    综上所述,"写的ssh+log4j+分页的Simple"可能是一个简单的Java Web项目示例,它演示了如何集成SSH框架进行应用开发,利用Log4j进行日志管理,以及实现了分页功能。这个项目可以帮助初学者理解如何在实际项目中整合...

    Loger_slf4j写入数据表Demo

    一、运行部署 1、将LogerWriteMySqlDemo项目导入Eclipse 2、修改db.properties文件中数据库...三、配置文件db.properties、log4j.properties两个配置文件可以通过servlet配置来使用,也可以直接先用DbUtil.java中先测试

    用log4j写的例子

    Log4j是Apache组织提供的一款广泛使用的Java日志框架,因其高效、灵活和可配置性而备受青睐。 **Log4j的基本概念** 1. **Logger(日志器)**: 是Log4j的核心组件,负责接收日志信息并将其传递给适当的输出目的地。...

Global site tag (gtag.js) - Google Analytics