Go 示例: 日志记录

Go 标准库提供了用于从 Go 程序输出日志的简单工具,包括用于自由格式输出的 log 包和用于结构化输出的 log/slog 包。

package main
import (
    "bytes"
    "fmt"
    "log"
    "os"
    "log/slog"
)
func main() {

只需调用 log 包中的 Println 等函数即可使用标准日志记录器,该记录器已预先配置为将合理的日志输出到 os.Stderr。其他方法,如 Fatal*Panic*,将在记录日志后退出程序。

    log.Println("standard logger")

可以使用标志配置日志记录器以设置其输出格式。默认情况下,标准日志记录器已设置 log.Ldatelog.Ltime 标志,这些标志收集在 log.LstdFlags 中。例如,我们可以更改其标志以以微秒精度发出时间。

    log.SetFlags(log.LstdFlags | log.Lmicroseconds)
    log.Println("with micro")

它还支持发出调用 log 函数的文件名和行号。

    log.SetFlags(log.LstdFlags | log.Lshortfile)
    log.Println("with file/line")

创建自定义日志记录器并将其传递可能很有用。创建新日志记录器时,我们可以设置一个前缀以区分其输出与其他日志记录器。

    mylog := log.New(os.Stdout, "my:", log.LstdFlags)
    mylog.Println("from mylog")

我们可以使用 SetPrefix 方法在现有日志记录器(包括标准日志记录器)上设置前缀。

    mylog.SetPrefix("ohmy:")
    mylog.Println("from mylog")

日志记录器可以具有自定义输出目标;任何 io.Writer 都可以。

    var buf bytes.Buffer
    buflog := log.New(&buf, "buf:", log.LstdFlags)

此调用将日志输出写入 buf

    buflog.Println("hello")

这实际上会在标准输出上显示它。

    fmt.Print("from buflog:", buf.String())

slog 包提供结构化日志输出。例如,以 JSON 格式记录日志非常简单。

    jsonHandler := slog.NewJSONHandler(os.Stderr, nil)
    myslog := slog.New(jsonHandler)
    myslog.Info("hi there")

除了消息之外,slog 输出还可以包含任意数量的键值对。

    myslog.Info("hello again", "key", "val", "age", 25)
}

示例输出;发出的日期和时间将取决于示例运行的时间。

$ go run logging.go
2023/08/22 10:45:16 standard logger
2023/08/22 10:45:16.904141 with micro
2023/08/22 10:45:16 logging.go:40: with file/line
my:2023/08/22 10:45:16 from mylog
ohmy:2023/08/22 10:45:16 from mylog
from buflog:buf:2023/08/22 10:45:16 hello

这些内容为了在网站上清晰呈现而进行了包装;实际上,它们是在一行上发出的。

{"time":"2023-08-22T10:45:16.904166391-07:00",
 "level":"INFO","msg":"hi there"}
{"time":"2023-08-22T10:45:16.904178985-07:00",
    "level":"INFO","msg":"hello again",
    "key":"val","age":25}

下一个示例:HTTP 客户端.