log4j的實現(xiàn)原理與思考

系列

log4j的介紹

  • Log4j是Apache的一個開源項目杖虾,通過使用Log4j亿絮,我們可以控制日志信息輸送的目的地是 控制臺骑祟、文件、GUI組件,甚至是套接口服務器、NT的事件記錄器、UNIX守護進程等;我們也可以控制每一條日志的輸出格式嫂丙;通過定義每一條日志信息的級別,我們能夠更加細致地控制日志的生成過程规哲。最令人感興趣的就是跟啤,這些可以通過一個配置文件來靈活地進行配置,而不需要修改應用的代碼。
  • 該篇內(nèi)容涵蓋了log4j日常的基本用法隅肥,深入分析了log4j的各功能組件竿奏、日志輸出過程,以及提出了擴展性的一些思考腥放。


log4j的基本用法

log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/" threshold="info" debug="false">

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
        </layout>
        <filter class="org.apache.log4j.varia.LevelMatchFilter">
            <param name="LevelToMatch" value="INFO" />
            <param name="AcceptOnMatch" value="true" />
        </filter>
        <filter class="org.apache.log4j.varia.DenyAllFilter"/>
    </appender>

    <appender name="file" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="logs/main.log" />
        <param name="Append" value="true" />
        <param name="ImmediateFlush" value="true" />
        <param name="MaxFileSize" value="10MB" />
        <param name="MaxBackupIndex" value="5" />

        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %d{Z} [%t] %-5p (%F:%L) - %m%n" />
        </layout>
    </appender>

    <logger name="com.journaldev.log4j" additivity="true">
        <level value="DEBUG" />
        <appender-ref ref="jdbc" />
    </logger>

    <logger name="com.journaldev.log4j.model" additivity="true">
        <level value="DEBUG" />
        <appender-ref ref="file" />
    </logger>

    <root>
        <priority value="DEBUG" />
        <appender-ref ref="console" />
    </root>

</log4j:configuration>
  • log4j.xml的基礎配置模板泛啸,配置包含appender、layout秃症、filter候址、logger、root种柑。
  • Appender是對記錄日志形式的抽象岗仑,標示了日志打印的目的地。
  • Filter是對日志是否輸出的過濾器莹规,標識了日志是否能夠打印赔蒲。
  • Layout是對日志行格式的抽象泌神。
  • 關鍵字threshold用來控制log4j整體的日志級別良漱,低于該級別的日志不被輸出。
  • 關鍵字debug用來日志log4j應用本身的啟動日志欢际。
  • 關鍵字additivity用來控制logger的繼承屬性母市。

log4j使用

public static void main(String[] args) {
  DOMConfigurator.configure("log4j.xml");
  Logger logger = Logger.getLogger("org.apache.log4j.xml");

  logger.info("++++++++++");
}
  • log4j的使用本質(zhì)上是通過配置解析器解析指定的log4j.xml文件來生成Logger對象。
  • spring在使用log4j的過程中本質(zhì)上也是加載了指定resources目錄下的log4j.xml文件损趋。


log4j的核心組件介紹

  • LoggingEvent是對一次日志記錄過程中所需要的信息的抽象,可以理解成一個上下文患久。
  • Logger 用于對日志記錄行為的抽象,提供記錄不同級別日志的統(tǒng)一接口浑槽。
  • Appender是對記錄日志形式的抽象蒋失,標示了日志打印的目的地。
  • Filter是對日志是否輸出的過濾器桐玻,標識了日志是否能夠打印篙挽。
  • Layout是對日志行格式的抽象。
  • Level對日志級別的抽象镊靴。

log4j組件關系

// LogManager包含Hierarchy對象
public class LogManager {
  static private RepositorySelector repositorySelector;
  static {
    Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));// Hierarchy保存Logger的所有信息
    repositorySelector = new DefaultRepositorySelector(h);
  }
}

// Hierarchy包含Logger對象
public class Hierarchy implements LoggerRepository, RendererSupport, ThrowableRendererSupport {
  Hashtable ht;   // 保存應用當中所有的Logger對象
  Logger root;    // 保存應用中的Root的Logger對象
  Level threshold; // 全局的日志打印范圍
}

// Logger包含Appender對象
public class Category implements AppenderAttachable {
  protected String   name; // Logger的名字
  volatile protected Level level; // Logger的日志級別
  volatile protected Category parent; // Logger繼承的父類
  AppenderAttachableImpl aai; //Logger的綁定的appender
  protected boolean additive = true; // Logger的是否繼承的標記
}

public class AppenderAttachableImpl implements AppenderAttachable {
  protected Vector  appenderList; // appender的列表
}

// Appender對象包含Layout對象和Filter對象铣卡。
public abstract class AppenderSkeleton implements Appender, OptionHandler {
  protected Layout layout; // appender綁定的layout對象
  protected String name; // append的名稱
  protected Priority threshold;
  protected Filter headFilter; // append綁定的filter列表的頭指針
  protected Filter tailFilter;// append綁定的filter列表的尾指針
}
  • LogManager包含Hierarchy對象。
  • Hierarchy包含多個Logger對象的Map偏竟。
  • Logger包含多個Appender對象列表煮落。
  • Appender對象包含Layout對象。
  • Appender對象包含多個Filter對象的列表踊谋。

appender

org.apache.log4j.Appender(Appender的實現(xiàn)接口)

org.apache.log4j.net.SyslogAppender(打到遠程日志服務器)
org.apache.log4j.jdbc.JDBCAppender(保存到數(shù)據(jù)庫)
org.apache.log4j.RollingFileAppender(滾動文件蝉仇,自動記錄最新日志) 
org.apache.log4j.ConsoleAppender (控制臺)  
org.apache.log4j.FileAppender (文件) 
org.apache.log4j.DailyRollingFileAppender (每天產(chǎn)生一個日志文件) 
org.apache.log4j.WriterAppender (將日志信息以流格式發(fā)送到任意指定的地方) 
  • log4j本身包含如SyslogAppender等日志輸出類,也可以通過實現(xiàn)Appender接口定制滿足特殊需求。

Layout

org.apache.log4j.Layout

org.apache.log4j.helpers.DateLayout
org.apache.log4j.PatternLayout
org.apache.log4j.SimpleLayout
  • log4j本身包含PatternLayout等日志輸出類量淌,也可以通過實現(xiàn)Layout接口定制滿足特殊需求骗村。

filter

org.apache.log4j.spi.Filter(Filter的實現(xiàn)接口)

org.apache.log4j.varia.LevelRangeFilter(日志等級范圍過濾器)
org.apache.log4j.varia.StringMatchFilter(字符串匹配過濾器)
org.apache.log4j.varia.DenyAllFilter(拒絕所有日志的過濾器)
org.apache.log4j.varia.LevelMatchFilter(日志等級匹配過濾器)
  • log4j本身包含如LevelRangeFilter等過濾類,也可以通過實現(xiàn)Filter接口定制滿足特殊需求呀枢。

log4j的日志輸出過程

  • application通過LogManager的getLogger(name)來獲取指定的Logger對象并調(diào)用info(msg)打印日志胚股。
  • Logger.info()過程先判斷滿足全局的日志級別和Logger本身的日志級別,不滿足直接返回裙秋。
  • Logger.info()在滿足日志的級別的前提下構(gòu)建日志對象LoggingEvent琅拌,并通過appender進行日志輸出。
  • Logger.info()在會遍歷Logger下appender對象列表摘刑,針對每個appender依次遍歷Filter進行過濾进宝。
  • Logger.info()在通過Layout對象格式化LoggingEvent日志對象并最終輸出。
  • Logger對象若配置多個appender則同時輸出多份日志枷恕,appender中多個Filter任意拒絕則拒絕輸出日志党晋。


log4j的配置解析過程

  • log4j通過DOMConfigurator解析log4j.xml文件,通過PropertyConfigurator解析log4j.property文件徐块。
  • 通過Configurator的解析過程構(gòu)建Logger未玻、Appender、Layout胡控、Filter的關系扳剿。


log4j的日常應用

  • 了解了log4j的整體日志輸出框架,就可以掌握log4j本身支持的擴展點來實現(xiàn)一些特殊的需求昼激,如攔截脫敏上報等功能庇绽。

appender日志級別輸出定制

?想實現(xiàn)將系統(tǒng)所有的warn日志統(tǒng)一收集到common-warn.log中,將系統(tǒng)所有的error日志統(tǒng)一收集到common-error.log中橙困,通過配置appender當中的LevelRangeFilter過濾器來實現(xiàn)定制不同日志級別的日志輸出瞧掺。

日志脫敏

?想實現(xiàn)對日志中敏感信息進行脫敏,log4j打印日志最終是通過Appender來輸出通過Layout格式化的日志凡傅,可以在自定義Appender或者自定義Layout來實現(xiàn)脫敏功能辟狈,當然暫時不考慮性能問題,只考慮可行性像捶。

日志上報打點

?想實現(xiàn)通過打印日志來實現(xiàn)異常次數(shù)采集監(jiān)控上陕,log4j打印日志最終是通過Appender來輸出日志担孔,可以通過自定義Appender來實現(xiàn)日志攔截上報打點蟆技,也可以自定義Filter過濾器在過濾器執(zhí)行過程中實現(xiàn)日志攔截上報打點惰蜜。
?筆者所在的公司就是通過工程啟動的時候在指定的logger對象的appender當中添加自定義的Filter對象來實現(xiàn)日志的攔截上報功能壶冒。

日志級別修改

?動態(tài)修改日志級別炮障,LogManager提供動態(tài)獲取Logger對象的接口進而可以修改日志級別橄杨。
?動態(tài)修改日志的Appender對象宅此,Logger對象提供addAppender/removeAppender的擴展接口垒棋。
?動態(tài)修改日志的Filter對象,Appender對象提供addFilter的擴展接口偏螺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末行疏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子套像,更是在濱河造成了極大的恐慌酿联,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夺巩,死亡現(xiàn)場離奇詭異贞让,居然都是意外死亡,警方通過查閱死者的電腦和手機柳譬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門喳张,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人美澳,你說我怎么就攤上這事销部。” “怎么了制跟?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵舅桩,是天一觀的道長。 經(jīng)常有香客問我凫岖,道長江咳,這世上最難降的妖魔是什么逢净? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任哥放,我火速辦了婚禮,結(jié)果婚禮上爹土,老公的妹妹穿的比我還像新娘甥雕。我一直安慰自己,他們只是感情好胀茵,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布社露。 她就那樣靜靜地躺著,像睡著了一般琼娘。 火紅的嫁衣襯著肌膚如雪峭弟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天脱拼,我揣著相機與錄音瞒瘸,去河邊找鬼。 笑死熄浓,一個胖子當著我的面吹牛情臭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼俯在,長吁一口氣:“原來是場噩夢啊……” “哼竟秫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起跷乐,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肥败,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后愕提,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拙吉,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年揪荣,在試婚紗的時候發(fā)現(xiàn)自己被綠了筷黔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡仗颈,死狀恐怖佛舱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挨决,我是刑警寧澤请祖,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站脖祈,受9級特大地震影響肆捕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盖高,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一慎陵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喻奥,春花似錦席纽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至甥厦,卻和暖如春纺铭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背刀疙。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工舶赔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人庙洼。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓顿痪,卻偏偏與公主長得像镊辕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蚁袭,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 主要參考:https://blog.csdn.net/zwj1030711290/article/details/...
    TheTempest閱讀 4,263評論 0 2
  • 本文主要內(nèi)容: 1. 概述 我們?yōu)榱朔治龀绦虻膱?zhí)行情況征懈,需要把我們關心的一些調(diào)試信息、錯誤信息等保存到日志中揩悄,Lo...
    morninz閱讀 5,746評論 0 4
  • 大家好卖哎,我是IT修真院深圳分院第01期學員,一枚正直純潔善良的web程序員删性。 今天給大家分享一下亏娜,修真院官網(wǎng)JAV...
    老菜菜閱讀 600評論 0 0
  • 一、log4j介紹 1 . 為什么要使用日志 答 : 開發(fā)階段發(fā)現(xiàn)程序的問題 , 排除錯誤 , 產(chǎn)品階段 , 可以...
    架構(gòu)師Javaspring閱讀 395評論 0 1
  • Log4j 概述 Log4j 是一個使用 Java 語言編寫的蹬挺,可靠维贺、快速、靈活的日志框架(API)巴帮,使用 Apa...
    yi次元閱讀 1,211評論 0 0