歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Log4j容器深入探究

Log4j容器深入探究

日期:2017/3/1 9:09:18   编辑:Linux編程

1.思考

容器是什麼?

  • 水壺是容器,水壺中存放著水,等我們需要水了,直接用

  • Spring中的ApplicationContext是容器,裡面存放著各種Bean,等我們需要了直接用,並且可以創建管理Bean

  • Hierarchy是Log4j的容器,它裡面存放著各種Logger? 用來管理各種Logger?

Hierarchy是什麼?

從字面上看:

n. 層級;等級制度。

log4j的文檔說明:

This class is specialized in retrieving loggers by name and also maintaining the logger hierarchy

用來根據名稱獲取Logger並維持logger等級。看來是我們想想的那樣,存放著各種Logger並管理,等我們需要的時候還可以從中獲取。

2.Hierarchy 容器

Hierarchy既然是容器,談到容器,就如上面所說的水壺、Spring中的ApplicationContext以及Java中的集合類。他們的核心功能就是存和取

簡單認識下Hierarchy字段

2.1 存儲數據結構

容器存的是Logger,每個Logger都有全局唯一的名稱,也可以說每個名稱只對應一個Logger實例,所有Logger均以名稱為key存儲在HashTable中,並且還根據名稱組裝成以RootLogger為根的一棵樹,樹的層次由Logger的name決定,以"."分隔。如下圖所示,HashTable和Logger中的parent維護了以RootLogger為根節點的樹。

由於Log4j允許先存放子節點,然後再存放父節點,這裡就會涉及到子節點的父節點更細問題,下面會分先存放父節點和子節點兩種情況進行分析,在開始之前先來認識下ProvisionNode.

ProvisionNode:

Provision類實際上就是一個Vector(通過繼承Vector實現)。當ChildLogger先建立,未能找到parent的時候,log4j會預先建立一個ProvisionNode,並將ChildLogger添加到ProvisionNode中,當實際的ParentLogger創建時,再將所有的ChildLogger從ProvisionNode轉移到Parent中.

2.1.1 先存放父節點,再存放子節點
  • 先存放RootLogger

  • 再存放Logger(x),在HashTable中沒有找到對應的Logger;調用LoggerFactory得到Logger(x),x的parent是Root

  • 再存放Logger(x.y),在HashTable中沒有找到對應的Logger;調用LoggerFactory得到Logger(x.y),x.y的parent有x、root,在HashTable中能找到x對應的Logger,設置Logger(x.y)的parent為Logger(x)

  • 再存放Logger(x.y.z),在HashTable中沒有找到對應的Logger,調用LoggerFactory得到Logger(x.y.z);x.y.z的parent有x.y、x、root,在HashTable中能找到x.y對應的Logger,設置Logger(x.y.z)的parent為Logger(x.y)

依次類推...

2.1.2 先存放子節點,再存放父節點
  • 先存放RootLogger

  • 存放Logger(x.y.z)

  • 查詢HashTable中不存在,Logger(x.y.z),創建Logger(x.y.z)

  • 遍歷父節點x.y\/x,不存在Logger(x.y)和Logger(x),創建P(x.y)和P(x),並添加Logger(x.y.z)到vector容器中,並存儲在HashTable中

  • 沒有找到父節點對應的Logger,設置Root為父節點

  • 存放Logger(x.y)

  • 查詢HashTable,得到P(x.y),創建Logger(x.y)

  • 遍歷P(x.y)的Vector(存放子節點)更新其parent

  • 遍歷Logger(x.y)父節點x,不存在Logger(x),則把Logger(x,y)添加到P(x)對應的vector中

  • 沒有找到Logger(x.y)父節點對應的Logger,設置RootLogger為其父節點

  • 存放Logger(x)

以此類推...

從上面的案例可以看出相同的名稱得到的Logger實例一定是相同,而且每個Logger都有一個Parent,根節點是RootLogger。

2.2 獲取Logger

我們常常用下面的代碼獲得Logger,相信通過上面的講解,你已經知道怎麼獲取的了。其實就是根據Class的完全限定名,去HashTable中獲取,如果不存在則創建,然後更新parent以及child.


private static Logger logger = Logger.getLogger(Test.Class);

更多Log4j相關教程見以下內容

Log4j配置詳解 http://www.linuxidc.com/Linux/2014-10/108401.htm

Apache Log4j 2 更多內容請看: http://logging.apache.org/log4j/2.x/

Log4j入門使用教程 http://www.linuxidc.com/Linux/2013-06/85223.htm

Log4j 日志詳細用法 http://www.linuxidc.com/Linux/2014-09/107303.htm

Hibernate配置Log4j顯示SQL參數 http://www.linuxidc.com/Linux/2013-03/81870.htm

Log4j學習筆記(1)_Log4j 基礎&配置項解析 http://www.linuxidc.com/Linux/2013-03/80586.htm

Log4j學習筆記(2)_Log4j配置示例&Spring集成Log4j http://www.linuxidc.com/Linux/2013-03/80587.htm

Log4j容器初始化探究 http://www.linuxidc.com/Linux/2016-11/137083.htm

Log4j 的詳細介紹:請點這裡
Log4j 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved