Log4j2常見使用示例及Syslog/Syslog-ng

準備工做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" 「截留」。

 

經常使用AppenderRollingFile

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.

 

經常使用AppenderSyslog

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

 

SyslogSyslog-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月

相關文章
相關標籤/搜索