準備工做html
打開http://logging.apache.org/log4j/,點擊左側Download,我下載的是Apache Log4j 2 binary (zip),目前是2.0.2版本。解壓後有30幾個jar包,大部分是跟兼容性及移植性相關的可選組件,咱們要用的是:java
log4j-api-2.0.2.jar程序員
log4j-core-2.0.2.jarapache
第一個示例程序api
log4j2.xml服務器
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="warn"> 3 <Appenders> 4 <Console name="Console" target="SYSTEM_OUT"> 5 <PatternLayout pattern="%m%n" /> 6 </Console> 7 </Appenders> 8 <Loggers> 9 <Root level="INFO"> 10 <AppenderRef ref="Console" /> 11 </Root> 12 </Loggers> 13 </Configuration>
解釋一下Configuration後面的status,這個用於設置log4j2自身內部的信息輸出,能夠不設置,當設置成trace時,你會看到log4j2內部各類詳細輸出。app
log4j2配置文件可使用XML或JSON,彷佛 再也不支持properties文件了。默認的文件名也有所不一樣,log4j2.xml,再也不是log4j.xml。大數據
log4j2.xml能夠放在任意的地方,只要你最後把它放到了classpath裏,上面的項目中新建一個resources目錄用於放置log4j2.xml,若是在未加入classpath時嘗試運行時會報以下錯誤:spa
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.rest
以Eclipse環境爲例,能夠在Run—Run Configurations對應項目的Classpath中選擇User Entries,點擊Advanced,選擇Add Folder,把resources文件夾添加進來。
Log4jTest.java
1 package mh.sample; 2 3 import org.apache.logging.log4j.LogManager; 4 import org.apache.logging.log4j.Logger; 5 6 public class Log4jTest { 7 static Logger log = LogManager.getLogger( Log4jTest.class.getName()); 8 9 public static void main(String[] args) { 10 log.info("This is an info log."); 11 log.warn("This is a warn log."); 12 } 13 }
須要注意的是,log4j2中要用LogManager.get logger,而不是之前的Logger.getLogger
運行此類,能夠看到控制檯輸出兩條日誌信息:
This is an info log.
This is a warn log.
經過將配置文件中的level改成」WARN」,能夠看到只有一條日誌了:
This is a warn log.
關於level的事就這麼簡單,很少解釋了。
關於pattern,詳見:http://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout
好比經常使用的是
[%-5p] %d %c - %m%n
若是使用此pattern,輸出將相似以下:
[INFO ] 2014-08-29 16:18:15,066 mh.sample.Log4jTest - This is an info log.
[WARN ] 2014-08-29 16:18:15,069 mh.sample.Log4jTest - This is a warn log.
5表示自動將level級別補空格至5個字符
第二個示例程序
Log4j2.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="warn"> 3 <Appenders> 4 <Console name="Console" target="SYSTEM_OUT"> 5 <PatternLayout pattern="[%-5p] %d %c - %m%n" /> 6 </Console> 7 <File name="File" fileName="dist/my.log"> 8 <PatternLayout pattern="%m%n" /> 9 </File> 10 </Appenders> 11 12 <Loggers> 13 <Logger name="mh.sample2.Log4jTest2" level="INFO"> 14 <AppenderRef ref="File" /> 15 </Logger> 16 <Root level="INFO"> 17 <AppenderRef ref="Console" /> 18 </Root> 19 </Loggers> 20 </Configuration>
在配置文件中我新加了一個Appender,
<File name="File" fileName="dist/my.log">
<PatternLayout pattern="%m%n" />
</File>
另外,新加了一個Logger,
<Logger name="mh.sample2.Log4jTest2" level="INFO">
<AppenderRef ref="File" />
</Logger>
Log4jTest.java
public class Log4jTest { static Logger log = LogManager.getLogger( Log4jTest.class.getName()); public static void main(String[] args) { log.info("This is an info log."); log.warn("This is a warn log."); // Log4jTest2 lt2 = new Log4jTest2(); lt2.printLog(); } }
Log4jTest2.java
1 public class Log4jTest2 { 2 3 static Logger log = LogManager.getLogger( Log4jTest2.class.getName()); 4 5 public void printLog(){ 6 log.info("This is an info log from Log4jTest2."); 7 log.warn("This is a warn log from Log4jTest2."); 8 } 9 }
運行起來,控制檯的輸出是,
[INFO ] 2014-08-29 17:16:39,899 mh.sample.Log4jTest - This is an info log.
[WARN ] 2014-08-29 17:16:39,901 mh.sample.Log4jTest - This is a warn log.
[INFO ] 2014-08-29 17:16:39,903 mh.sample2.Log4jTest2 - This is an info log from Log4jTest2.
[WARN ] 2014-08-29 17:16:39,904 mh.sample2.Log4jTest2 - This a is warn log from Log4jTest2.
項目下dist/my.log文件中的內容是,
This is an info log from Log4jTest2.
This is a warn log from Log4jTest2.
能夠看到,Root老是輸出全部。而新添加的logger負責把Log4jTest2中的日誌寫到指定文件。這個特性有利於在比較大的項目中對日誌進行分類。
須要注意的一點是,log4j存在一個「反直覺」的行爲,嘗試把Root的level改成「WARN」,從新運行,控制檯的輸出是:
[WARN ] 2014-08-29 17:24:06,788 mh.sample.Log4jTest - This is a warn log.
[INFO ] 2014-08-29 17:24:06,793 mh.sample2.Log4jTest2 - This is an info log from Log4jTest2.
[WARN ] 2014-08-29 17:24:06,794 mh.sample2.Log4jTest2 - This is a warn log from Log4jTest2.
Log4jTest2中的info級別的log仍是被輸出了,也就是,只要某個logger接受了該log請求,那爲做爲父親的Root就會跟着接受此log請求,而再也不考慮它的level
順帶介紹additivity屬性,
<Logger name="mh.sample2.Log4jTest2" level="INFO" additivity="false">
做了上面的修改,再運行程序,控制檯的輸出:
[WARN ] 2014-08-29 17:31:17,388 mh.sample.Log4jTest - This is a warn log.
因此additivity實際上停止了log請求向上級傳播,這致使了Log4jTest2中的日誌被Logger name="mh.sample2.Log4jTest2" 「截留」。
經常使用Appender之RollingFile
Log4j2.xml
<Configuration status="warn"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="[%-5p] %d %c - %m%n" /> </Console> <File name="File" fileName="dist/my.log"> <PatternLayout pattern="%m%n" /> </File> <RollingFile name="RollingFile" fileName="dist/my2.log" filePattern="dist/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="[%-5p] %d %c - %m%n" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="25 KB" /> </Policies> <DefaultRolloverStrategy max="20"/> </RollingFile> </Appenders> <Loggers> <Logger name="mh.sample2.Log4jTest2" level="INFO" additivity="false"> <AppenderRef ref="File" /> <AppenderRef ref="RollingFile" /> </Logger> <Root level="WARN"> <AppenderRef ref="Console" /> </Root> </Loggers> </Configuration>
上述RollingFile的配置將把日誌內容追加到dist/my2.log文件中,每當大小達到設定的25KB,就會按filePattern的規則備份到dist目錄下的子目錄中,因爲當前是2014年9月3號,該子目錄名稱是2014-09,裏面的文件則是app-09-03-2014-1.log.gz,app-09-03-2014-2.log.gz,app-09-03-2014-3.log.gz,……,從這還能夠看出,log4j2自動按你配置的文件名進行gzip壓縮。
DefaultRolloverStrategy屬性如不設置,則默認爲最多同一文件夾下7個文件,這裏設置了20.
經常使用Appender之Syslog
log4j2中對syslog的簡單配置,這裏就不重複展現log4j2.xml了:
<Syslog name="SYSLOG" host="localhost" port="514" protocol="UDP" facility="LOCAL3"/>
host是指你將要把日誌寫到的目標機器,能夠是ip(本地ip或遠程ip,遠程ip在實際項目中很常見,有專門的日誌服務器來存儲日誌),也可使用主機名,若是是本地,還可使用localhost或127.0.0.1
Port指定端口,默認514,參見/etc/rsyslog.conf(以Fedora系統爲例,下同)。protocol指定傳輸協議,這裏是UDP,facility是可選項,後面能夠看到用法,具體關於facility的規則能夠點擊:http://logging.apache.org/log4j/2.x/manual/appenders.html#SyslogAppender
Syslog及Syslog-ng相關配置(Fedora)
在運行程序以前,須要修改
/etc/rsyslog.conf
把這兩行前的#去掉,即取消註釋:
#$ModLoad imudp
#$UDPServerRun 514
這裏啓用udp監聽,514是默認監聽端口,重啓syslog:
service syslog restart
大部分日誌會默認寫到/var/log/messages中,若是不想寫到這個文件裏,能夠按下面修改,這樣local3的日誌就會寫到app.log中。這裏的local3即 log4j2.xml中facility的配置。
*.info;mail.none;authpriv.none;cron.none;local3.none /var/log/messages
新增一行
local3.* /var/log/app.log
除了使用自帶的syslog,咱們也可使用syslog的替代品,好比syslog-ng,這對於log4j2.xml配置沒有影響。
安裝:
yum install syslog-ng
啓動:
service syslog-ng start
其配置文件爲
/etc/syslog-ng/syslog-ng.conf
啓動前把source一節中這一行取消註釋便可:
#udp(ip(0.0.0.0) port(514));
這個端口會和syslog衝突,可使用別的端口好比50014,同時修改log4j2.xml中的port屬性。另外提一下,使用非默認端口,要求log4j版本在1.2.15或以上。
syslog-ng自己也能夠設置把日誌送到遠程機器上,
在源機器上的syslog-ng.conf中添加:
destination d_remote1 { udp(153.65.171.73 port(514));};
這表示源機器上的syslog-ng會把接收到的日誌送到遠程主機153.65.171.73的514端口上,只要保證153.65.171.73上的syslog-ng正常運行並監聽對應的端口便可。
送書了,送書了,關注公衆號「程序員雜書館」,送出O'Reilly《Spark快速大數據分析》紙質書(亦有一批PDF分享)! —— 2018年12月
![]() |
![]() |