首先咱們要使用log4j日誌文件時,咱們需將兩個必須的包放入lib目錄下:log4j.XX.jar和commons-logging.XX.jar;java
而後在classpath目錄下(IDE中即爲項目下的src目錄下)新建一個日誌文件,統一命名爲:log4j.properties;web
1.需求一:只須要知足存儲數據庫:spring
a.如下咱們一ms sql 2000爲例:首先在數據庫中建一個用來存儲日誌的數據庫命名爲 operate_log;字段以下:sql
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
上面的配置就是最精簡的將日誌內容直接存儲進入數據庫
下面來稍微解釋:apache
log4j.rootLogger=INFO,db語法爲:session
##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),但必須與咱們在後面進行的設置名字對應;app
而後下面就是進行數據庫鏈接的配置,log4j是使用jdbc進行鏈接的,該封轉的類就是log4j包下的 org.apache.log4j.jdbc.JDBCAppender,你們對jdbc瞭解的話上面的內容應該是很簡單的;webapp
這裏要注意的就是:1.記得把數據庫鏈接的相關包放到lib目錄下,2.在寫鏈接數據庫的信息時如user等注意後面不要有空格,不然就不能連上數據庫ide
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=50log4j.appender.A1.Append=truelog4j.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=50log4j.appender.A2.Append=truelog4j.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}')
到這裏個人需求基本上知足了,不知道有沒有知足你的需求。