log4j日志一般输出到控制台或文件中,本文讲解如何将日志输出到数据库。
首先在数据库中创建日志存储表:
-- 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 /*日志信息*/
);
-- 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.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)等后面不要有空格,否则就不能连上数据库
<!--新增数据库日志输出-->
<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中进行过滤器的配置:
<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–