這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。nxlog4go的項目網址:<https://github.com/ccpaging/nxlog4go>## 項目曆史ccpaging's log4go forked from <https://github.com/alecthomas/log4go>The latest release is 4.0.3 詳見:<https://github.com/ccpaging/log4go/releases>修複了一些bug。在修改的過程中產生了不少想法。詳見:<http://www.cnblogs.com/ccpaging/p/7205226.html>實現這些想法要修改log4go的基本架構,因此,項目更名為 [nxlog4go](https://github.com/ccpaging/nxlog4go)## nxlog4go 簡介nxlog4go 融合了log4net 與 go log的基本架構。Logger 是日誌記錄容器。包含了若干 Filter。另外,nxlog4go的Logger相容了go log的io.Writer,同樣支援io,MultiWriter。Filter 基於level過濾日誌。每個 Filter 包含一個 Appender。Appender 輸出日誌。例如,輸出到彩色終端、滾動檔案、TCP/IP部落格伺服器等。Layout 格式化日誌。詳細瞭解log4net的結構請參考:1. [log4net Tutorial](https://www.codeproject.com/Articles/140911/log-net-Tutorial)2. [log4net教程](https://www.bbsmax.com/A/pRdBZmEedn/)## LoggerLogger 的結構如下:```gotype Logger struct {mu sync.Mutex // ensures atomic writes; protects the following fieldsprefix string // prefix to write at beginning of each linecaller bool // runtime caller skipout io.Writer // destination for outputlevel Level // The log levellayout Layout // format record for outputfilters *Filters // a collection of Filters}```分成幾個部分:1. 鎖。協調寫日誌和改變更配置置。如果能保證在寫日誌前配置,鎖不是必須的。2. 首碼和取來源程式檔案名稱行號的開關。由於後者消耗了大量的cpu,可能不適合生產環境,因此,設定了開關可以關閉。首碼可以在多模組的系統中用於區分不同的模組。也許在網路搜集日誌的模型中可用於過濾和分發。3. go log相容的 io.Writer 以及附加的level過濾和layout格式化。nxlog4go 的 logger 直接使用而無需添加任何的 Appender。方便程式員在開發環境下使用。4. filter容器的指標。使用指標可以容易的設定和重設。建立 Logger 有三種方式:1. 使用 nxlog4go 內建的 logger。2. 在main.go中建立全域變數。3. 在多模組系統中,設定單獨的模組建立全域變數供其它模組調用。如果在package開發中使用,建議增加函數:func GetLogger() *Logger {return ...}返回 Logger 的變數指標,方便使用package的程式對 Logger 進行設定。## FilterFilter 的結構如下:```gotype Filter struct {Level LevelAppenderrec chan *LogRecord// write queueclosingbool// true if filter was closed at API level}```nxlog4go 提供了標準的 go routine 架構,最大程度的方便程式員開發新的 Appender。## AppenderAppender 的結構如下:```gotype Appender interface {// Set option about the Appender. The options should be set as default.// Must be set before the first log message is written if changed.// You should test more if have to change options while running.SetOption(name string, v interface{}) error// This will be called to log a LogRecord message.Write(rec *LogRecord)// This should clean up anything lingering about the Appender, as it is called before// the Appender is removed. Write should not be called after Close.Close()}```Appender 是一個介面定義。有以下特點:1. 可擴充性。Filter 自動調用 Write,程式員可以編寫自己的 Write,例如將日子存入map file、存入資料庫等等。1. nxlog4go 提供了一些基礎的Appender,例如: * color 目錄下的彩色螢幕日誌輸出 * file 目錄下可用於生產環境的定時滾動記錄檔輸出 * socket 目錄下支援TCP/UDP Client的部落格輸出 這些 Appender 可以作為開發新輸出介面的參考。## LayoutLayout 的結構如下:```gotype Layout interface {// Set option about the Layout. The options should be set as default.// Must be set before the first log message is written if changed.// You should test more if have to change options while running.Set(name string, v interface{}) LayoutGet(name string) string// This will be called to log a LogRecord message.Format(rec *LogRecord) []byte}```在早期的 log4go 中只提供了一個函數介面,基於字串處理。在nxlog4go中使用[]byte,避免反覆轉換造成的效率降低。對效率提高影響最大的則是借用了 go log 的 itoa 函數。```go// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.func itoa(buf *[]byte, i int, wid int) {// Assemble decimal in reverse order.var b [20]bytebp := len(b) - 1for i >= 10 || wid > 1 {wid--q := i / 10b[bp] = byte('0' + i - q*10)bp--i = q}// i < 10b[bp] = byte('0' + i)*buf = append(*buf, b[bp:]...)}```加上 log4net 的 timeCacheType,為 nxlog4go 提供了高效率低cpu消耗的 PatternLayout。同時還提供了擴充 Layout 可能性。例如參照<https://github.com/nblib/log4go/>做的jsonLayout,據稱比json編碼的效率高一倍。## 配置log4net,作為一個.net程式用的是xml設定檔驅動的。go lang裡邊如果這樣做,如log4go那樣,Appender的擴充性將受到限制。go lang 中的日誌系統如此之多,似乎沒有程式員滿意其他人做的日誌。擴充性比配置驅動更加重要。nxlog4go 提供了使用 xml、json 設定檔的樣本程式。詳見 example 目錄。---將來也許還會寫 nxlog4go 的使用。敬請關注……目前 nxlog4go 還正在開發中,有些細節可能還會調整。歡迎大家 Fork and Star,提供Issues and Pull Request。<https://github.com/ccpaging/nxlog4go>230 次點擊