Log4j配置日志输出到数据库

毛缪文
2023-12-01

功能描述

log4j日志一般输出到控制台或文件中,本文讲解如何将日志输出到数据库。

新建日志表

首先在数据库中创建日志存储表:

sqlserver库

-- for sqlserver
create table operate_log(
log_id int primary key identity /*id*/
, class varchar(500)/*类名*/
, method varchar(200)/*方法名*/
, createtime varchar(100) /*产生时间*/
, loglevel varchar(20) /*日志级别*/
, user_type varchar(50) /*用户联系*/
, user_id varchar(100) /*用户id*/
, logmsg text /*日志信息*/
);

oracle库

-- for oracle
create table operate_log(
log_id int primary key  /*id*/
, class varchar(500)/*类名*/
, method varchar(200)/*方法名*/
, createtime varchar(100) /*产生时间*/
, loglevel varchar(20) /*日志级别*/
, user_type varchar(50) /*用户联系*/
, user_id varchar(100) /*用户id*/
, logmsg VARCHAR(4000) /*日志信息*/
);

create sequence seq_operate_log increment by 1 start with 1 minvalue 1 NOMAXVALUE;

create or replace trigger tri_operate_log_insert 
before insert on operate_log
for each row 
begin 
	select   seq_operate_log.nextval   into:new.log_id from dual ; 
end;

配置log4j

配置log4j.properties

# 将所有日志输出到数据库
log4j.rootLogger=info,CONSOLE,A1,db
# 或者将指定包(com.test.*)下的日志输出到数据库
log4j.logger.com.test=INFO,db

# log-to-db
log4j.appender.db=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.db.BufferSize=1
# for sqlserver
#log4j.appender.db.driver=net.sourceforge.jtds.jdbc.Driver
#log4j.appender.db.URL=jdbc:jtds:sqlserver://localhost:1433;DatabaseName=test
#log4j.appender.db.user=user1
#log4j.appender.db.password=test
# for oracle
log4j.appender.db.driver=oracle.jdbc.OracleDriver
log4j.appender.db.URL=jdbc:oracle:thin:@127.0.0.1:1521/test 
log4j.appender.db.user=user1
log4j.appender.db.password=test
# 指定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','1','1')
log4j.appender.db.layout=org.apache.log4j.PatternLayout

注意事项:
1.把数据库驱动包放到lib目录下;
2.数据库配置参数(如user,password)等后面不要有空格,否则就不能连上数据库

配置log4j.xml

	<!--新增数据库日志输出-->
	<appender name="DATABASE" class="org.apache.log4j.jdbc.JDBCAppender">  
		<param name="URL" value="jdbc:oracle:thin:@127.0.0.1:1521/test"/>  
		<param name="driver" value="oracle.jdbc.driver.OracleDriver"/>  
		<param name="user" value="user1"/>  
		<param name="password" value="test"/>      
		<layout class="org.apache.log4j.PatternLayout">  
			<param name="ConversionPattern"  
				value="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')" />  
		</layout>  
	</appender>  
	
	<!-- (推荐)将指定包中的类日志输出到数据库中-->  
	<logger name="com.test" additivity="false">     
		<level value="info" />     
		<appender-ref ref="DATABASE" />     
	</logger>  
	<logger name="com.dev" additivity="false">     
		<level value="info" />     
		<appender-ref ref="DATABASE" />     
	</logger>  
    
	<!-- (不推荐)将全部日志输出到数据库中-->  	
	<root>  
		<priority value="info" />  
		<!--新增数据库日志输出-->
		<appender-ref ref="DATABASE" />  
	</root>  

日志中记录用户信息

工作原理

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配置文件中的sql语句中进行读取:

过滤器代码:

package com.test.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 String DEFAULT_USERID = "0";

	@Override
	public void destroy() {

	}

	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 {
			// 用户的id
			String userId = (String) session.getAttribute("uid");
			// 用户的类型
			String userType = (String) session.getAttribute("rid");
			if (userId == null && userType == null) {
				MDC.put("userId", DEFAULT_USERID);
				MDC.put("userType", DEFAULT_USERID);
			} else {
				// System.out.println("用户id" + userId + "\t类型" + userType);
				MDC.put("userId", userId);
				MDC.put("userType", userType);
			}
		}
		chain.doFilter(request, response);
	}

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

	}

}

配置web.xml

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

	<filter> 
        <filter-name>LogResFilter</filter-name> 
        <filter-class>com.test.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{userType}')

–END–

 类似资料: