由于Hadoop生態鏈基本都是java開發的,所以在很多有關大數據處理的開源項目中,常常會看到log4j這個jar包。
本文旨在對它的用法做基本說明。
2. log4j的3要素
log4j存在3個重要概念:loggers, appenders和layouts,這3個要素使得引入log4j庫的開發者可以靈活控制打印行動,如日志等級、日志內容、日志格式及打印目的地(如本地或遠程打印),等等。
2.1 loggers
事實上,loggers是1些大小寫敏感的命名實體,這些實體的命名遵守以下的層級命名規則(細節可查看文檔Short introduction to log4j):
A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there
are no ancestors between itself and the descendant logger.
在loggers的層級結構中,root logger處于最頂級。使用log4j庫時,root logger必須被創建且只能通過類靜態方法Logger.getRootLogger來創建,而其它logger可以通過傳入logger name調用類靜態方法Logger.getLogger來實例化。
可以為logger實例指定日志等級(如通過setLevel接口),目前支持這些經常使用等級:TRACE, DEBUG, INFO, WARN, ERROR, FATAL。不斟酌TRACE,其余等級的重要程度順次為:DEBUG < INFO < WARN < ERROR < FATAL。
若某個logger實例沒有顯式指定等級,則它會繼承距離它最近的、被顯式指定過日志等級的父logger實例的等級。
1旦為某個logger實例指定了等級,則調用該實例打印日志時,只有日志等級不小于指定等級的日志會被打印,低于指定等級的日志不會被打印出來。這個規則是log4j庫的核心規則,它保證了日志等級的靈活控制。
2.2 appenders
appenders其實就是日志打印的目的地址(In log4j speak, an output destination is called an appender),目前支持的appenders包括:console, files, GUI components, remote socket servers, JMS, NT Event
Loggers, and remote UNIX Syslog daemons。
1個logger實例可以有多個appender(s),即同1條日志可以同時打印到多個目的地。
默許情況下,某logger實例的日志打印要求會打印到已為該logger實例添加的所有appenders上,另外,該日志打印要求還會沿著logger實例的層級繼承鏈向上傳播給其先人logger的所有appenders。
例如,為root logger添加console類型的appender后,root logger的日志打印要求會輸出到console,這很容易理解。現在假定logger實例C繼承自root,且為實例C添加了file類型的appender,則調用實例C進行日志打印時,除file appender會輸出日志外,實例C的先人,即本例中的root
logger也會收到該日志打印要求,由于root logger添加了console appender,所以,console appender也會輸出日志。這個默認行動可以通過將logger的additive字段設置為false來關閉。
關于appender additivity的更多說明及示例,可以參考Short introduction to log4j這篇文檔關于Appender部份的說明。
2.3 layouts
layouts可以指定日志的格式,支持的PatternLayout在文檔log4j - Class PatternLayout中有詳細說明,這里不贅述。
4. log4j庫的初始化進程
log4j不對它的使用處景做任何假定,因此,它沒有默許的appender,也即,appender必須由使用者顯式配置。援用了log4j庫的java進程啟動時,JVM的classloader機制會對利用程序援用到的Logger類進行加載,而該類的靜態初始化函數會嘗試自動配置log4j。log4j庫默許的初始化進程在文檔Short
introduction to log4j的"Default Initialization Procedure"部份有詳細說明,感興趣的同學可以去查看。
備注:關于JVM加載class(如系統包或第3方擴大包)的機制,可以通過下面幾篇文檔來理解:
1)
Understanding the Java Classloading Mechanism
2)
Understanding Extension Class Loading
3)
Internals of Java Class Loading
========================= EOF ========================