golang結(jié)構(gòu)化日志slog的用法簡介
日志是任何軟件的重要組成部分,Go 提供了一個內(nèi)置日志包(slog)。然而,隨著應(yīng)用的復(fù)雜性不斷增加,對結(jié)構(gòu)化日志的需求也越來越明顯。結(jié)構(gòu)化日志允許開發(fā)人員以結(jié)構(gòu)化格式記錄數(shù)據(jù),便于日志聚合工具進(jìn)行解析和分析,目前業(yè)界使用比較多的是:zap。
在本文中,我將簡單介紹 slog 包、它的功能以及如何在 Go 應(yīng)用程序中使用它。
什么是 slog
slog
提供結(jié)構(gòu)化日志記錄,其中的日志記錄包括一條消息、level 和其他各種以鍵值對表示的屬性。
使用
最新的1.21
版本引入了slog
。要在 Go 項目中使用slog
,可以通過以下方式導(dǎo)入它:
import "log/slog"
這里寫一個非常簡單的例子:
func main() { slog.Info("hello, world!", "coding", "happy") }
輸出:
2023/09/15 13:42:27 INFO hello, world! coding=happy
功能
slog
提供了許多有用的功能,使其成為 Go 的強大日志包。以下是其中的一些主要功能:
- 結(jié)構(gòu)化日志
- 嚴(yán)重級別日志
- 分組日志
- 自定義處理
結(jié)構(gòu)化日志
slog
默認(rèn)提供兩種方式:
- TextHandler
- JSONHandler
我們寫一下使用這兩個方式的例子:
func main() { textHandler := slog.NewTextHandler(os.Stdout, nil) textLogger := slog.New(textHandler) textLogger.Info("TextDemo", slog.String("app-version", "v0.0.1"), slog.Int("release-version", 1), ) jsonHandler := slog.NewJSONHandler(os.Stdout, nil) jsonLogger := slog.New(jsonHandler) jsonLogger.Info("JsonDemo", slog.String("app-version", "v0.0.1"), slog.Int("release-version", 1), ) }
輸出為:
time=2023-09-15T13:48:37.424+08:00 level=INFO msg=TextDemo app-version=v0.0.1 release-version=1
{"time":"2023-09-15T13:48:37.4647782+08:00","level":"INFO","msg":"JsonDemo","app-version":"v0.0.1","release-version":1}
從上面我們可以看到,代碼中使用了類似slog.String
的方法,slog
提供了指定屬性的功能。有多種類型的屬性可供選擇:
- slog.String:字符串屬性。
- slog.Int:整數(shù)屬性。
- slog.Float64:浮點屬性。
- slog.Bool:布爾屬性。
- slog.Duration:持續(xù)時間屬性。
- slog.Time:時間屬性。
- slog.Group:組屬性,可用于將相關(guān)屬性分組
func main() { jsonHandler := slog.NewJSONHandler(os.Stdout, nil) jsonLogger := slog.New(jsonHandler) jsonLogger.Info( "attributes", slog.String("version", "1.0.0"), slog.Int("app-version", 1), slog.Float64("point-value", 1.2), slog.Bool("status", true), slog.Duration("duration", time.Hour*1), slog.Time("time", time.Now()), slog.Group( "request", slog.String("path", "<https://example.com>"), slog.String("method", "get"), ), ) }
對應(yīng)的輸出,我已經(jīng)將其格式化了:
{ "time": "2023-09-15T13:53:43.8848272+08:00", "level": "INFO", "msg": "attributes", "version": "1.0.0", "app-version": 1, "point-value": 1.2, "status": true, "duration": 3600000000000, "time": "2023-09-15T13:53:43.8848272+08:00", "request": { "path": "<https://example.com>", "method": "get" } }
嚴(yán)重級別日志
這允許我們記錄不同嚴(yán)重程度的信息。slog
默認(rèn)提供四個日志級別,每個級別都有一個整數(shù)值:
- DEBUG(-4)
- INFO(0)
- WARN(4)
- ERROR(8)
例子:
func main() { jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelDebug, }) jsonLogger := slog.New(jsonHandler) jsonLogger.Debug("Hello, world!") jsonLogger.Info("Hello, world!") jsonLogger.Warn("Hello, world!") jsonLogger.Error("Hello, world!") }
NOTE: 記得在NewHandler
時設(shè)置級別。
分組日志
分組日志指的是將日志信息歸類為邏輯組或類別的做法。Slog
通過使用與日志記錄相關(guān)聯(lián)的屬性或鍵值對來支持分組日志記錄。
例子:
func main() { jsonHandler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelDebug, }) jsonLogger := slog.New(jsonHandler).WithGroup("request") jsonLogger.Info("", slog.String("url", "<https://example.com>"), slog.String("method", "GET"), slog.Int("response-code", 200), ) }
這里有個比較好的實踐:
- 在 http 服務(wù)的 middleware 中定義一個 request 組的 logger,會一些 4xx、5xx等請求的一些信息打印出來。
- 而普通業(yè)務(wù)的話,我們又可以使用一個 service 組的 logger
自定義處理
slog
能夠創(chuàng)建自定義handler
,將日志信息寫入不同的目的地,如文件、數(shù)據(jù)庫或外部服務(wù)。
slog
提供的處理程序接口定義了自定義處理程序必須實現(xiàn)的方法。處理程序接口有四個方法:
type Handler interface { Enabled(Level) bool Handle(Record) error WithAttrs([]Attr) Handler WithGroup(string) Handler }
下面舉例說明如何創(chuàng)建一個將日志信息寫入文件的自定義handler
:
type FileHandler struct { file *os.File } func NewFileHandler(filename string) (*FileHandler, error) { file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return nil, err } return &FileHandler{file}, nil } func (h *FileHandler) Enabled(_ context.Context, level slog.Level) bool { return true } func (h *FileHandler) Handle(_ context.Context, record slog.Record) error { _, err := h.file.WriteString(record.Message + "\n") return err } func (h *FileHandler) WithAttrs(attrs []slog.Attr) slog.Handler { return h } func (h *FileHandler) WithGroup(name string) slog.Handler { return h } func (h *FileHandler) Close() error { return h.file.Close() } func main() { fileHandler, err := NewFileHandler("log.log") if err != nil { panic(err) } defer fileHandler.Close() logger := slog.New(fileHandler) logger.Info("Hello, world!") logger.Debug("Debugging errors") }
這個時候運行程序時,控制臺就不會有對應(yīng)的日志輸出了,而是輸出到對應(yīng)文件上:
slogDemo cat .\log.log
Hello, world!
Debugging errors
總結(jié)
slog
是一個功能強大的 Go 日志包,提供結(jié)構(gòu)化日志功能。它易于使用,并提供了許多有用的功能,如級別日志和自定義處理程序。如果你正在尋找一個能滿足你不斷增長的應(yīng)用程序需求的日志包,那么 slog
絕對值得你一試。
到此這篇關(guān)于golang結(jié)構(gòu)化日志slog的用法簡介的文章就介紹到這了,更多相關(guān)go slog內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go實現(xiàn)自動解壓縮包以及讀取docx/doc文件內(nèi)容詳解
在開發(fā)過程中,我們常常需要處理壓縮包和文檔文件。本文將介紹如何使用Go語言自動解壓縮包和讀取docx/doc文件,需要的可以參考一下2023-03-03Go string轉(zhuǎn)int,int64,int32及注意事項說明
這篇文章主要介紹了Go string轉(zhuǎn)int,int64,int32及注意事項說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07GoLang?channel關(guān)閉狀態(tài)相關(guān)操作詳解
Channel?和?goroutine?的結(jié)合是?Go?并發(fā)編程的大殺器。而?Channel?的實際應(yīng)用也經(jīng)常讓人眼前一亮,通過與?select,cancel,timer?等結(jié)合,它能實現(xiàn)各種各樣的功能。接下來,我們就要介紹GoLang?channel關(guān)閉狀態(tài)相關(guān)操作2022-10-10