Log4j建議只使用四個級別,優先級從高到低分別是ERROR、WARN、INFO、DEBUG。好比在這裏定義了INFO級別,只有等於及高於這個級別的才進行處理,css
1、log4j使用步驟(重點在使用過程和初始化):
1.將log4j.jar相關包放到jsp-examples\WEB-INF\lib下;
2.在classpath下面創建log4j.properties;
3.完善log4j.properties內容:html
具體log4j.properties的配置方法參見http://hi.baidu.com/276668688/blog/item/e8d2fc1fdd8818c1a786698d.htmljava
4.初始化log4j的配置文件:有兩種方法
方法一:
a.新建一個初始化類,通常用Servlet或過濾器Log4JInit.javanode
注意:System.setProperty("webappHome", test);」這行代碼要出如今「PropertyConfigurator.configure(prefix + file);」這行代碼以前;由於這樣纔給"webappHome"設置值了,log4j.properties文件中的「log4j.appender.A1.file=${webappHome}/logs/tomcat_log_」中的「${webappHome}」這個環境變量才被賦值了,不然沒法輸出日誌文件;web
b.配置web.xml文件spring
注意:上面的load-on-startup應設爲1,以便在Web容器啓動時即裝入該Servlet。log4j.properties文件放在根的properties子目錄中,也能夠把它放在其它目錄中。應該把.properties文件集中存放,這樣方便管理。
方法2、使用Spring已經寫好的過濾器
a.配置web.xmlapache
5.在webapp中使用log4j
主要創建一個屬性private static Logger logger = Logger.getLogger(Log4jTest.class);tomcat
public class Hello extends HttpServlet {
private static Logger logger = Logger.getLogger(Hello.class);多線程
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("Hello world!!");
logger.debug("log4j加載成功!");
}app
}
6.在具體使用的時候若是觸發了異常,就在生成以日期命名的html日誌文件tomcat_log_2007-03-05.html了!
這個日誌的格式能夠在log4j.properties裏面配置.......
====================================================================================================================================================================================================
經常使用log4j配置
經常使用log4j配置,通常能夠採用兩種方式,.properties和.xml,下面舉兩個簡單的例子:
1、 log4j.properties
### 設置org.zblog域對應的級別INFO,DEBUG,WARN,ERROR和輸出地A1,A2 ##
log4j.category.org.zblog=ERROR,A1
log4j.category.org.zblog=INFO,A2
log4j.appender.A1=org.apache.log4j.ConsoleAppender
### 設置輸出地A1,爲ConsoleAppender(控制檯) ##
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
### 設置A1的輸出佈局格式PatterLayout,(能夠靈活地指定佈局模式)##
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
### 配置日誌輸出的格式##
log4j.appender.A2=org.apache.log4j.RollingFileAppender
### 設置輸出地A2到文件(文件大小到達指定尺寸的時候產生一個新的文件)##
log4j.appender.A2.File=E:/study/log4j/zhuwei.html
### 文件位置##
log4j.appender.A2.MaxFileSize=500KB
### 文件大小##
log4j.appender.A2.MaxBackupIndex=1
log4j.appender.A2.layout=org.apache.log4j.HTMLLayout
##指定採用html方式輸出
2、 log4j.xml
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="org.zblog.all" class="org.apache.log4j.RollingFileAppender">
<!-- 設置通道ID:org.zblog.all和輸出方式:org.apache.log4j.RollingFileAppender -->
<param name="File" value="E:/study/log4j/all.output.log" /><!-- 設置File參數:日誌輸出文件名 -->
<param name="Append" value="false" /><!-- 設置是否在從新啓動服務時,在原有日誌的基礎添加新日誌 -->
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" /><!-- 設置輸出文件項目和格式 -->
</layout>
</appender>
<appender name="org.zblog.zcw" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="E:/study/log4j/zhuwei.output.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="10240" /> <!-- 設置文件大小 -->
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
</layout>
</appender>
<logger name="zcw.log"> <!-- 設置域名限制,即zcw.log域及如下的日誌均輸出到下面對應的通道中 -->
<level value="debug" /><!-- 設置級別 -->
<appender-ref ref="org.zblog.zcw" /><!-- 與前面的通道id相對應 -->
</logger>
<root> <!-- 設置接收全部輸出的通道 -->
<appender-ref ref="org.zblog.all" /><!-- 與前面的通道id相對應 -->
</root>
</log4j:configuration>
3、 配置文件加載方法:
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
public class Log4jApp {
public static void main(String[] args) {
DOMConfigurator.configure("E:/study/log4j/log4j.xml");//加載.xml文件
//PropertyConfigurator.configure("E:/study/log4j/log4j.properties");//加載.properties文件
Logger log=Logger.getLogger("org.zblog.test");
log.info("測試");
}
}
4、 項目使用log4j
在web 應用中,能夠將配置文件的加載放在一個單獨的servlet中,並在web.xml中配置該servlet在應用啓動時候加載。對於在多人項目中,能夠給每個人設置一個輸出通道,這樣在每一個人在構建Logger時,用本身的域名稱,讓調試信息輸出到本身的log文件中。
5、 經常使用輸出格式
# -X號:X信息輸出時左對齊;
# %p:日誌信息級別
# %d{}:日誌信息產生時間
# %c:日誌信息所在地(類名)
# %m:產生的日誌具體信息
# %n:輸出日誌信息換行
===============================================================================================
修改前:
偶們的作法是在action裏記錄日誌,注意這個日誌是面向用戶的日誌,姑且稱它爲業務日誌,至於後臺日誌,則在此文章中暫不考慮,基本是經過log4j打印到後臺日誌文件中。看下面一段代碼:
這段代碼實際上已經將寫日誌的過程封裝起來,開發者只須要傳入3個參數:操做者、是前臺系統仍是後臺系統、以及日誌的錯誤等級,其它的如操做者機器IP, 日誌時間等信息由系通通一設定,即便是這樣,若是一個action裏面有多個操做,代碼看起來也很是臃腫,並且給開發者增長了工做量,既然有了aop,爲 什麼不利用一下?看下面改造的代碼:
這段代碼應該很清楚了,將logService注入到攔截log的advice裏,進行正確操做的日誌記錄,而afterReturning方法裏 的第一行判斷是因爲logService裏的寫日誌的方法是以save開始的。因此,若是攔截器攔截到此方法,不須要記錄日誌。
正確的日誌記錄完,固然若是發生異常,咱們須要記錄操做的失敗日誌,固然了,咱們也是經過aop來作,可是此次是經過實現exception advice來實現,代碼以下:
上面代碼已經很好的說明了,若是發生exception的話,日誌是怎麼記錄的,這裏要提到的一點的是,異常的處理稍微有一些複雜,就拿本例的代碼能看出 來,只要在service層有異常的時候,都會記錄失敗日誌,實際上,不少時候,未必是這樣,在某個模塊,可能須要定義一種特殊的異常,而一旦這種異常發 生,則須要進入另一個流程或者作一些特殊的處理,這個時候須要根據具體狀況作一些變動,好比在上面代碼咱們加上:
1.在網上看了很多例子,下面本身實踐了一下。因爲系統開發的時候忘記了對異常的日誌處理,因此如今考慮加上,通過考慮決定使用spring的aop與log4j來作,這樣作的好處就是我不用在每一個類裏面try{}catch或者拋出異常。由於類已經寫了好多好多了。要是一個一個弄工做量是很大的 。
下面說下簡單的實現過程,首先啊,在項目工程中的src目錄中加入log4j.properties,內容以下:
###設置日誌級別###
###這部分是將info信息輸出到控制檯###
log4j.rootLogger = info,stdout,F
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
###錯誤日誌配置###
log4j.appender.F = org.apache.log4j.DailyRollingFileAppender
##輸出格式爲自定義的HTML##
log4j.appender.F.layout = com.yale.sys.log.FormatHTMLLayout
log4j.appender.F.Threshold = ERROR
log4j.appender.F.Append=true
##錯誤文件存放位置##
log4j.appender.F.File=error.html
##天天滾動一次文件,即天天產生一個新的文件,文件名字eg:error.html.2012-06-18.html##
log4j.appender.F.DatePattern='.'yyyy-MM-dd'.html'
-------------------------------耐心的看下去 -----------------------------------
其次呢,看上面紅色那部分,由於是要將輸出日誌信息存儲到html文件中,因此重寫了下log4j中HTMLLayout類,代碼片斷:
----------------------------耐心點往下看,就要沒了 --------------------------------------------------
再來就是錯誤文件error.html的存儲位置,想要放在項目的WebRoot下,因而就寫了個servlet,代碼片斷:
注意啦,錯誤文件存儲的路徑不容許空格上面亂碼七糟的,必定要注意哦。
寫完這個servlet,咱們不能忘記初始化,您說對不對啊,因此啊,web.xml就像下面這個樣子了:
--------------------------------下面就開始和spring aop相關啦,看吧,看吧-----------------------
再一次首先,寫一個系統異常日誌攔截器類,您看:
上面這個類,主要用到了aspectj中的ProceedingJoinPoint,支持的是<aop:around />。
類寫完了,可是spring配置文件applicationContext.xml尚未搞啊,因此搞一下:
小插曲:看見<aop:config>節點中proxy-target-class="true"這個屬性了吧,當我不加的時候,啓動項目,訪問action代碼,就好比是LoginAction中的login()方法,不幸的是他報錯了,相似於
java.lang.NoSuchMethodException: $Proxy54.login(),但是回去一看,有寫過這個login方法啊, $Proxy54又是怎麼回事呢?由於你加入aop功能了,但是spring是這麼幹的,默認啊實現的是接口注入,關聯的實現類。這裏實現注入類,因此出現了異常。要怎麼解決呢,因而就要加上proxy-target-class="true"屬性,接下來啓動項目吧,你會發現不幸的事情又發生了,又報錯了:
org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
提示的很明顯,少jar包了,因此就加吧,可是加jar的時候也要注意了:
須要導入的jar包是cglib-nodep-2.1_3.jar(這裏面整合了asm)或者(asm-2.2.3.jar和cglib-2.2.jar 。)由於cglib須要asm的支持。
到此完成。
啓動項目開始運行吧,模擬了下一個異常,輸出到html最終這樣啦: