一、日誌概述
- 日誌的原理
通過一個標誌位debug控制輸出。
這時的輸出便是可控的,但只有兩個級別:輸出與不輸出。
debug爲false時不輸出,debug爲true時輸出。
Log4j等日誌工具也都是這個原理,但增加了很多的輸出級別。輸出級別、輸出樣式、
輸出目的地都可以在配置文件中配置,而不是寫在程序中,增加了靈活性。 - JDK1.4的Logging
JDK Logging把日誌分爲幾個級別:ALL、FINEST、FINER、FINE、
CONFIG、INFO、WARNING、SEVERE、OFF等,級別依次升高。
如果將級別設爲INFO,則INFO之前的低級別信息將不會輸出,
只有INFO級別之後的信息會輸出,通過控制級別達到控制輸出的目的。
Logger log = Logger.getLogger(classString); // JDK日誌
Handler console = new ConsoleHandler(); // 添加一個控制檯輸出
console.setLevel(Level.INFO); // 設置控制檯級別爲INFO
log.addHandler(console); // 添加到log中
log.setLevel(Level.INFO); // 設置log級別爲INFO
log.info("info") // info輸出 - Log4J控件
Log4J是目前應用最廣泛的日誌控件,它把日誌分爲ALL、TRACE(跟蹤)、DEBUG(調試)、
INFO(信息)、WARNING(警告)、ERROR(錯誤)、FITAL(致命)、OFF等幾個級別,
級別依次升高。級別高的Level會屏蔽級別低的信息。
如果設置爲WARNING,則TRACE、DEBUG、INFO都不會輸出。
注意添加Log4J的類庫。
日誌的配置例如輸出級別、輸出到哪兒、輸出什麼附加信息、輸出格式(包括時間、
類名、輸出級別以及日誌信息)等,一般都寫在配置文件log4j.properties中。
Log4J的使用十分靈活,功能也很強大。可以在配置文件中配置輸出樣式,
可以把日誌輸出到屏幕、控制檯、各種樣式的文件、數據庫、FTP服務器、HTTP服務器、
遠程實時監控程序、Windows NT系統日誌、發送郵件到指定郵箱、甚至發送短信等。 - commons-logging控件
commons-logging是Apache commons類庫中的一員。
commons-logging能夠選擇使用Log4J還是JDK Logging,
但不依賴於Log4J、JDK Logging的API。
如果項目的classpath中包含log4j的類庫,則使用log4j,否則使用JDK Logging。
使用commons-logging能夠靈活的選擇使用哪種日誌方式,而不需要修改源代碼。
commons-logging的使用類似於Log4J,它們的級別及使用規則是完全一樣的。
默認地,commons-logging會自動檢查是否使用log4j。也可以使用配置文件顯示地啓用log4j。
配置文件爲commons-logging.properties,放到程序的classpath下即可。
二、Log4J控件
- Log4j概述
- Log4j的執行效率
Log4j內部做了大量的優化、緩存工作,
使輸出時對服務器的壓力、消耗的時間、資源等都達到最小。
Log4j只在初始化的時候打開文件,並保持對文件的寫控制,直到系統
結束的時候才關閉文件。這樣就使I/O次數達到最小,提高了運行效率。
而當輸出級別設爲ERROR時,log.debug()、log.warning()方法
會因爲輸出級別小於ERROR而直接返回,因此不會消耗太多的資源。 - 優化日誌代碼
- Log4j.properties配置文件
Log4j默認的配置文件爲log4j.properties。啓動時,
會加載classpath下的log4j.properties初始化Log4j。 - 使用其他配置文件
如果不使用默認的文件名log4j.properties,
可以使用PropertyConfigurator指定配置文件路徑。
PropertyConfigurator.configure("src/Log4jConfigTest.properties"); - Log4j.xml配置文件
Lot4j也可以使用XML文件配置
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{HH:mm:ss} %5p %c{1} %m%n" />
</layout>
</appender>
XML配置需要遵循Log4j的格式。
三、日誌記錄器Logger
- Log4j配置中有3個重要的概念:
日誌記錄器(Logger)、輸出地(Appender)以及日誌格式化器(Layout)。
其中,Logger負責記錄日誌,Appender負責輸出到什麼地方,Layout負責
以什麼格式輸出、輸出哪些附加信息(例如時間、類名、方法名、所在行數等)。 - 日誌記錄器Logger
Logger就是Java代碼中的Logger。
public Logger log = Logger.getLogger(Log4jConfigTest.class);
Logger是有名字的,它的名字便是Logger.getLogger()方法的參數。
如果參數爲所在的類,Log4j會取類名作爲Logger的名稱。
Logger爲單態模式:相同名字的Logger只會有一個實例。
如果在構建一個同名的Logger,Log4j會返回先前的Logger實例。
命名規則:一般都以類名作爲Logger的名稱。Logger的名字類似於
Java中的Package名字,大小寫敏感、用點分開且具有繼承關係。
Log4j中有一個根記錄器rootLogger,它是所有Logger的父親。 - Logger的配置
在log.properties配置中,log4j.logger後面配置的是Logger,
log4j.appender後面配置的是Appender。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, A1 - rootLogger配置
根記錄器rootLogger直接用log4j.rootLogger配置。
rootLogger是所有記錄器的父親。任何記錄其都可繼承rootLogger的配置。
log4j.rootLogger=ERROR, A1 - 類別category配置
Logger還有個類別(Category)的概念,通過設置類別來設置類別下所有的Logger:
log4j.category.com.xxx=DEBUG
四、輸出地Appender
- Appender表示日誌輸出到什麼地方,常用的輸出地有控制檯、文件、數據庫、遠程服務器等。
Log4j中內置了常用的輸出地,一般情況下配置一下即可使用。
所有的Appender都實現自org.apache.log4j.Appender接口。
在log4j.properties中,Appender都使用log4j.appender.*配置。 - 輸出到控制檯
控制檯是最常用的輸出地。控制檯輸出實現類爲org.apache.log4j.ConsoleAppender。
log4j.rootLogger=ERROR, A1
log4j.category.com.xxx=DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.Threshold=DEBUG
log4j.appender.A1.Encoding=UTF-8
log4j.appender.A1.ImmediateFlush=true
log4j.appender.A1.Target=System.err
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=
%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%P] %m%n
控制檯輸出需要配置layout屬性,最常用的是正則表達式格式。
Encoding設置編碼方式,ImmediateFlush設置是否緩存,
Target設置輸出到System.out還是System.err。
Threhold用來設置該Appender的級別,只對本Appender生效。 - 輸出到文件
文件輸出(FileAppender)把日誌輸出到指定的文件。
文件輸出的實現類爲org.apache.log4j.FileAppender,
配置時需要用File指定文件名稱。可以使用相對路徑,也可以使用絕對路徑。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, f
log4j.appender.f=org.apache.log4j.FileAppender
log4j.appender.f.File=C:\\tomcat.log
log4j.appender.f.Appender=true
log4j.appender.f.layout=org.apache.log4j.PatternLayout
log4j.appender.f.layout.ConversionPattern=
%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%P] %m%n
可選參數Append配置是否在源文件內容的基礎上追加日誌。
如果爲false,Logger初始化時會先清掉文件內容,也就是說每次重啓程序,
原來的日誌會丟失。如果爲true,日誌文件會越來越大。默認爲true。 - 輸出到按大小滾動的文件
按大小滾動文件輸出(RollingFileAppender)把日誌輸出到指定的文件,
文件達到指定的大小時,會自動更名。按尺寸滾動文件輸出類爲
org.apache.log4j.RollingFileAppender,需配置文件名稱、文件的最大尺寸。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, f, rolling_file
log4j.appender.rolling_file=org.apache.log4j.RollingFileAppender
log4j.appender.rolling_file.Threshold=DEBUG
log4j.appender.rolling_file.File=C:\\rolling.log
log4j.appender.rolling_file.Appender=true
log4j.appender.rolling_file.MaxFileSize=10KB
log4j.appender.rolling_file.MaxBackupIndex=100
log4j.appender.rolling_file.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling_file.layout.ConversionPattern=
%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%P] %m%n
配置的滾動文件名爲rolling.log,文件最大爲10K。當rolling.log達到10K時,
會自動更名爲rolling.log.1、rolling.log.2...直到rolling.log.100。
Logger支持多個Appender,用逗號將多個Appender名字隔開即可。 - 輸出到按日期滾動文件
按日期滾動文件輸出(DailyRollingFileAppender)將日誌輸出到指定的文件,
當日期發生變化時,會將文件按指定的日期格式自動改名。
日期滾動文件輸出類爲org.apache.log4j.DailyRollingFileAppender。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, dailly_rolling
log4j.appender.dailly_rolling=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailly_rolling.File=C:\\daily_rolling.log
log4j.appender.dailly_rolling.DatePattern=.yyyy-MM-dd
log4j.appender.dailly_rolling.layout=org.apache.log4j.PatternLayout
log4j.appender.dailly_rolling.layout.ConversionPattern=
%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%P] %m%n
日誌文件名稱爲daily_rolling.log,日期格式爲yyyy-MM-dd。進入新的一天後,
文件會被自動更名,格式爲daily_rolling.log.yyyy-MM-dd。 - 輸出到JDBC數據庫
數據庫輸出(JDBCAppender)通過JDBC連接把日誌輸出到數據庫中。
配置時需要配置JDBC驅動、連接字符串、用戶名、密碼以及SQL語句。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, DATABASE
log4j.appender.DATABASE=org.apache.log4j.JDBCAppender
log4j.appender.DATABASE.Threshold=ERROR
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/log4j
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=admin
log4j.appender.DATABASE.sql=INSERT INTO tb_log(
data, priority, message, classname) VALUES('%d', '%p', '%m', '%c')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=%m
配置的關鍵是SQL語句。Log4j能夠取到各種環境數據,
包括時間、級別、類名、文件名、方法名、所在行數等。 - 輸出到SOCKET套接字
套接字輸出(SocketAppender)將日誌通過網絡TCP協議發送給遠程的服務器。
SocketAppender會與遠程服務器建立Socket連接,將日誌信息封裝爲
LoggingEvent對象,串行化(Serialize)後發送給對方。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, SOCKET
log4j.appender.SOCKET=org.apache.log4j.SocketAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=2008
log4j.appender.SOCKET.ReconnectionDelay=30000
log4j.appender.SOCKET.LocationInfo=true
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCKET.layout.ConversionPattern=%m
可選參數LocationInfo配置是否發送本地信息給服務器。
ReconectionDelay配置如果連接失敗,多少毫秒後重新連接。
用戶可以使用SocketServer自己編寫一個服務器端,
在某個特定的端口監聽,接收Log4j發送的日誌並實時顯示。
Log4j自帶一個簡單的服務器,用來接收SocketAppender發送的數據。
該程序只是簡單的將接受到的數據輸出到文件。
import org.apache.log4j.net.SimpleSocketServer;
public class RunSimpleSocketServer {
public static void main(String[] args) {
String port = "2008";
String file = "C:\\socket.log";
SimpleSocketServer.main(new String[] {port, file});
// 啓動SimpleSocketServer
}
}
SimpleSocketServer啓動後便在2008端口等待。
如果有Log4j連接,則接收日誌,並記錄到C:\\socket.log中。 - 輸出到SMTP郵件
郵件輸出(SMTPAppender)將日誌以郵件的形式發送出去,配置時需要配置
郵件服務器地址、用戶名、密碼、發件人郵箱、收件人郵箱等。
發送郵件需要Java Mail的支持。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, MAIL
log4j.appender.MAIL=org.apache.log4j.SMTPAppender
log4j.appender.MAIL.BufferSize=512
log4j.appender.MAIL.SMTPHost=smtp.163.com
log4j.appender.MAIL.Subject=Log4j Error Message
log4j.appender.MAIL.SMTPUsername=your_username
log4j.appender.MAIL.SMTPPassword=your_password
[email protected]
[email protected]
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=%m
SMTPappender默認的輸出級別爲ERROR。 - 自定義輸出
Log4j支持自定義的輸出。所有的輸出都實現自Appender接口。一般來說,
自定義輸出值需要繼承AppenderSkeleton類,並實現幾個方法就可以了。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, COUNTING
log4j.appender.COUNTING=org.apache.log4j.CountingConsoleAppender
log4j.appender.COUNTING.limit=10
log4j.appender.COUNTING.layout=org.apache.log4j.PatternLayout
log4j.appender.COUNTING.layout.ConversionPattern=%m
設定輸出次數爲10。當輸出次數超過10後,
該自定義Appender會輸出信息後並停止輸出。
五、日誌格式化器Layout
- 日誌格式化器Layout負責格式化日誌信息。方法log.error()的參數值包含日誌信息,
利用Layout可以附加其他信息,以輸出更多的信息或者佈局顯示。 - PatternLayout
PatternLayout是最常用的格式化器,用戶可以自定義輸出信息,例如日期、
時間、所在的線程、類名、文件名、方法名、信息級別、文件行數等。
Log4j的常用參數
c 輸出Logger所在的類別(即Logger的名字)。
允許使用%c{數字}輸出部分的名稱(從右邊往左邊數)。
C 輸出Logger所在類的名稱。
有時候Logger的名稱不同於類名。
d 輸出日期。允許使用%d{yyyy-MM-dd HH:mm:ss}格式化日期。
%d不僅支持JDK SimpleDateFormat的日期格式,
還支持自己的日期格式。
F 輸出所在的類文件名稱
l 輸出語句所在的行數,包括類名、方法名、文件名、行數等。
L 輸出語句所在的行數,只輸出數字。
m 輸出日誌
M 輸出方法名
n 換行。Windows下輸出\r\n,Linux下輸出\n。
p 輸出日誌級別
r 輸出從程序啓動到輸出該日誌之間的時間間隔,單位毫秒。
t 輸出當前的線程名稱
% %%用來輸出百分號
Log4j允許設置輸出內容的長度等,不夠長會用空格補齊,使輸出內容變得整齊。
設置方法是在%與參數符號間添加數字,例如%20p、%-20p等。
正數表示右對齊,負數表示左對齊,數字表示最小寬度,不足時用空格補齊。
還可以設置最大寬度,如果超出,則截取,方法是用小數點+數字設置,例如%.30p。 - HTMLLayout佈局
HTMLLayout將日誌格式化爲HTML代碼,輸出到文件後,可以直接用瀏覽器瀏覽。
使用HTMLLayout時,日誌文件後綴一般爲.html。
log4j.rootLogger=DEBUG, f
log4j.appender.f=org.apache.log4j.FileAppender
log4j.appender.f.File=C:\\log.html
log4j.appender.f.Appender=false
log4j.appender.f.layout=org.apache.log4j.HTMLLayout - XMLLayout佈局
XMLLayout把日誌內容格式化爲XML文件。XML文件的好處是解析比較容易,
有現成的DOM技術與SAX技術。XMLLayout的配置如下:
log4j.rootLogger=DEBUG, f
log4j.appender.f=org.apache.log4j.FileAppender
log4j.appender.f.File=C:\\abc.log
log4j.appender.f.Encoding=UTF-8
log4j.appender.f.Appender=false
log4j.appender.f.layout=org.apache.log4j.XMLLayout
XMLLayout生成的並不是完整的XML文件,而只是XML文件的一部分,
因此是無法直接打開、解析的。其中包含一系列的<log4j:event>標籤。
可以在XML文檔中引入文檔類型名稱爲log4j:eventSet的外部DTD文件,
並設置實體標籤引入[<!ENTITY data SYSTEM "abc.log"]xml文件,
然後data置於<log4j:eventSet>標籤裏面:
<log4j:eventSet>&data;</log4j:eventSet>。