前言html
Appender按網絡釋義,有「輸出目的地」之意。官網給出的定義是:「Appenders are responsible for delivering LogEvents to their destination.」。Log4j2爲使用者提供了13種很是實用的Appenders,使用者可用方便的調用這13種Appender來控制日誌的輸出。java
摘要web
Log4j2的Appenders充分考慮了日誌事件的輸出、包裝以及過濾轉發的可能,包括最基本的輸出到本地文件、輸出到遠程主機,對文件進行封裝、注入,而且還能按照日誌文件的時間點、文件大小等條件進行自動封存。例如,想要將幾個不一樣源的日誌聚集到一塊兒,能夠用FlumeAppender;想要在LogEvent中注入信息,能夠用RewriteAppender;想要讓系統按照設定的時間間隔自動封存日誌信息,能夠用RollingFileAppender(每隔必定時間自動保存一份新增的日誌文件,並按照時間戳等指定格式命名);當產生安全級別達ERROR或FATAL的LogEvent時,給維護人員發送郵件可用SMTPAppender;但願將日誌信息寫到遠程主機的,可用SocketAppender;但願可以按照RFC5424格式向遠程主機發送日誌信息,可用SyslogAppender。等等。apache
下面將按照以下順序依次介紹每一個Appender的做用及重要參數,並附上完整參數地址及官網配置示例地址。api
目錄數組
一、FileAppender 普通地輸出到本地文件緩存
二、FlumeAppender 將幾個不一樣源的日誌聚集、集中到一處。安全
三、JMSQueueAppender VS. JMSTopicAppender 與JMS相關的日誌輸出服務器
四、RewriteAppender 對日誌事件進行掩碼或注入信息網絡
五、RollingFileAppender 對日誌文件進行封存(詳細)
六、RoutingAppender 在輸出地之間進行篩選路由
七、SMTPAppender 將LogEvent發送到指定郵件列表
八、SocketAppender 將LogEvent以普通格式發送到遠程主機
九、SyslogAppender 將LogEvent以RFC 5424格式發送到遠程主機
十、AsynchAppender 將一個LogEvent異步地寫入多個不一樣輸出地
十一、ConsoleAppender 將LogEvent輸出到命令行
十二、FailoverAppender 維護一個隊列,系統將嘗試向隊列中的Appender依次輸出LogEvent,直到有一個成功爲止
正文:
一、FileAppender
FileAppender用於將LogEvent寫入到一個文件中,該文件由fileName參數指定。有幾個重要的參數:
① fileName,String,指定寫入的log文件的名稱。
② append,boolean,指定是不是追加寫入(append=true,默認狀況),仍是覆蓋寫入(append=false)。
③ bufferedIO,boolean,是否對數據進行緩衝到緩衝區滿後再寫入。測試顯示,即便在啓用immediateFlush的狀況下,設置bufferedIO=true也能提升性能。
④ locking,boolean,是否對文件上鎖,當有多個線程可能同時寫該文件時須要考慮上鎖(在《異常處理反模式》中就提到要把在一塊兒的日誌輸出語句寫到一句,而不是拆成幾句來避免併發線程致使的日誌語句之間的錯位)。但對文件上鎖會影響系統的性能,因此須要謹慎使用。默認值是false。
二、FlumeAppender
FlumeAppender是一個可選的組件,它並不包含在core jar中,若要使用,須要額外加入log4j-flume-ng-2.0-beta4.jar包。FlumeAppender是配合Apache Flume來使用的。Apache Flume是一個能有效地將不一樣地方的大量日誌數據收集、聚會到一塊兒的一個系統。詳細信息參見【Apache Flume】
幾個比較重要的參數:
① agents,Agent[],用來維護一個將接收log event的數組,若是數組中agent的數量大於1,那麼將把第一個agent視爲primary agent,剩下的爲備選agent。當第一個agent沒法鏈接時,將把log event發送給備選agent。
② batchSize,integer,一次給agent發送的log event的個數。
③ compress,boolean,當設置爲true時,發送的message將使用gzip進行壓縮。
三、JMSQueueAppender VS. JMSTopicAppender
JMSQueueAppender的做用是將格式化的log event發送到JMSQueue上,一樣的,JMSTopicAppender的做用是將格式化的log event發送到JMSTopic上。JMSQueue和JMSTopic的區別是,JMSQueue只將一個message發送給一個consumer,而JMSTopic是將一個message發佈(publish)給全部訂閱了這個message的訂閱者(subscribe)。更詳細的二者間的區別能夠【戳這裏】
幾個重要的參數:
JMSQueueAppender:
① queueBindingName,String, 用來定位queue。
② factoryBindingName,String, 用來定位產生上下文信息的QueueConnectionFactory。
JMSTopicAppender:
① topicBindingName,String, 用來定位topic。
② factoryBindingName,String, 用來定位產生上下文信息的QueueConnectionFactory。
四、RewriteAppender
RewriteAppender可讓符合篩選條件的log event在被其餘appender輸出前被加工一下,好比對message中的密碼進行掩碼,或者向message中注入信息等。RewriteAppender須要一個RewritePolicy來指定重寫的規則。
幾個重要的參數:
① appender-ref,String,指定被重寫後的log event將發往哪一個appender。
② rewritePolicy,RewritePolciy,用來描述重寫log event的規則。
RewritePolicy:
RewritePolicy是一個接口,有一個須要實現的方法名爲rewrite,該方法接收一個log event對象做爲參數,而後通過函數處理後返回該log event或新建一個log event返回。
Log4j2中已實現的兩種RewritePolicy有MapRewritePolicy和PropertiesRewritePolicy。
【完整的參數設置、已實現的RewritePolicy和官方配置示例】
五、RollingFileAppender
RollingFileAppender是一個很是有意思的輸出器。它將log信息寫入一個文件後,會判斷是否知足封存文件的要求,若知足,則除非封存文件的動做。RollingFileAppender須要TriggeringPolicy來指定觸發封存的條件,另外還須要RolloverStrategy來告訴輸出器如何封存文件。
Log4j2中已提供的TriggeringPolicy有以下四種:
① CompositeTriggeringPolicy
複合型觸發策略。即將多個觸發條件邏輯或到一塊兒,只要其中一個條件知足,則觸發封存動做。
② OnStartup Triggering Policy
這一觸發策略不須要參數設置,它會自行判斷log文件的建立時間和JVM的啓動時間。若log文件的建立時間早於JVM的啓動時間,則將原來的log文件封存,而後建立一個新的空白log文件。
③ SizeBased Triggering Policy
這一觸發策略基於對log文件大小的判斷。當log文件大於設定的閾值時,將觸發封存動做。可設定的log文件大小的單位有bytes、KB、MB或GB。
④ TimeBased Triggering Policy
基於時間的觸發策略。該策略主要是完成周期性的log文件封存工做。有兩個參數:
interval,integer型,指定兩次封存動做之間的時間間隔。
modulate,boolean型,說明是否對封存時間進行調製。若modulate=true,則封存時間將以0點爲邊界進行偏移計算。好比,modulate=true,interval=4hours,那麼假設上次封存日誌的時間爲03:00,則下次封存日誌的時間爲04:00,以後的封存時間依次爲08:00,12:00,16:00,。。。
Log4j2中實現的RolloverStrategy爲Default Rollover Strategy,它有三個參數能夠設置,分別爲:
fileIndex,String,有兩個選擇「max」或「min」。設置爲「max」意味着將最新的日誌信息封存在序號較大的封存文件中。「min」則相反。
min,integer,封存文件的序號的起始值。
max,integer,封存文件的序號的最大值。(超過最大值時,將有文件被刪除)
至關於min和max兩個參數設置了一個保存窗口,超出這個窗口的日誌文件將會被刪除。
【完整的參數設置、TriggeringPolicy和RolloverStrategy的用法示例】
六、RoutingAppender
經過路由規則來評價一個log event後,決定它下一個被髮往的appender。RoutingAppender有一個重要的參數名爲routes,是Routes型數據,用來描述該appender的路由規則。
七、SMTPAppender
SMTPAppender主要用來給指定的E-mail發送log event(這種狀況通常用在event的安全級別超過ERROR或FATAL時,event的安全分級能夠參考【此文】之日誌記錄小節)。SMTPAppender有不少重要的參數以完成log event發送到指定E-mail。
① bcc,String,由逗號分隔的幾個盲抄送地址。(盲抄送就是說收件人的地址不會顯示在郵件信息中)
② cc,String,由逗號分隔的幾個明抄送地址。(明抄送就是說收件人的地址將顯示在郵件信息中)
③ bufferSize,integer,信中所能包含的最大log event的數量。
④ from,String,發件人的地址。
⑤ layout,Layout,log event的佈局格式。默認爲SerializedLayout。
⑥ replyTo,String,回信的地址。
⑦ smtpHost,String,要發送到的SMTP的主機名。(此參數是必需的)
⑧ smtpPassword,String,經過SMTP服務器所需的密碼。
⑨ smtpPort,integer,SMTP服務的端口號。
⑩ smtpProtocol,String,使用的協議。默認爲"smtp"。
其餘還有smtpUsername(經過SMTP server所需的用戶名),to(接收者的郵件地址)等。
八、SocketAppender
將log event輸出到一個遠程服務器上(需指定服務器名和端口號),數據能夠以任意指定的格式經由TCP或UDP協議發送。
SocketAppender中比較重要的參數有:
① host,String,指定服務器的主機名。(必需)
② immediateFlush,boolean,是否當即flush,仍是等待緩存到必定大小後在flush。
③ layout,Layout,log event輸出的格式。
④ port,integer,遠程服務器堅挺log event的應用的端口號。
⑤ protocol,String,發送log event所使用的協議,"TCP" 或"UDP"。
⑥ reconnectionDelay,integer,當鏈接斷開時,延遲等待的ms數。
九、SyslogAppender
SyslogAppender跟SocketAppender同樣,是將log event發送到遠程服務器上,可是使用的是BSD Syslog格式。關於Syslog格式能夠【戳這裏】
十、AsynchAppender
將一個LogEvent異步地寫入多個不一樣輸出地。在AsynchAppender中有一個參數,名爲「appender-ref」,用來指定要發送到的appender的名稱。AsynchAppender維護了一個隊列,隊列中存放了須要異步發送的LogEvent,隊列中LogEvent的個數能夠經過「bufferSize」參數來指定。另外,還有一個「blocking」參數來指定是否對AsynchAppender的LogEvent隊列上鎖,若是blocking=true,那麼在隊列滿員的狀況下,新到達的LogEvent將等待,直到有空位。若blocking=false,那麼在隊列滿員的狀況下,將把新到的LogEvent轉到error appender。
十一、ConsoleAppender
將LogEvent輸出到命令行。有兩個比較有意思的參數,一個是layout,用來指定輸出字串的格式(format);另外一個是target,用來指定輸出的是 "SYSTEM_OUT" 仍是 "SYSTEM_ERR",默認狀況下是"SYSTEM_ERR"。
十二、FailoverAppender
維護一個failover appenders隊列,系統先嚐試一個主appender(primary appender),若不成功,則嘗試failover隊列中的Appenders,直到有一個成功爲止,或都不成功。比較重要的參數有:
primary(String型):用來指定主appender的名稱。
failovers(String[]型):一個appender數組,指定的備選的其餘appenders。
retryInterval(integer型):用來設定隔多少秒從新嘗試主appender,默認爲60秒。
參考資料:
一個最經常使用的log4j2的配置:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="ERROR"> <Appenders> <RollingFile name="RollingFile" fileName="E:/webapp/logs/yadou-manage.log" filePattern="E:/webapp/logs/$${date:yyyy-MM}/yadou-manage-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout> <Pattern>%d %-5level [%t]%l - %msg%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="250 MB"/> </Policies> </RollingFile> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%highlight{%d %-5level [%t]%l - %msg%n}"/> </Console> </Appenders> <Loggers> <!--控制輸出debug,不繼承--> <Logger name="com.jia.yadou.manage" level="debug" additivity="false"> <!--保存文件,只存儲info級別以上的日誌--> <AppenderRef ref="RollingFile" level="info"/> <!--控制檯打印指定包路徑下面的debug--> <AppenderRef ref="Console"/> </Logger> <!--默認info級別--> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
項目中注意事項:
一般咱們的項目有時候是以jar包的形式發佈出去,可是此時若是你直接使用lo4j2的api的話,至關於別人依賴你的jar的項目也必須加入log4j2的jar包。這樣是高度耦合的。咱們不建議這樣使用,log4j2官方給出了適配slf4j,咱們只須要在項目中加入如下依賴:
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.6.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency>
而後項目中,咱們使用slf4j的api而不要使用lo4j2的api例如:
將LogManager.getLogger(xxx);替換爲LoggerFactory.getLogger(xx);
這樣當其餘項目引入你的jar後,就能夠不用強制他們使用log4j2,也不會由於沒有log4j2的jar而報錯。
log4j2最強的是支持異步寫日誌,這個是個人簡單配置:
異步輸出,官方有兩種方案。第一種是採用配置開關,第二種則是基於異步標籤。注意:異步輸出日誌須要disruptor-3.3.0.jar或者以上的版原本支持。下面我具體的說明下兩種狀況:
添加一個名字爲:log4j2.component.properties文件,放到classpath下面,log4j2會在啓動的時候自動加載。而後你的日誌輸出已經變成了異步輸出了。(注意:這種狀況,本人在main方法啓動函數測試的時候,常常出現不成功,可能須要附加其餘配置參數,我也推薦你們使用第二種方式)
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
你只須要將你要異步輸出的塊改成AsyncLogger標籤就好了。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="ERROR"> <Properties> <!--定義變量--> <Property name="filename">E:/webapp/logs/hnmcc_sso/sso.log</Property> <Property name="filenameError">E:/webapp/logs/hnmcc_sso/ssoError.log</Property> </Properties> <Appenders> <!--控制檯輸出--> <Console name="STDOUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/> </Console> <!--入文件--> <RollingFile name="RollingFile" fileName="${filename}" filePattern="/webapp/logs/hnmcc_sso/${date:yyyy-MM}/sso-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/> <Policies> <SizeBasedTriggeringPolicy size="200 MB"/> <TimeBasedTriggeringPolicy/> </Policies> <!--自動刪除超過120天的日誌壓縮文件--> <DefaultRolloverStrategy> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="*/sso-*.log.gz"/> <IfLastModified age="120d"/> </Delete> </DefaultRolloverStrategy> </RollingFile> <!--錯誤日誌入文件--> <RollingFile name="RollingFileError" fileName="${filenameError}" filePattern="/webapp/logs/hnmcc_sso/${date:yyyy-MM}/ssoError-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/> <Policies> <SizeBasedTriggeringPolicy size="200 MB"/> <TimeBasedTriggeringPolicy/> </Policies> <!--自動刪除超過120天的日誌壓縮文件--> <DefaultRolloverStrategy> <Delete basePath="${baseDir}" maxDepth="2"> <IfFileName glob="*/sso-*.log.gz"/> <IfLastModified age="120d"/> </Delete> </DefaultRolloverStrategy> </RollingFile> </Appenders> <Loggers> <!--採用異步輸出日誌--> <AsyncLogger name="com.xwtec.util.Transport" level="info"> <!--寫入info級別--> <AppenderRef ref="RollingFile"/> <!--寫入error級別--> <AppenderRef ref="RollingFileError" level="error"/> </AsyncLogger> <Root level="debug"> <AppenderRef ref="STDOUT"/> </Root> </Loggers> </Configuration>