【前面的話】html
學習的進度應該稍微在快一點。java
Java日誌到了必須學習怎麼使用的時候了,由於在項目中要進行使用。基礎性文章,選擇性閱讀。程序員
【結構】apache
java日誌對調試,記錄運行,問題定位都起到了很重要的做用,通常經常使用的日誌框架有:服務器
【定義】多線程
記錄日誌:通常在最開始寫代碼的時候老是會在代碼中加入一些System.out.println方法的語句來觀察代碼運行的狀況。這樣須要反覆加入和修改,日誌API就是爲了解決這個問題。app
java.util.logging包就是JDK的日誌開發包。框架
Log4j是Apache的一個開放源代碼項目,經過使用Log4j,咱們能夠控制日誌信息輸送的目的地是控制檯、文件、GUI組件,甚至是套接口服務器、NT的事件記錄器、UNIX Syslog守護進程等;咱們也能夠控制每一條日誌的輸出格式;經過定義每一條日誌信息的級別,咱們可以更加細緻地控制日誌的生成過程。最使人感興趣的就是,這些能夠經過一個配置文件來靈活地進行配置,而不須要修改應用的代碼。函數
好處佈局
【JDK自帶logging】
1、 日誌級別
級別 |
意義 |
等級 |
OFF |
這個日誌級別比較特殊,用來關閉日誌 |
|
SEVERE |
系統比較嚴重的錯誤級別,通常是沒法恢復的bug |
最高 |
WARNING |
警告提示 |
|
INFO |
普通訊息輸出 |
|
CONFIG |
靜態配置信息輸出,如cpu,mem |
|
FINE |
FINE,FINER,FINEST三個日誌級別都是用來跟蹤日誌信息,輸出信息的詳細程度依次遞增 |
|
FINER |
|
|
FINEST |
最低 |
|
ALL |
全部的日誌信息都輸出 |
|
在默認狀況下,只記錄前面三個級別。也能夠設置級別以下:
1 logger.setLevel(Level.ALL);
2、例子
1. 代碼
1 import java.util.logging.ConsoleHandler; 2 import java.util.logging.Level; 3 import java.util.logging.Logger; 4 5 public class LoggerTest { 6 public static void main(String []args){ 7 Logger logger =Logger.getLogger("cn.cc.ccc"); 8 /* ConsoleHandler handler=new ConsoleHandler(); 9 handler.setLevel(Level.ALL); 10 logger.addHandler(handler);*/ 11 logger.setLevel(Level.ALL); 12 logger.severe("嚴重錯誤"); 13 logger.warning("警告信息"); 14 logger.info("普通輸出"); 15 logger.config("配置信息"); 16 logger.fine("日誌信息"); 17 logger.finer("日誌信息"); 18 logger.finest("日誌信息"); 19 } 20 }
2. 結果:
1 四月 10, 2014 4:48:55 下午 LoggerTest main 2 嚴重: 嚴重錯誤 3 四月 10, 2014 4:48:55 下午 LoggerTest main 4 警告: 警告信息 5 四月 10, 2014 4:48:55 下午 LoggerTest main 6 信息: 普通輸出
3. 問題:
進行了等級設置之後爲何不能輸出下面的幾個級別的信息?也就是爲何沒有輸出:
1 四月 10, 2014 4:44:43 下午 LoggerTest main 2 配置: 配置信息 3 四月 10, 2014 4:44:43 下午 LoggerTest main 4 詳細: 日誌信息 5 四月 10, 2014 4:44:43 下午 LoggerTest main 6 較詳細: 日誌信息 7 四月 10, 2014 4:44:43 下午 LoggerTest main 8 很是詳細: 日誌信息
4. 緣由:
默認規定只能輸出到INFO級別,咱們沒有修改配置文件,也就是使用了默認的配置。有兩種修改方式,
一種是修改.properties文件(本文沒有實現),默認狀況下配置文件存在於:jre/lib/logging.properties
第二種是安裝一個新的ConsoleHandler,以下代碼:
1 import java.util.logging.ConsoleHandler; 2 import java.util.logging.Level; 3 import java.util.logging.Logger; 4 5 public class LoggerTest { 6 public static void main(String []args){ 7 Logger logger =Logger.getLogger("cn.cc.ccc"); 8 ConsoleHandler handler=new ConsoleHandler(); 9 handler.setLevel(Level.ALL); 10 logger.addHandler(handler); 11 logger.setLevel(Level.ALL); 12 logger.severe("嚴重錯誤"); 13 logger.warning("警告信息"); 14 logger.info("普通輸出"); 15 logger.config("配置信息"); 16 logger.fine("日誌信息"); 17 logger.finer("日誌信息"); 18 logger.finest("日誌信息"); 19 } 20 }
結果
1 四月 10, 2014 4:44:43 下午 LoggerTest main 2 嚴重: 嚴重錯誤 3 四月 10, 2014 4:44:43 下午 LoggerTest main 4 嚴重: 嚴重錯誤 5 四月 10, 2014 4:44:43 下午 LoggerTest main 6 警告: 警告信息 7 四月 10, 2014 4:44:43 下午 LoggerTest main 8 警告: 警告信息 9 四月 10, 2014 4:44:43 下午 LoggerTest main 10 信息: 普通輸出 11 四月 10, 2014 4:44:43 下午 LoggerTest main 12 信息: 普通輸出 13 四月 10, 2014 4:44:43 下午 LoggerTest main 14 配置: 配置信息 15 四月 10, 2014 4:44:43 下午 LoggerTest main 16 詳細: 日誌信息 17 四月 10, 2014 4:44:43 下午 LoggerTest main 18 較詳細: 日誌信息 19 四月 10, 2014 4:44:43 下午 LoggerTest main 20 很是詳細: 日誌信息
【log4j】
再學習一個常見的日誌框架,log4j。先看個例子。
1、例子
1. LoggerTest.java
1 import java.util.logging.Level; 2 3 import org.apache.log4j.Logger; 4 5 public class LoggerTest { 6 public static void main(String []args){ 7 //獲取Logger實例,參數爲本類 8 Logger logger=Logger.getLogger(LoggerTest.class); 9 logger.debug("debuging");//輸出一段DEBUG信息 10 logger.info("info..."); //輸出一段INFO信息 11 logger.error("error..."); //輸出一段ERROR錯誤信息 12 logger.fatal("fatal"); 13 logger.warn("warn"); 14 } 15 }
2. log4j.properties
1 #此屬性指定日誌等級等於或低於INFO的日誌信息輸出到名爲stdout的目的地 2 log4j.rootCategory=INFO, stdout 3 #此屬性執行stdout這個輸出目的地類型爲控制檯 4 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 #此屬性指定輸出日誌的佈局類,這裏採用LOG4J默認的佈局類 6 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
3. 結果
1 info... 2 error... 3 fatal 4 warn
4. 注意事項
須要把log4j-1.2.16.jar導入
2、log4j的結構
(一) log4j的構成
(二) log4j包含類的意義
3、.properties配置信息
Log4j由三個重要的組件構成:日誌信息的優先級,日誌信息的輸出目的地,日誌信息的輸出格式。日誌信息的優先級從高到低有ERROR、WARN、 INFO、DEBUG,分別用來指定這條日誌信息的重要程度;日誌信息的輸出目的地指定了日誌將打印到控制檯仍是文件中;而輸出格式則控制了日誌信息的顯示內容。
在.properties進行配置的時候,也是針對日誌信息的優先級,日誌信息的輸出目的地,日誌信息的輸出格式進行配置。
1. 配置根Logger
例子中,properties文件中的第一句就是配置這個。
1 log4j.rootLogger = level,appenderName1,appenderName2, ···
其中,level 是日誌記錄的優先級,分爲OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定義的級別。Log4j建議只使用四個級別,優先級從高到低分別是ERROR、WARN、INFO、DEBUG。經過在這裏定義的級別,您能夠控制到應用程序中相應級別的日誌信息的開關。好比在這裏定義了INFO級別,則應用程序中全部DEBUG級別的日誌信息將不被打印出來。 appenderName就是指B日誌信息輸出到哪一個地方。您能夠同時指定多個輸出目的地。優先級:ALL < DEBUG < INFO <WARN < ERROR < FATAL < OFF
2. 配置日誌信息輸出目的地Appender
1 log4j.appender.appenderName = Log4j提供的appender類 2 log4j.appender.appenderName.屬性名 = 屬性值 3 ··· 4 log4j.appender.appenderName.屬性名 = 屬性值
其中,Log4j提供的appender有如下幾種:
1 org.apache.log4j.ConsoleAppender(控制檯), 2 org.apache.log4j.FileAppender(文件), 3 org.apache.log4j.DailyRollingFileAppender(天天產生一個日誌文件), 4 org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件), 5 org.apache.log4j.WriterAppender(將日誌信息以流格式發送到任意指定的地方)
1) ConsoleAppender選項
Threshold=WARN:指定日誌消息的輸出最低層次。
ImmediateFlush=true:默認值是true,意謂着全部的消息都會被當即輸出。
Target=System.err:默認狀況下是:System.out,指定輸出控制檯
2) FileAppender 選項
Threshold=WARN:指定日誌消息的輸出最低層次。
ImmediateFlush=true:默認值是true,意謂着全部的消息都會被當即輸出。
File=mylog.txt:指定消息輸出到mylog.txt文件。
Append=false:默認值是true,即將消息增長到指定文件中,false指將消息覆蓋指定的文件內容。
3) DailyRollingFileAppender 選項
Threshold=WARN:指定日誌消息的輸出最低層次。
ImmediateFlush=true:默認值是true,意謂着全部的消息都會被當即輸出。
File=mylog.txt:指定消息輸出到mylog.txt文件。
Append=false:默認值是true,即將消息增長到指定文件中,false指將消息覆蓋指定的文件內容。
DatePattern=''.''yyyy-ww:每週滾動一次文件,即每週產生一個新的文件。
固然也能夠指定按月、周、天、時和分。即對應的格式以下:
4) RollingFileAppender 選項
Threshold=WARN:指定日誌消息的輸出最低層次。
ImmediateFlush=true:默認值是true,意謂着全部的消息都會被當即輸出。
File=mylog.txt:指定消息輸出到mylog.txt文件。
Append=false:默認值是true,即將消息增長到指定文件中,false指將消息覆蓋指定的文件內容。
MaxFileSize=100KB: 後綴能夠是KB, MB 或者是 GB. 在日誌文件到達該大小時,將會自動滾動,即將原來的內容移到mylog.log.1文件。
MaxBackupIndex=2:指定能夠產生的滾動文件的最大數。
3. 配置日誌信息的格式(佈局)
1 log4j.appender.appenderName.layout = Log4j提供的layout類 2 log4j.appender.appenderName.layout.屬性 = 值 3 ••• 4 log4j.appender.appenderName.layout.屬性 = 值 Log4j
其中,Log4j提供的layout有如下幾種:
1 org.apache.log4j.HTMLLayout(以HTML表格形式佈局), 2 org.apache.log4j.PatternLayout(能夠靈活地指定佈局模式), 3 org.apache.log4j.SimpleLayout(包含日誌信息的級別和信息字符串), 4 org.apache.log4j.TTCCLayout(包含日誌產生的時間、線程、類別等等信息)
1) HTMLLayout選項
LocationInfo=true:默認值是false,輸出java文件名稱和行號
Title=my app file: 默認值是 Log4J Log Messages.
2) PatternLayout選項
ConversionPattern=%m%n :指定怎樣格式化指定的消息。
3) XMLLayout選項
LocationInfo=true:默認值是false,輸出java文件和行號
Log4J採用相似C語言中的printf函數的打印格式格式化日誌信息,打印參數以下:
1 og4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n
這裏須要說明的就是日誌信息格式中幾個符號所表明的含義:
-X號: X信息輸出時左對齊;
%p: 輸出日誌信息優先級,即DEBUG,INFO,WARN,ERROR,FATAL,
%d: 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也能夠在其後指定格式,
好比:%d{yyy MMM dd HH:mm:ss,SSS},輸出相似:2002年10月18日 22:10:28,921
%r: 輸出自應用啓動到輸出該log信息耗費的毫秒數
%c: 輸出日誌信息所屬的類目,一般就是所在類的全名
%t: 輸出產生該日誌事件的線程名
%l: 輸出日誌事件的發生位置,至關於%C.%M(%F:%L)的組合,包括類目名、發生的線程,以及行數。
舉例:Testlog4.main(TestLog4.java:10)
%x: 輸出和當前線程相關聯的NDC(嵌套診斷環境),尤爲用到像java servlets這樣的多客戶多線程的應用中。
%%: 輸出一個"%"字符
%F: 輸出日誌消息產生時所在的文件名稱
%L: 輸出代碼中的行號
%m: 輸出代碼中指定的消息,產生的日誌具體信息
%n: 輸出一個回車換行符,Windows平臺爲"\r\n",Unix平臺爲"\n"輸出日誌信息換行
能夠在%與模式字符之間加上修飾符來控制其最小寬度、最大寬度、和文本的對齊方式。如:
4、xml配置信息
詳細內容見例子:
1. LoggerTest.java
1 import org.apache.log4j.Logger; 2 3 public class LoggerTest { 4 private static final Logger log = Logger.getLogger(LoggerTest.class); 5 public static void main(String[] args) { 6 log.info("Enter the main()...."); 7 log.debug("Enter the main()...."); 8 log.warn("Enter the main()...."); 9 log.info("Enter the main()...."); 10 System.out.println("this is a log4j test."); 11 log.info("log end."); 12 } 13 }
2. log4j.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> 3 <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> 4 5 <!-- ========================== 自定義輸出格式說明================================ --> 6 <!-- %p 輸出優先級,即DEBUG,INFO,WARN,ERROR,FATAL --> 7 <!-- %r 輸出自應用啓動到輸出該log信息耗費的毫秒數 --> 8 <!-- %c 輸出所屬的類目,一般就是所在類的全名 --> 9 <!-- %t 輸出產生該日誌事件的線程名 --> 10 <!-- %n 輸出一個回車換行符,Windows平臺爲「/r/n」,Unix平臺爲「/n」 --> 11 <!-- %d 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也能夠在其後指定格式,好比:%d{yyy MMM dd HH:mm:ss,SSS},輸出相似:2002年10月18日 22:10:28,921 --> 12 <!-- %l 輸出日誌事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main(TestLog4.java:10) --> 13 <!-- ========================================================================== --> 14 15 <!-- ========================== 輸出方式說明================================ --> 16 <!-- Log4j提供的appender有如下幾種: --> 17 <!-- org.apache.log4j.ConsoleAppender(控制檯), --> 18 <!-- org.apache.log4j.FileAppender(文件), --> 19 <!-- org.apache.log4j.DailyRollingFileAppender(天天產生一個日誌文件), --> 20 <!-- org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件), --> 21 <!-- org.apache.log4j.WriterAppender(將日誌信息以流格式發送到任意指定的地方) --> 22 <!-- ========================================================================== --> 23 <!-- 輸出到日誌文件 --> 24 <!-- 設置通道file和輸出方式:org.apache.log4j.RollingFileAppender --> 25 <appender name="FILE" class="org.apache.log4j.RollingFileAppender"> 26 <!-- 設置File參數:日誌輸出文件名 --> 27 <param name="File" value="D:/logxml/test_log4j_debug.log"/> 28 <!-- 設置是否在從新啓動服務時,在原有日誌的基礎添加新日誌 --> 29 <param name="Append" value="true"/> 30 <param name="MaxFileSize" value="5KB"/> 31 <param name="MaxBackupIndex" value="2"/> 32 <layout class="org.apache.log4j.PatternLayout"> 33 <!-- 設置輸出文件項目和格式 --> 34 <param name="ConversionPattern" value="%c %d{ISO8601}-- %p -- %m%n"/> 35 </layout> 36 <filter class="org.apache.log4j.varia.LevelRangeFilter"> 37 <param name="LevelMin" value="DEBUG"/> 38 <param name="LevelMax" value="DEBUG"/> 39 </filter> 40 </appender> 41 <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> 42 <layout class="org.apache.log4j.PatternLayout"> 43 <param name="ConversionPattern" value="%c %d{ISO8601}-- %p -- %m%n"/> 44 </layout> 45 <filter class="org.apache.log4j.varia.LevelRangeFilter"> 46 <param name="LevelMin" value="INFO"/> 47 <param name="LevelMax" value="INFO"/> 48 </filter> 49 </appender> 50 <root> 51 <priority value="debug"/> 52 <appender-ref ref="FILE" /><!-- 與前面的通道id相對應 --> 53 <appender-ref ref="STDOUT" /> 54 </root> 55 </log4j:configuration>
3. 運行結果:
在控制檯中輸出結果:
1 LoggerTest 2014-04-11 16:20:17,683-- INFO -- Enter the main().... 2 LoggerTest 2014-04-11 16:20:17,684-- INFO -- Enter the main().... 3 this is a log4j test. 4 LoggerTest 2014-04-11 16:20:17,684-- INFO -- log end.
在D:/logxml/test_log4j_debug.log輸出結果:
1 LoggerTest 2014-04-11 16:20:17,684-- DEBUG -- Enter the main()....
【參考資料】
1. java日誌詳解
2. JAVA應用開發日志解決方案
3. log4j入門、詳解
【後面的話】
好好學習。
——TT