log4j2的學習

背景:

業(yè)務上面的代碼,肯定都是需要打印日志的甲献,不論是之后定位問題還是其他什么的宰缤。
最基礎的訴求就是能夠將不同級別的日志打印到不同的文件中,能夠按天來區(qū)分晃洒。這些log4j2都有慨灭,并且支持異步處理。雖然我沒有用過logback和log4j锥累,但是通過博客中得出的結論就是log4j2有他們都有的優(yōu)點缘挑,也有他們沒有的優(yōu)點集歇。
本文并沒有仔細鉆研l(wèi)og4j2的底層桶略,暫時只是出于用日志的地步。其實有日志也可以玩出很多玩意诲宇,比如小米的lcs际歼,就可以通過log4j2來講一些數(shù)據(jù)異步上傳到服務器中,來完成一些數(shù)據(jù)打點姑蓝。

日志配置

先來一個簡單的日志配置
依賴:

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.7</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>

        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.2</version>
        </dependency>
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error">
    <!--先定義所有的appender -->
    <appenders>
        <!--這個輸出控制臺的配置 -->
<!--        onMatch="ACCEPT" 表示匹配該級別及以上-->
<!--        onMatch="DENY" 表示不匹配該級別及以上-->
<!--        onMatch="NEUTRAL" 表示該級別及以上的鹅心,由下一個filter處理,如果當前是最后一個纺荧,則表示匹配該級別及以上-->
<!--        onMismatch="ACCEPT" 表示匹配該級別以下-->
<!--        onMismatch="NEUTRAL" 表示該級別及以下的旭愧,由下一個filter處理颅筋,如果當前是最后一個,則不匹配該級別以下的-->
<!--        onMismatch="DENY" 表示不匹配該級別以下的-->

        <Console name="Console" target="SYSTEM_OUT">
            <!--             控制臺只輸出level及以上級別的信息(onMatch)输枯,其他的直接拒絕(onMismatch) -->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <!--             這個都知道是輸出日志的格式 -->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </Console>

        <!--文件會打印出所有信息议泵,這個log每次運行程序會自動清空,由append屬性決定桃熄,這個也挺有用的先口,適合臨時測試用 -->
        <!--append為TRUE表示消息增加到指定文件中,false表示消息覆蓋指定的文件內容瞳收,默認值是true -->
        <File name="log" fileName="D:/logs/log4j2.log" append="true">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </File>

        <!--添加過濾器ThresholdFilter,可以有選擇的輸出某個級別以上的類別  onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否則直接拒絕  -->
        <File name="ERROR" fileName="D:/logs/error.log">
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </File>

        <!--這個會打印出所有的信息碉京,每次大小超過size,則這size大小的日志會自動存入按年份-月份建立的文件夾下面并進行壓縮螟深,作為存檔 -->
        <RollingFile name="RollingFile" fileName="D:/logs/web.log"
                     filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
            <SizeBasedTriggeringPolicy size="2MB"/>
        </RollingFile>
    </appenders>


    <!--然后定義logger谐宙,只有定義了logger并引入的appender,appender才會生效 -->
    <loggers>
        <AsyncRoot level="info" includeLocation="true">
            <appender-ref ref="RollingFile"/>
            <appender-ref ref="Console"/>
            <appender-ref ref="log"/>
            <appender-ref ref="ERROR" />
        </AsyncRoot>
    </loggers>
</configuration>

測試程序

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Test {
    private static  Logger logger= LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
    @org.junit.Test
    public void Test(){
        System.out.println(1);
        logger.info("info");
        logger.error("error");
    }
}

=========================================================
上面中重要的配置標簽有3個界弧,一個是全局的Configuration, 然后是appender, 然后是logger.
下面這段話是copy過來的卧惜。


image.png

Logger是最常使用的類,用于打印日記的接口夹纫,通過LogManager類指定名字獲得咽瓷。LogManager定位LoggerContext并從它那獲得Logger。如果Logger被創(chuàng)建舰讹,Logger會被關聯(lián)一個LoggerConfig茅姜,該LoggerConfig可能與Logger同名,或同父package名或為root LoggerConfig(涉及Level Inheritance)(這邊可以結合測試程序來看)月匣。

使用Logger可以打印不同級別的日志钻洒,這些日志會被包裝為LogEvent。LogEvent會被派送到LoggerConfig上锄开。LoggerConfig在xml配置文件中由Logger元素配置的(我們日志中的應該就是rootlog)素标,LoggerConfig含有日志級別(Log Level)信息,對應0到多個Appender萍悴。LoggerConfig根據(jù)自己的日志級別配置與LogEvent的級別头遭,決定是否允許進一步的處理。如果NO則丟棄癣诱,如果Yes則傳給Appender计维。

LoggerConfig中的日記級別只是一個種定義好了的過濾器(Filter),還可以在Logger元素中為LoggerConfig配置過濾器撕予,進行更細致的控制鲫惶。
Appender負責將LogEvent派送到目的地,可以有很多目的地实抡,如console欠母,文件欢策、遠程服務器或數(shù)據(jù)庫等等。一個loggerConfig可以對應很多Appender赏淌,loggerConfig含有父(或祖先)loggerConfig的引用猬腰。因此loggerConfig不僅將LogEvent發(fā)送給自己的所有Appender,還發(fā)給它的父(或祖先)LoggerConfig的appender猜敢,然后遞歸向上姑荷,這種行為被稱為Additivity。
appender只關心如何將LogEvent送到目的地缩擂,而Layout負責格式化LogEvent鼠冕。log4j中含有不同種Layout,用于不同的用途胯盯,如JSON懈费,XML,HTML等等博脑。
每個Logger都有自己的名字憎乙,通常使用Logger所處類的全限定名作為Logger的名字。
在log4j中必定存在root LoggerConfig叉趣,即使沒有手動配置泞边,也會使用默認的,保證Logger能夠關聯(lián)到LoggerConfig疗杉。
==================================================
(這邊有一個疑惑阵谚,logger的日志級別設置和appender中的ThresholdFilter日志級別設置)
問題解答:經(jīng)過我本地的測試,其實這邊消息會經(jīng)過多種過濾烟具。首先在logger中會根據(jù)日志級別將消息傳到所有滿足的logger上(當有多個logger的時候)梢什,然后logger會傳送給appender, appender如果設置了ThresholdFilter, 就會篩選出符合對應日志級別的信息朝聋,床送到目的地中

學習的有些片面嗡午,剛會使用的地步,但是在調用異步的時候冀痕,程序開始報錯了荔睹,明天需要好好探究一下原因。 原因居然是因為少加了一個依賴=-=,也是醉了金度,算了应媚,明天再寫吧

        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.2</version>
        </dependency>

3個標簽:

Configuration

Configuration元素一些重要的屬性如下:
status:log4j框架內部要輸出到console的LogEvent的級別〔录可選值:trace", “debug”, “info”, “warn”, “error” and “fatal”。貌似默認warn消玄。
dest:輸出到console具體的流跟伏《撸可選值:“err”,“out”,文件或url。默認out受扳。
monitorInterval:多少秒掃描一下配置文件

Appenders

<appenders>主要有3種類型的子標簽携龟,console(控制臺), File 普通文件勘高, RollingFile 一種可以自動調節(jié)的文件
Console節(jié)點用來定義輸出到控制臺的Appender.
File節(jié)點用來定義輸出到指定位置的文件的Appender.
RollingFile節(jié)點用來定義超過指定大小自動刪除舊的創(chuàng)建新的的Appender.
其中滾動策略可以做成時間和大小雙重滾動峡蟋,配置如下:

<!--此處舉例為每小時滾動一個文件且每500M滾動一個文件,控制每小時最多保留20個文件华望,總的文件保留3天-->
  <!--具體需要根據(jù)應用的日志量和希望保留日志大小以及磁盤空間進行評估-->
  <RollingRandomAccessFile name="APPINFO_APPENDER" fileName="${baseLogDir}/appinfo.log"
      filePattern="${baseLogDir}/appinfo.log.%d{yyyyMMddHH}.%i.gz">
      <PatternLayout>
          <Pattern>${pattern}</Pattern>
      </PatternLayout>
      <Policies>
          <SizeBasedTriggeringPolicy size="500MB" />
          <TimeBasedTriggeringPolicy interval="1" modulate="true" />
      </Policies>
      <Filters>
          <!-- 當前appender只打印info日志蕊蝗,warn及以上日志忽略,由后面的錯誤日志記錄 -->
          <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL" />
          <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY" />
      </Filters>
      <!-- max=20表示一小時內最多保留20個日志文件 -->
      <DefaultRolloverStrategy max="20">
          <!-- 對于指定的路徑下的指定后綴的文件赖舟,只保留3天的日志文件蓬戚,那么最多會有3天*24小時*20個日志文件 -->
          <!-- 注意應用需要根據(jù)業(yè)務需求和磁盤大小評估需要保留的日志個數(shù),對于500M的日志文件來說宾抓,要根據(jù)應用日志的情況子漩,觀察單個日志壓縮后文件大小,并計算總大小需要的空間 -->
          <Delete basePath="${baseLogDir}" maxDepth="1">
              <IfFileName glob="*.gz" />
              <IfLastModified age="3d" />
          </Delete>
      </DefaultRolloverStrategy>
  </RollingRandomAccessFile>

具體標簽石洗,看配置文件應該是可以看懂的幢泼,之后的例子都可以這樣子設置

Logger

Loggers標簽中常見同步的有兩種:Root和Logger,異步有AsyncRoot 讲衫,和 AsyncLogger旭绒。
log4j2支持同步,異步焦人,混合模式挥吵。
Root節(jié)點用來指定項目的根日志,如果沒有單獨指定Logger花椭,那么就會默認使用該Root日志輸出
Logger節(jié)點用來單獨指定日志的形式忽匈,比如要為指定包下的class指定不同的日志級別等。
自定義的Logger(子Loggger)繼承自rootLogger矿辽,如果存在繼承丹允,那么他們也會繼承他們的父類中的appender,這個就是上面所說的這種行為被稱為Additivity。

總結:

對目前來說袋倔,會用就行雕蔽,不要搞出都不知道日志打印到了哪邊,日志怎么不輸出的玩笑出來宾娜。

參考博客:

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末批狐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嚣艇,老刑警劉巖承冰,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異食零,居然都是意外死亡困乒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門贰谣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娜搂,“玉大人,你說我怎么就攤上這事吱抚“儆睿” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵频伤,是天一觀的道長恳谎。 經(jīng)常有香客問我,道長憋肖,這世上最難降的妖魔是什么因痛? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮岸更,結果婚禮上鸵膏,老公的妹妹穿的比我還像新娘。我一直安慰自己怎炊,他們只是感情好谭企,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著评肆,像睡著了一般债查。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓜挽,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天盹廷,我揣著相機與錄音,去河邊找鬼久橙。 笑死俄占,一個胖子當著我的面吹牛,可吹牛的內容都是我干的淆衷。 我是一名探鬼主播缸榄,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼祝拯!你這毒婦竟也來了甚带?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎欲低,沒想到半個月后辕宏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畜晰,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡砾莱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了凄鼻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腊瑟。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖块蚌,靈堂內的尸體忽然破棺而出闰非,到底是詐尸還是另有隱情,我是刑警寧澤峭范,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布财松,位于F島的核電站,受9級特大地震影響纱控,放射性物質發(fā)生泄漏辆毡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一甜害、第九天 我趴在偏房一處隱蔽的房頂上張望舶掖。 院中可真熱鬧,春花似錦尔店、人聲如沸眨攘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鲫售。三九已至,卻和暖如春该肴,著一層夾襖步出監(jiān)牢的瞬間情竹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工沙庐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鲤妥,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓拱雏,卻偏偏與公主長得像棉安,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子铸抑,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355