glog 紀錄檔庫簡介與測試【GO 常用的庫】

2023-09-12 18:00:23

〇、前言

golang/glog 是 C++ 版本 google/glog 的 Go 版本實現,基本實現了原生 glog 的紀錄檔格式。

在 Kuberntes 中,glog 是預設紀錄檔庫。因此需要詳細瞭解下。下面列舉下 glog 的特點:

  • 高效性:glog 採用了非同步寫入紀錄檔的方式,這意味著紀錄檔記錄操作不會阻塞主程式的執行。它還使用了緩衝區來收集紀錄檔訊息,並在後臺執行緒中將它們寫入磁碟。這種非同步寫入機制可以顯著提高應用程式的效能。
  • 靈活設定:glog 允許您通過命令列引數或組態檔來自定義紀錄檔輸出的行為。可以指定要記錄的紀錄檔級別、紀錄檔檔案的路徑、是否同時輸出到標準錯誤流等。這使得 glog 非常適合於不同環境和需求的應用程式。
  • 紀錄檔級別控制:glog 支援不同的紀錄檔級別,包括 INFO、WARNING、ERROR、FATAL 等。可以根據需要,選擇要記錄的紀錄檔級別,以便及時發現關鍵的紀錄檔資訊。
  • 紀錄檔格式化:glog 提供了豐富的紀錄檔格式化選項,允許您按照自己的喜好定義紀錄檔的輸出格式。您可以指定時間戳、原始碼位置、紀錄檔級別等資訊的顯示方式,以及自定義的文字和變數的輸出。
  • 紀錄檔回滾:glog 支援紀錄檔檔案的自動回滾功能,可以根據檔案大小或日期來切分紀錄檔檔案。這樣可以避免單個紀錄檔檔案過大導致難以管理和分析。
  • 跨平臺支援:glog 是一個跨平臺的紀錄檔庫,可以在不同的作業系統上使用。它提供了對 Unix、Linux 和 Windows 等主流作業系統的支援。

強大功能且簡單易用的 glog 紀錄檔庫,為 GO 語言開發者提供了一種高效、靈活和可客製化的紀錄檔記錄解決方案。無論是小型專案還是大規模應用程式,glog 都能滿足日常的紀錄檔需求,也能協助開發者更好地理解和偵錯程式碼。

glog 的基本實現邏輯就是,在 buffer 中寫入格式化的內容並定期刷入檔案中。

一、glog 詳細介紹

1.1 紀錄檔級別與測試

glog 將紀錄檔級別分為 4 種,分別是:

  • INFO:一般紀錄檔,可用於記錄程式執行狀態;
  • WARNING:警告紀錄檔,記錄潛在的問題或錯誤;
  • ERROR:錯誤紀錄檔,記錄程式執行中一些可恢復的錯誤,可能導致程式功能受限或出現異常情況,但是不會導致系統崩潰;
  • FATAL:嚴重錯誤紀錄檔,程式遇到一個不可恢復的錯誤,在列印完紀錄檔後程式將會自動退出(os.Exit()

開始測試之前,準備工作:

// 1.建立資料夾和檔案:./src/glog/main.go
// 2.初始化和整理當前模組(新增或刪除)
go mod init
go mod tidy
// 3.拉取必要的庫 glog
go get github.com/golang/glog

如下為 main.go 檔案中的程式碼:

package main

import (
	"flag"

	"github.com/golang/glog"
)

func main() {
    // 用於解析命令列中 - 橫線後邊的引數和值,如下範例中的:-log_dir=log -alsologtostderr
    // go run main.go -log_dir=log -alsologtostderr
	flag.Parse()
    // defer() 退出前執行,清空快取區,將紀錄檔寫入檔案
	defer glog.Flush()

	glog.Info("This is info message")
	glog.Infof("This is info message: %v", 12345)
	glog.InfoDepth(1, "This is info message", 12345)

	glog.Warning("This is warning message")
	glog.Warningf("This is warning message: %v", 12345)
	glog.WarningDepth(1, "This is warning message", 12345)

	glog.Error("This is error message")
	glog.Errorf("This is error message: %v", 12345)
	glog.ErrorDepth(1, "This is error message", 12345)

	glog.Fatal("This is fatal message")
	glog.Fatalf("This is fatal message: %v", 12345)
	glog.FatalDepth(1, "This is fatal message", 12345)
}

 然後就是執行程式碼:

// 1.建立 log 資料夾,必須先建立,否則無法以檔案形式輸出紀錄檔
mkdir log
// 2.將紀錄檔寫入到 log 資料夾下
go run main.go -log_dir=log -alsologtostderr
// log_dir:用來指定紀錄檔資料夾名
// alsologtostderr:表示既在標準視窗輸出也在檔案中記錄

 記錄紀錄檔的其他設定項簡介:

  • -stderrthreshold=ERROR    達到或高於此嚴重程度的紀錄檔事件被記錄為標準錯誤以及檔案。
  • -log_backtrace_at=""     設定儲存一般紀錄檔的檔案和行號,例如:-log_backtrace_at = gopherflakes.go:234,預設堆疊跟蹤都會寫入 Info 紀錄檔,檔名的字尾可以不為 .go。
  • -v=0    在指定級別上啟用 v 級紀錄檔記錄。
  • -vmodule=""    通過數位指定檔案的記錄紀錄檔級別,可以同時設定多個檔案的不同級別,用‘,’分隔。例如:-vmodule=recordio=2,file=1,gfs*=3,最後一個代表所有以‘gfs’開頭的檔案記錄 3 級以下的紀錄檔。檔名的字尾必須為 .go,且可省略。

下面看下 Warning 級別的紀錄檔檔案記錄的內容:

1.2 vmodule 設定

vmodule 引數通過 -v=int 來自由設定輸出級別,int 代表級別的數位,預設為 0。如下範例:

package main

import (
	"flag"

	"github.com/golang/glog"
)

func main() {
	// 用於解析命令列中 - 橫線後邊的引數和值,如下範例中的:-log_dir=log -alsologtostderr
	// go run main.go -log_dir=log -alsologtostderr
	flag.Parse()
	// defer() 退出前執行,清空快取區,將紀錄檔寫入檔案
	defer glog.Flush()

	glog.V(0).Info("LEVEL 0 message") // 使用紀錄檔級別 0
	glog.V(3).Info("LEVEL 3 message") // 使用紀錄檔級別 3
	glog.V(4).Info("LEVEL 4 message") // 使用紀錄檔級別 4
	glog.V(5).Info("LEVEL 5 message") // 使用紀錄檔級別 5
	glog.V(8).Info("LEVEL 8 message") // 使用紀錄檔級別 8
}

 如下測試結果,當不加 -v 設定項時,只輸出了預設級別為 0 的紀錄檔,當設定為 4 時,輸出 <=4 級別的紀錄檔:

 

1.3 vmodule 多檔案設定不同的紀錄檔級別

通過該功能,可以對指定模組採用不同紀錄檔級別的輸出,可有效提升偵錯效率

main.go 檔案內容:

package main

import (
	"flag"

	"github.com/golang/glog"
)

func main() {
	// 用於解析命令列中 - 橫線後邊的引數和值,如下範例中的:-log_dir=log -alsologtostderr
	// go run main.go -log_dir=log -alsologtostderr
	flag.Parse()
	// defer() 退出前執行,清空快取區,將紀錄檔寫入檔案
	defer glog.Flush()
	bar()
	bar2()
	glog.V(0).Info("LEVEL 0 message") // 使用紀錄檔級別 3
	glog.V(3).Info("LEVEL 3 message") // 使用紀錄檔級別 3
	glog.V(4).Info("LEVEL 4 message") // 使用紀錄檔級別 4
	glog.V(5).Info("LEVEL 5 message") // 使用紀錄檔級別 5
	glog.V(8).Info("LEVEL 8 message") // 使用紀錄檔級別 8
}

 bar.go、bar2.go 檔案內容:

package main

import "github.com/golang/glog"

func bar() {
	glog.V(3).Info("LEVEL 3: level 3 message in bar.go")
	glog.V(4).Info("LEVEL 4: level 4 message in bar.go")
}

package main

import "github.com/golang/glog"

func bar2() {
	glog.V(4).Info("LEVEL 4: level 4 message in bar2.go")
}

如下執行語句,相關的三個檔案都需要列出,全域性設定為 -v=3,bar.go 檔案中設定為 3 級,bar2.go 檔案設定為 4 級,多檔案間用‘,’分隔

go run main.go bar.go bar2.go -log_dir=log -alsologtostderr -v=3 -vmodule=bar=3,bar2=4

如下圖為輸出結果,bar.go 檔案中大於 3 級的紀錄檔未輸出,main.go 中 3 級及以下的紀錄檔輸出:

對於檔名還可以使用萬用字元 *,如下測試:

go run main.go bar.go bar2.go -log_dir=log -alsologtostderr -v=3 -vmodule=bar*=4

1.4 traceLocation 功能(log_backtrace_at 引數設定)

 traceLocation 的命令格式為-log_backtrace_at=bar.go:6(檔案全名:行號),當執行到指定程式碼處時,將把該程式碼的棧資訊列印出來。

 如下語句執行程式碼,在檔案 bar.go 中的第 6 行,輸出棧資訊:

go run main.go bar.go bar2.go -log_dir=log -alsologtostderr -v=3 -vmodule=bar=3,bar2=4 -log_backtrace_at=bar.go:6

1.5 紀錄檔格式簡介

從前邊幾節中可知,紀錄檔預設的格式為:<header>] <message>,紀錄檔頭資訊和詳細資訊通過中括號 ] 來分隔。

header 的預設格式:Lmmdd hh:mm:ss.uuuuuu threadid file:line。其中開頭的字母 L 代表的是紀錄檔級別 level,如下對應關係:

I -> INFO
W -> WARNING
E -> ERROR
F -> FATAL

threadid 是程序 PID,即 os.Getpid() 的呼叫結果。

參考:https://cloud.tencent.com/developer/article/1683448