日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Log4js原理解析

發布時間:2024/3/26 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Log4js原理解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Log4js原理解析

?

基于log4js?0.6.14版本

?

? ? Log4js總共三篇博客

? ? 《Log4js原理解析》http://blog.csdn.net/hfty290/article/details/42844085

? ? 《Log4js配置詳解》http://blog.csdn.net/hfty290/article/details/42843737

? ? 《Log4js多進程陷阱與避免》http://blog.csdn.net/hfty290/article/details/42843303

一、概述

? ? 網絡上有不少關于Log4j的源碼解析文章,但是到目前為止還未見到一個log4js的源碼解析,雖然這兩者有其共同之處,但是在實現原理是存在顯著的差別。作為在node.js世界里最流行的日志模塊,了解其內部設計與實現還是挺有意義的。本篇將描述log4js的架構與實現,先簡要說明log4js中出現的元素,接著為每個元素做詳細說明,最后分析元素的協同工作。


二、設計元素簡述

? ? 在log4js中出現的設計元素包括:level、layout、appender、logger;請看下面表格:

?

?

三、色彩繽紛的Appender

? ? 不同的Appender實現不同的日志寫入方式,所有的Appender都在源碼的?lib/appenders目錄下,目前log4js提供了很多種的寫入方式,有file、datefile、multiprocess、console、clustered、gelf、hookio、loggly、smtp。本文將依次介紹前五種Appender。每個Appender的js文件都會導出appender和configure兩個函數,file與dateFile還會導出shutdown函數。

appender函數返回的是一個閉包函數,該閉包函數實現將內容寫入到日志。典型的appender函數實現如下:


function fileAppender (file, layout, logSize, numBackups) {…….var logFile = openTheStream(file, logSize, numBackups); return function(loggingEvent) {logFile.write(layout(loggingEvent) + eol, "utf8"); }; }

? ? 而configure函數根據參數提供配置信息,去調用對應的appender函數,將appender函數的返回值作為自己的返回值,如下:


function configure(config, options) {……return fileAppender(config.filename, layout, config.maxLogSize, config.backups); }

? ? 因此configure返回值是一個閉包函數,通過該函數可以實現將日志寫入到文件之中。

?

? ? 下面將依次介紹每個Appender的實現:

1、file:實現將日志寫入到文本文件之中,同時支持日志文件按照大小滾動。

?

?

2、datefile:實現將日志寫入到文本文件之中,日志按照日期進行滾動。

?

?

3、console:實現將日志寫入到控制臺。

?

?

4、multiprocess:實現多進程同步方式寫日志,具體是在master(自主配置)進程上開啟一個監聽端口,所有的worker進程將日志通過tcp發送給master,由master將日志寫入到文件中。注意:這種模式只支持配置一個appender,不能配置多個。

Master配置參數:

?

?

Worker配置參數:

?

5、clustered:用于node的cluster環境之中,實現方式與multiprocess類似,真正的寫日志是在Master中,Worker只是將日志發送給Master。Worker和Master的配置一樣,內部根據cluster.isMaster可以自動判斷。

配置參數:

?

?

四、布局Layout

?

? ? Layout實現每條日志記錄的格式化,log4js提供了多種的格式化樣式可供選擇,有basicLayout、messagePassThroughLayoutpatternLayoutcolouredLayout、coloredLayout,默認情況下會使用basicLayout。所有的Layout都在源碼的lib/layouts.js中定義。layouts.js文件除了導出上述說到的這些Layout,還導出一個layout函數,定義如下:

layout: function(name, config) {return layoutMakers[name] && layoutMakers[name](config); }layoutMakers = {"messagePassThrough": function() { return messagePassThroughLayout; }, "basic": function() { return basicLayout; }, "colored": function() { return colouredLayout; }, "coloured": function() { return colouredLayout; }, "pattern": function (config) {return patternLayout(config && config.pattern, config && config.tokens);} }

實現將一個文本描述的Layout轉換成內部定義的Layout函數。使用起來就像這樣: layout = layouts.layout(config.layout.type, config.layout); 其中的config.layout.type字段表示Layout的名稱,而config.layout中的其他字段為對應Layout的配置信息。只有創建pattern類型的Layout時才需要其他配置。

下面依次介紹每種Layout的功能。

1、basicLayout:最基礎的Layout,一個message通過該basicLayout會變成如下樣子:

[startTime] [logLevel] categoryName - message\n

2、 colouredLayout 、c oloredLayout :格式化日志內容,其中包括了顏色信息,顏色是根據每條日志的級別預定義的。每條記錄內容與basicLayout一樣:

[startTime] [logLevel] categoryName - message\n

3、 messagePassThroughLayout :日志內容只包括消息,沒有其他字段:

message\n

4、patternLayout:實現日志按照配置進行格式化,該Layout需要兩個參數,pattern、tokens;其中的pattern表示格式化字符串,tokens表示自定義函數。

預定義格式化有:

var replacers = {'c': categoryName,'d': formatAsDate,'h': hostname,'m': formatMessage,'n': endOfLine,'p': logLevel,'r': startTime,'[': startColour,']': endColour,'%': percent,'x': userDefined};
?

例如,一個patternLayout的配置如下:

"pattern":?"%[%r?(%x{pid})?%p?%c?-%]?%m%n",

"tokens":?{

"pid"?:?function()?{?return?process.pid;?}

}

? ? 其中自定義了tokens為pid,通過%x{pid}來引用。注意pattern的的?%[?與?%]?表示顏色的開始于結束。上述配置打印出來的日志如下:

18:13:39 (19556) INFO app - Test log message

?

五、Logger對象

?

? ? Logger對象實現對日志Level的管理,并定義了對外的寫日志接口。客戶端通過log4js.getLogger()獲取的就是該Logger對象。Logger類從events.EventEmitter繼承,因此Logger對象具有發生事件的能力。在log4js之中,寫日志是通過在log事件上注冊對應的appender來實現的。

Logger對象的組成:

?

?

?

?

六、log4js

?

? ? log4js源碼文件為lib/log4js.js,里面包含了一些函數來實現對appender的加載,日志的管理等操作。所有外面要使用log4js中的對象,都采用export的方式導出,可以直接引用,導出的成員如下:

?

?

1、日志管理

? ? log4js中為日志進行類別劃分,每個類別下最多可以創建一個Logger。同樣每個appender實例也有歸屬的類別,但是一個appender實例可以同時屬于多個類別。如圖1:

?

?

?

? ? 圖1:有兩個category分別為cheese與bread;每個category最多對應著一個logger對象。圖中有三個appender,cheese.log與cheese1.log類型為file,另外還有一個console。console這個appender同時指向了cheese和bread,也就是這兩個日志都會使用到console。另外cheese有三個appender指向它,意味著,如果想cheese分類的日志中寫日志,會同時向三個地方寫入,cheese.log,?cheese1.log,?console.

2、log事件

? ? 前面已經說明,調用Logger實例的寫日志操作,會觸發log事件。appender在log事件中被調用,從而實現記錄寫入到日志文件中。如圖1中類型為Cheese的Logger,關聯著三個appender實例,fileAppender-cheese.log,fileAppender-cheese1.log,console。那么當調用該logger寫日志函數,如logger.info時,觸發了log事件,與其關聯的三個appender實例被調用,最終這條日志內容被寫入到三個地方。

?

?? ? 圖2:Logger的事件監聽機制;用戶在調用logger.info(hello');?觸發了Logger實例的log事件,所有類別為Cheese的Appender實例(有三個),都會監聽到該事件,實現將日志記錄寫入到三個位置。另外還有一種為all的分類,如果指定一個appender的類型為all,那么將收到所有logger的log事件,log4js默認加載的console就是類型為all的appender。

3、替換console

? ? 在開發的過程中,為了方便可能直接將日志直接以console.log方式打印出來,使用log4js可以將console的日志重定向到日志文件中。log4js導出了兩個函數:

?

?

4、日志配置定期檢查更新

? ? log4js提供了自動重新加載日志配置,更新所有的appender與日志級別的信息,是一項非常使用的功能。log4js導出的configure函數中,第二個參數如果設置了reloadSecs,則會在指定的間隔秒數之后,重載配置。如下:

log4js.configure('file.json', { reloadSecs: 300 });

5、其他導出函數說明

?

?

?

? ? Log4js總共三篇博客

? ? 《Log4js原理解析》http://blog.csdn.net/hfty290/article/details/42844085

? ? 《Log4js配置詳解》http://blog.csdn.net/hfty290/article/details/42843737

? ? 《Log4js多進程陷阱與避免》http://blog.csdn.net/hfty290/article/details/42843303

?

?

?

?


總結

以上是生活随笔為你收集整理的Log4js原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。