系列
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的擴展接口偏螺。