logback官方文檔閱讀筆記(二)


前言


logback官方文檔html

本文關於官方文檔第二章:Architecturejava

第二章篇幅較長,分了兩篇筆記。第二篇關於第二章的筆記segmentfault

正文


logback的三個組成部分


Logback's architecture

Logback's basic architecture is sufficiently generic so as to apply under different circumstances. At the present time, logback is divided into three modules, logback-core, logback-classic and logback-access.api

The core module lays the groundwork for the other two modules. The classic module extends core. The classic module corresponds to a significantly improved version of log4j. Logback-classic natively implements the SLF4J API so that you can readily switch back and forth between logback and other logging systems such as log4j or java.util.logging (JUL) introduced in JDK 1.4. The third module called access integrates with Servlet containers to provide HTTP-access log functionality. A separate document covers [access module documentation] (http://logback.qos.ch/access....app

In the remainder of this document, we will write "logback" to refer to the logback-classic module.less

這一段談及Logback的三個部分:logback-core,logback-classic和logback-access。其中logback-core爲後兩個部分的基石,logback-classic爲logback-core的增強。logback-classic對應於有了經歷重要更新版本的log4j(應該是指log4j2),同時它從設計之初就想好了是爲SLF4J日誌規約而生的,能良好的適配,也所以你能夠輕鬆愉快地在它和其它SLF4J的具體實現如log4j和JUL間相互切換。而logback-access統合了Servlet容器(JavaWeb開發的概念)以提供在JavaWeb開發過程當中的日誌支持。ide

本文檔以後使用的logback均只指logback-classic。學習


logback功能實現的三個主力類


Logger, Appenders and Layouts

Logback is built upon three main classes:Logger, Appender and Layout. These three types of components work together to enable developers to log messages according to message type and level, and to control at runtime how these messages are formatted and where they are reported.flex

The Logger class is part of the logback-classic module. On the other hand, the Appender and Layout interfaces are part of logback-core. As a general-purpose module, logback-core has no notion of loggers.ui

說完logback的三大部分,這裏logback告知實現日誌功能三個主力類分別是AppenderLoggerLayout

通過後續的學習或者一些實踐,會發現這裏漏了一員大將:過濾器Filter


日誌系統主流設計和實現思路


The first and foremost advantage of any logging API over plain System.out.println resides in its ability to disable certain log statements while allowing others to print unhindered.

這一段指明瞭使用日誌系統代替System.out.println(...)的根本緣由,也即日誌系統的應該作的事情和優點。

This capability assumes that the logging space, that is, the space of all possible logging statements, is categorized according to some developer-chosen criteria.

這一段說明了絕大部分日誌系統應該作(強於使用System.out.println(...))的事情的實現思路。

In logback-classic, this categorization is an inherent part of loggers. Every single logger is attached to a LoggerContext which is responsible for manufacturing loggers as well as arranging them in a tree like hierarchy.

這裏其實講了兩件事。
第一件事,上述的對輸出分類管理的思想是logback一以貫之的。但具體怎麼貫之,沒講了。
第二件事,指明logback依靠一個關鍵類LoggerContext做爲實現思路的實踐者。這個類在第一章的文檔中也出現過,也能夠去看個人筆記的第一篇。這個關鍵類負責生成日誌記錄器(我目前對logger的翻譯和理解)並將它們安排在一個樹狀的層次結構中。


日誌記錄器的樹狀層次結構


Loggers are named entities. Their names are case-sensitive and they follow the hierarchical naming rule:

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.

For example, the logger named "com.foo" is a parent of the logger named "com.foo.Bar". Similarly, "java" is a parent of "java.util" and an ancestor of "java.util.Vector". This naming scheme should be familiar to most developers.

The root logger resides at the top of the logger hierarchy. It is exceptional in that it is part of every hierarchy at its inception. Like every logger, it can be retrieved by its name, as follows:

Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

All other loggers are also retrieved with the class static getLogger method found in the org.slf4j.LoggerFactory class. This method takes the name of the desired logger as a parameter.

這裏首先強調了日誌記錄器是有名字的,而後進一步講明瞭上一節提到的LoggerContext將日誌記錄器安排在一個樹狀的層次結構中是怎麼根據名字去作的。


日誌記錄器的分級


Loggers may be assigned levels. The set of possible levels (TRACE, DEBUG, INFO, WARN and ERROR) are defined in the ch.qos.logback.classic.Level class. Note that in logback, the Level class is final and cannot be sub-classed, as a much more flexible approach exists in the form of Marker objects.

If a given logger is not assigned a level, then it inherits one from its closest ancestor with an assigned level. More formally:

The effective level for a given logger_L_, is equal to the first non-null level in its hierarchy, starting at_L_itself and proceeding upwards in the hierarchy towards the root logger.

To ensure that all loggers can eventually inherit a level, the root logger always has an assigned level. By default, this level is DEBUG.

這裏說明了logback對輸出信息進行分類管理時,有哪些類能夠被輸出信息分入,以及日誌記錄器如何分配日誌等級(即分爲哪一類),在無指定的狀況下會如何被肯定級別。

其實寫到這裏仔細一想會以爲奇怪,咱們前面接觸到的例子,不都是一個Logger類實例L經過L.info(...)或者L.debug(...)啥的來記錄日誌麼。不該該對消息分級,怎麼對日誌記錄器分級了呢?別急,接下來文檔就回答了這問題。


日誌消息的級別與日誌記錄器級別的關係


Printing methods and the basic selection rule

By definition, the printing method determines the level of a logging request. For example, if L is a logger instance, then the statement L.info("..") is a logging statement of level INFO.

A logging request is said to be_enabled_if its level is higher than or equal to the effective level of its logger. Otherwise, the request is said to be_disabled_. As described previously, a logger without an assigned level will inherit one from its nearest ancestor. This rule is summarized below.

Basic Selection Rule:
A log request of level p issued to a logger having an effective level q, is enabled if p >= q.

This rule is at the heart of logback. It assumes that levels are ordered as follows: TRACE < DEBUG < INFO <  WARN < ERROR.

解決了在以前看到的例子中L.info("...")這樣好像消息自己纔是被分級的,爲什麼上一節說日誌記錄器被分級的疑惑。被分級爲q的日誌記錄器只有使用分級大於q的級別的記錄方法,纔有可能造成有效的記錄。

最後給出了日誌等級的前後大小關係。


日誌記錄器類Logger與名字一對一關係


Calling the LoggerFactory.getLogger method with the same name will always return a reference to the exact same logger object.

For example, in

Logger x = LoggerFactory.getLogger("wombat"); 
Logger y = LoggerFactory.getLogger("wombat");

x and y refer to exactly the same logger object.

Thus, it is possible to configure a logger and then to retrieve the same instance somewhere else in the code without passing around references.

說明在整個應用程序的聲明週期中一個Logger的實例與的名字成一對一關係。


配置日誌記錄器時沒必要考慮層級關係


In fundamental contradiction to biological parenthood, where parents always precede their children, logback loggers can be created and configured in any order. In particular, a "parent" logger will find and link to its descendants even if it is instantiated after them.

Configuration of the logback environment is typically done at application initialization. The preferred way is by reading a configuration file. This approach will be discussed shortly.

指明配置日誌記錄器時的順序不須要像傳統生物學同樣先有祖先再有子代。

隨後指明推薦在軟件初始化時經過讀取配置文件來配置logback環境。但具體的配置方法請繼續閱讀,如今還不告訴你。


使用日誌記錄器的推薦範式


Logback makes it easy to name loggers by software component. This can be accomplished by instantiating a logger in each class, with the logger name equal to the fully qualified name of the class. This is a useful and straightforward method of defining loggers. As the log output bears the name of the generating logger, this naming strategy makes it easy to identify the origin of a log message. However, this is only one possible, albeit common, strategy for naming loggers. Logback does not restrict the possible set of loggers. As a developer, you are free to name loggers as you wish.

Nevertheless, naming loggers after the class where they are located seems to be the best general strategy known so far.

對於一個在ch.qos.logback.Main的類下使用的日誌記錄器Logger的實例L,最推薦的方式是Logger L = LoggerFactory.getLogger(Main.class)Logger L = LoggerFactory.getLogger("ch.qos.logback.Main")這樣在哪一個類用,就用哪一個類的字節碼或者全限定名。固然,若是你使用Logger L = LoggerFactory.getLogger("Main")也可,這並不會引發錯誤。

相關文章
相關標籤/搜索