Go 原始碼學習 log 庫

2021-10-03 01:15:07 字數 2446 閱讀 6006

log 包實現了乙個簡單的日誌功能。

logger 結構體作為日誌物件,生成文字行到 io.writer。每次記錄日誌的操作都生成一行日誌,即便是log.printf也不用包含\n。結構體中有sync.metex鎖,保證了在多 goroutine 情況時的順序寫入。

type logger struct

其中 flags 可選項如下:

const

( ldate =

1<<

iota

// 本地時區的日期: 2009/01/23

lmicroseconds // 毫秒粒度: 01:23:23.123123. 包含了 ltime.

llongfile // 完整的路徑和檔名和行號: /a/b/c/d.go:23

lshortfile // 不包含路徑,僅檔名和行號: d.go:23. overrides llongfile

lutc // 使用 utc 而非本地時區

lstdflags = ldate | ltime // 標準 logger 的初始 flag 值

)

new 函式用於建立 logger,三個引數是:輸出目標, 字首字串,屬性標誌

func

new(out io.writer, prefix string

, flag int

)*logger

logger 的 setoutput 方法用於設定輸出目標

func

(l *logger)

setoutput

(w io.writer)

包中提供了乙個標準 logger - std,我們的程式中執行log.print時執行的就是std.print

var std =

new(os.stderr,

"", lstdflags)

logger 的 formatheader 方法將字首字串、日期、時間、檔名和行號寫入緩衝區,它會呼叫itoa函式格式化文字。

func

(l *logger)

formatheader

(buf *

byte

, t time.time, file string

, line int

)

logger 的 output 方法列印日誌,它處理流程如下:

func

(l *logger)

output

(calldepth int

, s string

)error

獲取當前時間

logger 加鎖

如果 flags 設定了 lshortfile 或 llongfile,先解鎖,再呼叫runtime.caller()函式獲取檔名,再加鎖。解鎖加鎖是因為獲取檔名的動作消耗較大

清空 logger 的緩衝buf

呼叫formatheader方法將時間、檔名、行號寫入緩衝buf

將日誌內容追加寫入緩衝buf

如果行尾沒有換行符就新增乙個換行符

將緩衝buf寫入輸出目標

logger 的 printf、print、println 呼叫 output 方法列印日誌,fatal、fatalf、fatalln 呼叫 output 方法列印日誌後以錯誤碼1退出程式,panic、panicf、panicln 呼叫 output 方法列印日誌後觸發panic,panic的內容就是日誌內容。

還有其他一些設定和獲取自定義 logger 或者 std logger 的字首字串、屬性標誌和輸出目標的函式和方法。

logger 結構體裡面的 buf 是為了高效寫入,除此以外,log 包裡面還有乙個itoa函式,它會高效地把整數按位轉換為位元組陣列寫入緩衝buf

func

itoa

(buf *

byte

, i int

, wid int

)// i < 10

b[bp]

=byte

('0'

+ i)

*buf =

(*buf, b[bp:

]...

)}

如果要像 python 的logging 那樣可以設定日誌旋轉的日誌功能可以使用這個包:lumberjack

Go 筆記三 庫原始碼檔案

庫原始碼檔案不能被直接執行,它僅用於存放程式實體。只要遵從 go 語言規範,這些程式實體就可以被其他 使用。在 go 語言中,它是變數 常量 函式 結構體和介面的統稱。第一條規則,同目錄下的原始碼檔案的 包宣告語句要一致。也就是說,它們要同屬於乙個 包。這對於所有原始碼檔案都是適用的。第二條規則,原...

Go 標準庫 context 原始碼解析

context 主要用來在goroutine 之間傳遞上下文資訊,包括取消訊號 超時時間 截止時間 k v等。標準庫的許多介面加上了 context 引數,來實現併發控制和超時控制。type context inte ce err error value key inte ce inte ce 該介...

go語言學習 go語言原始碼檔案

二 庫原始碼檔案 三 總結 原始碼檔案分為三種,即 命令原始碼檔案 庫原始碼檔案和測試原始碼檔案。命令原始碼檔案 庫原始碼檔案 測試原始碼檔案 1.1命令原始碼檔案介紹 package main import flag包用於接收和解析命令引數 flag fmt包含有格式化i o函式 fmt var ...