`

log4j to db

 
阅读更多

 

由于最近正在扩展卫生局考务系统,由于上一次使用过一次该系统后,发现很多考生最后出现说已打印报名表但却在数据库中找不到她的报名记录;

 

因此为了以后有依据,将所有用户的操作日志文件写入数据供管理员查询成为了这次扩张项目的一个内容;

 

这里我决定使用的log4j日志文件,在多次的使用中感觉这个很不错;

 

首先我们要使用log4j日志文件时,我们需将两个必须的包放入lib目录下:log4j.XX.jar和commons-logging.XX.jar;

 

然后在classpath目录下(IDE中即为项目下的src目录下)新建一个日志文件,统一命名为:log4j.properties

 

1.需求一:只需要满足存储数据库:

 

a.以下我们一ms sql 2000为例:首先在数据库中建一个用来存储日志的数据库命名为 operate_log;字段如下:

 

 

b.数据库成功建立后,就可以去配置日志文件log4j.properties,代码如下:

 

复制代码
log4j.properties  

log4j.rootLogger=INFO,db
            
########################  
 
# 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=1
  
log4j.appender.db.driver=net.sourceforge.jtds.jdbc.Driver
                        
log4j.appender.db.URL=jdbc:jtds:sqlserver://localhost:1433;DatabaseName=infor_manage
#enter  
log4j.appender.db.user=sa 
  
log4j.appender.db.password=123 
log4j.appender.db.sql=insert into operate_log(class,method,createtime,loglevel,logmsg,user_id,user_type) values ('%C','%M','%d{yyyy-MM-dd HH\:mm\:ss}','%p','%m','1',1)  
  
log4j.appender.db.layout=org.apache.log4j.PatternLayout  
复制代码

 

上面的配置就是最精简的将日志内容直接存储进入数据库
下面来稍微解释:

 

log4j.rootLogger=INFO,db语法为:

 

##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个输出地方,这个名字可以任意(如上面的db),但必须与我们在后面进行的设置名字对应;

 

然后下面就是进行数据库连接的配置,log4j是使用jdbc进行连接的,该封转的类就是log4j包下的 org.apache.log4j.jdbc.JDBCAppender,大家对jdbc了解的话上面的内容应该是很简单的;

 

这里要注意的就是:1.记得把数据库连接的相关包放到lib目录下,2.在写连接数据库的信息时如user等注意后面不要有空格,否则就不能连上数据库

 

c.日志文件配置完成后,我们就可以进行测试了,我们可以随便在后台写一个类:

 

复制代码
package xidian.sl.action.admin;

import org.apache.log4j.Logger;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorld extends ActionSupport{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private static final Logger log = Logger.getLogger(HelloWorld.class);//日志文件
    
    public static void main(String[] args) {
        log.error("访问了HelloWorld");
        log.warn("访问了HelloWorld");
        log.info("访问了HelloWorld");
        log.debug("访问了HelloWorld");
    }
}
复制代码

 

然后右键运行,如果没有报错的话应该是成功了,可以去数据库看看:

 

 

可以看到日志信息已经进行了存储,但发现只有三条,少了debug,对了,由于我们进行了日志优先级的配置:log4j.rootLogger=INFO,db,只有debug级别就不能进行打印了;

 

到这里我们可以说基本成功了,但还远远不能满足我的需求:

 

我们发现数据库中出现了很多的日志信息,这个日志信息应该是启动等,从系统文件(spring等)中打印的,但这个其实不是我们需要的,或者说我们需要将其分开:

 

我们重新进行日志文件的配置

 

复制代码
log4j.properties  

log4j.rootLogger=INFO,stdout
log4j.logger.xidian=INFO,db  
log4j.logger.org=WARN, A1
log4j.logger.com =WARN, A2

#stdout\u5e94\u7528\u4e8e\u63a7\u5236\u53f0
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%d %5p (%c\:%L) - %m%n

#A1\u5e94\u7528\u4e8e\u6587\u4ef6\u56de\u6eda
log4j.appender.A1=org.apache.log4j.RollingFileAppender
log4j.appender.A1.File=${webapp.root}/WEB-INF/logs/org.log
log4j.appender.A1.MaxFileSize=500KB
log4j.appender.A1.MaxBackupIndex=50
log4j.appender.A1.Append=true
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} - [%p] [%C{1}] - %m%n

#A2\u5e94\u7528\u4e8e\u6587\u4ef6\u56de\u6eda
log4j.appender.A2=org.apache.log4j.RollingFileAppender
log4j.appender.A2.File=${webapp.root}/WEB-INF/logs/com.log
log4j.appender.A2.MaxFileSize=500KB
log4j.appender.A2.MaxBackupIndex=50
log4j.appender.A2.Append=true
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} - [%p] [%C{1}] - %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=1
  
log4j.appender.db.driver=net.sourceforge.jtds.jdbc.Driver
                        
log4j.appender.db.URL=jdbc:jtds:sqlserver://localhost:9433;DatabaseName=infor_manage
#enter  
log4j.appender.db.user=sa 
  
log4j.appender.db.password=123@sports
 
log4j.appender.db.sql=insert into operate_log(class,method,createtime,loglevel,logmsg,user_id,user_type) values ('%C','%M','%d{yyyy-MM-dd HH\:mm\:ss}','%p','%m','1',1)  
  
log4j.appender.db.layout=org.apache.log4j.PatternLayout  
复制代码

 

这次的配置要复杂点

 

log4j.logger.xidian=INFO,db 
log4j.logger.org=WARN, A1
log4j.logger.com =WARN, A2

 

这个配置就是将不同的包下的信息输出到不同的文件中,根据下面的配置可知以xidian开头的包下的java文件的日志信息时进行数据库存储的,而 org与com包开头的日志信息是输出到文件中,文件的输出地址是${webapp.root}/WEB-INF/logs/org.log即项目的 WEB-INF目录下的logs文件夹中,为了得到${webapp.root}我们还需要到web.xml文件中进行配置:

 

复制代码
 <!--由Sprng载入的Log4j配置文件位置-->
 <context-param>
  <param-name>log4jConfigLocation</param-name>

  <param-value>classpath:log4j.properties</param-value>
 </context-param>
 <!--Spring log4j Config listener-->
 <listener>
  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
 </listener>
复制代码

 

这样我们再次运行HelloWorld程序
查看数据库(很干净了,哈哈):

 

 

然后在到WEB-INF目录下的logs文件夹中查看输出的日志文件:

 

 

 由于我们在根Logger下也进行了配置:这个根Logger的配置是对所有日志操作都是有作用的

 

复制代码
log4j.rootLogger=INFO,stdout

#stdout\u5e94\u7528\u4e8e\u63a7\u5236\u53f0
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%d %5p (%c\:%L) - %m%n
复制代码

 

这个配置是进行控制太的输出,因此我们在控制台中也会发现有输出:

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 到此为止我们日志的基本操作都应该掌握了,但我还有一个需求没有满足,就是我一开始数据库字段的设计中还包含了两个字段:

 

 

这两个字段是存储用户的id和用户类型的,以便我们在后面日志的核查中能正确的找出用户信息;但这里就有一个问题了我们就靠上面的操作还是不能将用户信息得到的,

 

还有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中,然后再在log4j.properties配置文件中的sql语句中进行读取:

 

过滤器代码:

 

复制代码
package xidian.sl.filter;

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.MDC;

public class LogResFilter implements Filter {
    
    private final static double DEFAULT_USERID= 0.0;   
    
    @Override
    public void destroy() {
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //System.out.println("进入过滤器");
        HttpServletRequest req=(HttpServletRequest)request;  
        HttpSession session= req.getSession();  
        if (session==null){  
            MDC.put("userId",DEFAULT_USERID);
            MDC.put("userType",DEFAULT_USERID);  
        }  
        else{  
            //StuInfor stuInfor =(StuInfor)session.getAttribute("admin"); 
            //用户的id
            Integer userId = (Integer)session.getAttribute("userId");
            //用户的类型
            String adminType = (String)session.getAttribute("adminType");
            if (userId == null&& adminType == null){  
                MDC.put("userId",DEFAULT_USERID);  
                MDC.put("userType",DEFAULT_USERID);  
            }  
            else  
            {  
                System.out.println("用户id"+userId+ "类型"+ adminType);
                MDC.put("userId", userId);  
                MDC.put("userType", adminType);  
            }  
        }  
       chain.doFilter(request, response);  
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}
复制代码

 

然后在web.xml中进行过滤器的配置:

 

复制代码
    <filter> 
        <filter-name>LogResFilter</filter-name> 
        <filter-class>xidian.sl.filter.LogResFilter</filter-class> 
    </filter>
    <filter-mapping>
        <filter-name>LogResFilter</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
复制代码

 

这样用户登录后存储在session中的信息通过该过滤器就存储MDC中,然后我们在日志文件中写sql语句:

 

log4j.appender.db.sql=insert into operate_log(class,method,createtime,loglevel,logmsg,user_id,user_type) values ('%C','%M','%d{yyyy-MM-dd HH\:mm\:ss}','%p','%m','%X{userId}','%X{adminType}')  

 


到这里我的需求基本上满足了,不知道有没有满足你的需求。

 

 
分享到:
评论

相关推荐

    Log - Log4j - log4j.properties配置文件

    log4j.appender.MyAppFileAppender.File=/path/to/myapp.log ``` 集成Log4j到Hibernate框架中,主要是为了记录SQL语句和执行时间,这对于数据库操作的调试非常有用。以下是配置示例: ```properties # Hibernate...

    log4j添加日志到数据库和文件中

    log4j.appender.FILE.File=/path/to/logfile.log ``` 2. **数据库日志**:要将日志写入数据库,我们需要使用DBAppender。首先,确保你的应用程序连接到数据库,然后配置Log4j连接到同一个数据库。例如,使用...

    log4j 数据库,邮件,html 等配置

    Log4j,作为Java领域广泛应用的日志框架,提供了强大的功能来满足这些需求。本文将深入探讨如何利用Log4j进行数据库、邮件以及HTML格式的日志记录。 一、数据库日志记录 Log4j允许我们直接将日志信息存储到数据库...

    erlang日志应用log4erl(非sasl)

    - Support for a log formatter (similar to Layouts in Log4J) - Support for console log - Support for smtp formatter - Support for XML logs - Support for syslog - Support for changing format and level ...

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

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

    azkaban-3.38安装包(已编译)

    log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss.SSS Z} %p [%c{1}] [Azkaban] %m%n 5. 在azkaban-exec-server目录下...

    分布式事务内存数据库MemDB.zip

     // Connect to memdb  yield mdbgoose.connectAsync({  shards : { // specify all shards here  s1 : {host : '127.0.0.1', port: 31017},  s2 : {host : '127.0.0.1', port: 31018},...

    Introduction to bode plot

    20\log_{10}(H(j\omega)) = 20\log_{10}\left(\frac{K(j\omega + z_1)(j\omega + z_2)\cdots(j\omega + z_m)}{(j\omega + p_1)(j\omega + p_2)\cdots(j\omega + p_n)}\right) \] 这个表达式可以进一步简化为: \[ 20...

    Hive2.3.4安装文档

    mv hive-log4j2.properties.template hive-log4j2.properties cp hive-default.xml.template hive-site.xml ``` 四、配置hive-site.xml文件 ``` &lt;!-- hive元数据地址,默认是/user/hive/warehouse --&gt; ...

    Linux下刪除Oracle Instance

    - `/u01/app/oracle/product/10.2.0/db_1/oc4j/j2ee/OC4J_DBConsole_host_testdb` - `/u01/app/oracle/product/10.2.0/db_1/rdbms/log/alert_testdb.log` - `/u01/app/oracle/product/10.2.0/db_1/host_testdb` ...

    数字信号处理教学课件:Chapter9 IIR Digital Filter Design.ppt

    The loss function, A(ω) = -20log10|G(e^jω)|, is often used to express these specifications in decibels (dB). 2. **Filter Type Selection**: Based on the application, one must choose between ...

    p6spy日志监控 sql注入

    # mysql Connector/J driver # realdriver=com.mysql.jdbc.Driver # informix driver # realdriver=com.informix.jdbc.IfxDriver # ibm db2 driver # realdriver=COM.ibm.db2.jdbc.net.DB2Driver # the mysql ...

    移动代理源代码

    This document This document contains some information ...logsProps: contains the rules for logging with log4j. repositories: contains the DB used to store some info used for the prototype execution.

    C8051f35x系列单片机示例程序

    // 117dB = 20 log10 ( 11 / 2^23) // 20 bits = 117dB / 6dB/bit // // Another parameter of note for integrating converters is the number of // Noise-Free bits. For a Gaussian-distributed noise floor, ...

    图像SNR、PSNR与MSE计算

    \[ MSE = \frac{1}{MN} \sum_{i=1}^{M} \sum_{j=1}^{N} (I_{ij} - O_{ij})^2 \] 其中,M和N是图像的高度和宽度,I和O分别代表原始图像和处理后的图像。 在给定的MATLAB文件中,`SNR.m`、`PSNR.m`和`MSE.m`可能是...

    计算峰值信噪比

    峰值信噪比(Peak Signal-to-Noise Ratio,简称PSNR)是数字图像处理领域中一个常用的评价指标,用于衡量图像质量的好坏。它通过比较原始图像(无噪声图像)与处理后的图像(如压缩、传输后或添加噪声的图像)之间的...

    安装ulogd步骤

    grant all privileges on ulog.* to ulog@localhost identified by 'ulog'; flush privileges; exit 5. 安装iptables规则 安装iptables规则以记录网络流量: iptables -A INPUT -p tcp --dport 80 -j ULOG ...

Global site tag (gtag.js) - Google Analytics