Lo4j 寫入數據庫(配置) 轉

[color=red]參考:http://blog.csdn.net/ziruobing/article/details/3919501[/color]

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=JDBCExtAppender

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章