Log4j 是Apache的一個開放源代碼項目,通過使用Log4j,我們可以控制日志信息輸送的目的地是控制台、文件、GUI組件、甚至是套接口服務器、NT的事 件記錄器、UNIX Syslog守護進程等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志信息的級別,我們能夠更加細致地控制日志的生成過程。最令人感興趣的就 是,這些可以通過一個配置文件來靈活地進行配置,而不需要修改應用的代碼。
如此強大的優越性,實際上手並不難,尤其在spring框架下,使用log4j更是容易,下面介紹一下spring下的log4j應用。
<一>如何配置日志環境
(1)在web工程沖導入log4j-xxx.jar
(2)在spring的配置文件web.xml加入如下配置
<!-- 配置日志監聽器 -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>weChat.root</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value><!--指定日志配置文件的所在位置-->
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
說明: 在上文的配置里,在上文的配置里,Log4jConfigListener會去WEB- INF/props/log4j.propeties 讀取配置文件;
開一條watchdog線程每60秒掃描一下配置文件的變化(這樣在web服務啟動后再去修改配置文件也不用重新啟動web服務了);
並把 web目錄的路徑壓入一個叫webapp.root的系統變量(webapp.root將在log4j.properties文件中使用)。
(3)在項目中加入日志配置文件(放入上面配置中指定的位置)
log4j.properties內容如下:
#將ibatis log4j運行級別調到DEBUG可以在控制台打印出ibatis運行的sql語句
#trace<debug<info<warn<error<fatal
#指定日志有的輸出的級別和要輸出的方式
log4j.rootLogger=info,stdout,logfile,db
#指定日志輸出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
#指定日志輸出到文件
log4j.appender.logfile=org.apache.log4j.FileAppender
#指定日志輸出的位置(這里使用${weChat.root}指定當前項目根目錄)
log4j.appender.logfile.File=${weChat.root}/logs/mylog.log
#指定日志文件的大小
log4j.appender.logfile.MaxFileSize=1024KB
#指定日志輸出的布局
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
#指定日志的輸出內容
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n
#指定將日志寫入數據庫中
log4j.appender.db = com.cdjp.util.Log4jJDBCAppender
#緩存,這里是有一條日志就存入數據庫(較浪費性能)
log4j.appender.db.BufferSize=1
#指定數據庫的驅動
log4j.appender.db.driver=oracle.jdbc.driver.OracleDriver
#指定數據庫的鏈接
log4j.appender.db.URL=jdbc:oracle:thin:@localhost:1521:xe
#指定數據庫的用戶名
log4j.appender.db.user=system
#指定數據庫的密碼
log4j.appender.db.password=123456
#寫入數據的sql語句
log4j.appender.db.sql=insert into reslog(logId,class,method,createDate,logLevel,msg) values(reslog_seq.nextval,'%C','%M',
to_date('%d{yyyy-MM-dd HH:mm:ss}','yyyy-MM-dd HH24:mi:ss'),'%p','%m')
#指定日志的輸出布局方式
log4j.appender.db.layout=org.apache.log4j.PatternLayout
注意:
原本上面這個屬性 log4j.appender.db = org.apache.log4j.jdbc.JDBCAppender
可是將數據寫入數據庫時,部分數據中存在單引號(需要轉義),這樣在夠構成寫入數據庫的sql語句就會產生錯誤。例如%m中含有單引號,因而就如發生SQLException:缺失逗號。
這里錯誤的原因是JDBCAppender這個類,官方已經不建議使用,它不會對數據中的單引號進行特殊處理(原理網上有,不過我看不懂,大家自行研究)
建議重寫org.apache.log4j.jdbc.JDBCAppender, 代碼如下:
1.就是自己寫一個類擴展LoggingEvent,重寫它的getThreadName方法,代碼如下:
public class BPSLoggingEvent extends LoggingEvent { private static final long serialVersionUID = -1405129465403337629L; public BPSLoggingEvent(String fqnOfCategoryClass, Category logger, Priority level, Object message, Throwable throwable) { super(fqnOfCategoryClass, logger, level, message, throwable); } public String getThreadName() { String thrdName=super.getThreadName(); if(thrdName.indexOf("'")!=-1){ thrdName=thrdName.replaceAll("'", "''"); } return thrdName; } public String getRenderedMessage() { String msg=super.getRenderedMessage(); if(msg.indexOf("'")!=-1){ msg=msg.replaceAll("'", "''"); } return msg; } }
2.擴展JDBCAPPend了,覆蓋里面的getLogStatement方法,代碼如下:
public class BPSJDBCAppender extends JDBCAppender { protected String getLogStatement(LoggingEvent event) { String fqnOfCategoryClass=event.fqnOfCategoryClass; Category logger=Category.getRoot(); Priority level=event.level; Object message=event.getMessage(); Throwable throwable=null; BPSLoggingEvent bEvent=new BPSLoggingEvent(fqnOfCategoryClass,logger,level,message,throwable); return super.getLogStatement(bEvent); } }
3. log4j.appender.db = org.apache.log4j.jdbc.JDBCAppender 指定成上面BPSJDBCAppender(全稱),就可以了。
<二>日志文件配置相關說明
log4j使用的幾個關鍵點
根記錄器(rootLogger),輸出端(appenders)和布局(layouts)
a)定義根記錄器的格式為
log4j.rootLogger = [ level ], appendName1, appendName2, …appendNameN。同一個記錄器可有多個輸出端。
PS:level的級別(此級別可以自定義,系統默認提供了以下級別)
◆debug//調試信息
◆info//一般信息
◆warn//警告信息
◆error//錯誤信息
◆fatal//致命錯誤信息
上面列出的就是所謂log4j的輸出級別,log4j建議只使用4個級別,它們從上到下分別為ERROR、WARN、INFO、DEBUG,假設你定義的級別是info,
那么error和warn的日志可以顯示而比他低的debug信息就不顯示了。
b)定義一個appender的輸出目的地的格式為
log4j.appender.appenderName = fully.qualified.name.of.appender.class。log4j提供了以下幾種常用的輸出目的地:
◆org.apache.log4j.ConsoleAppender,將日志信息輸出到控制台
◆org.apache.log4j.FileAppender,將日志信息輸出到一個文件
◆org.apache.log4j.DailyRollingFileAppender,將日志信息輸出到一個,並且每天輸出到一個新的日志文件
◆org.apache.log4j.RollingFileAppender,將日志信息輸出到一個文件,通過指定文件的的尺寸,當文件大小到達指定尺寸的時候會自動把文件改名,如名為example.log的文件會改名為 example.log.1,同時產生一個新的example.log文件。如果新的文件再次達到指定尺寸,又會自動把文件改名為 example.log.2,同時產生一個example.log文件。依此類推,直到example.log. MaxBackupIndex, MaxBackupIndex的值可在配置文件中定義。
◆org.apache.log4j.WriterAppender,將日志信息以流格式發送到任意指定的地方。
◆org.apache.log4j.jdbc.JDBCAppender,通過JDBC把日志信息輸出到數據庫中。
c)輸出格式(布局)layout
Log4j提供了一下幾種布局:
◆org.apache.log4j.HTMLLayout,以HTML表格形式布局
◆org.apache.log4j.PatternLayout,可以靈活地指定布局模式
◆org.apache.log4j.SimpleLayout,包含日志信息的級別和信息字符串
定義一個PatternLayout布局的語句為:
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1} - %m%n
PS:ConversionPattern參數的格式含義
%c 輸出日志信息所屬的類的全名
%d 輸出日志時間點的日期或時間,默認格式為ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss },輸出類似:2002-10-18- 22:10:28
%f 輸出日志信息所屬的類的類名
%l 輸出日志事件的發生位置,即輸出日志信息的語句處於它所在的類的第幾行
%m 輸出代碼中指定的信息,如log(message)中的message
%n 輸出一個回車換行符,Windows平台為“\r\n”,Unix平台為“\n”
%p 輸出優先級,即DEBUG,INFO,WARN,ERROR,FATAL。如果是調用debug()輸出的,則為DEBUG,依此類推
%r 輸出自應用啟動到輸出該日志信息所耗費的毫秒數
%t 輸出產生該日志事件的線程名
ps:這些記錄大多是抄錄於他人(給出了具體原理,自行觀看)
抄錄一:Spring 配置log4j和簡單介紹Log4J的使用
抄錄二:log4j重寫