如何在golang中实现基于级别的日志记录?

pym*_*ymd 45 logging go

在golang中是否有可用于基于级别的日志记录的好包装器?如果没有,我应该如何自己实施?

我想要的很简单.我想要一些功能,例如

log.Error()
log.Info()
Run Code Online (Sandbox Code Playgroud)

等等,它们将输出显示给stdout,并将它们保存在日志文件中(基于作为命令行参数给予程序的级别).我如何实现这个包装器?

Bry*_*yan 47

现在有了更多建议,现有答案已经很久了:

  • nanolog不满足“将其输出显示到stdout”的要求。Binlog的GitHub星为零。 (2认同)

ynn*_*ynn 25

2023 年的今天,Go 1.21.0 终于带来了一个标准级别的记录器:log/slogpackage

对于普通用户来说,不再需要外部库。

1. 基本使用

package main

import "log/slog"

func main() {
    slog.Info("hello")
    slog.Warn("hello")
    slog.Error("hello")
}
Run Code Online (Sandbox Code Playgroud)
2023/08/09 20:05:49 INFO hello
2023/08/09 20:05:49 WARN hello
2023/08/09 20:05:49 ERROR hello
Run Code Online (Sandbox Code Playgroud)

1.1 启用Debug日志级别

操场

Debug默认情况下禁用日志级别。要启用它,请调用SetLogLoggerLevel()(在 Go 1.22 或更高版本中可用):

2023/08/09 20:05:49 INFO hello
2023/08/09 20:05:49 WARN hello
2023/08/09 20:05:49 ERROR hello
Run Code Online (Sandbox Code Playgroud)

1.2 禁用日志记录

操场

如果您想(暂时)禁用日志记录,最干净的解决方案是定义您自己的记录器(有关详细信息,请参阅4. 创建您自己的记录器)。

然而,这句俏皮话却有效:

slog.SetLogLoggerLevel(slog.LevelDebug)
Run Code Online (Sandbox Code Playgroud)

2. 添加上下文

名称slog是Structured Logging的缩写,这意味着每个日志条目都可以有一个结构。

日志函数可以选择接收任意数量的键值对:

slog.SetLogLoggerLevel(math.MaxInt)
Run Code Online (Sandbox Code Playgroud)
2023/08/09 20:07:51 INFO hello username=Mike age=18
Run Code Online (Sandbox Code Playgroud)

3. 自定义格式

log可用于自定义log/slog记录器的格式。

package main

import "log/slog"

func main() {
    slog.Info("hello", "username", "Mike", "age", 18)
}
Run Code Online (Sandbox Code Playgroud)
2023/08/09 20:15:36 INFO hello
2023/08/09 20:15:36.601583 INFO hello
Run Code Online (Sandbox Code Playgroud)

4. 创建您自己的记录器

顶级函数(例如slog.Info())涵盖了基本用法,但您可以创建自己的记录器以进行详细定制。

创建的记录器可以通过设置为默认记录器slog.SetDefault()。之后,顶级函数(例如slog.Info())使用您的记录器。

4.1 标准记录仪

log/slog一些内置记录器的包中提供了构造函数。

2023/08/09 20:07:51 INFO hello username=Mike age=18
Run Code Online (Sandbox Code Playgroud)
time=2023-08-09T20:31:05.798+09:00 level=DEBUG msg=hello username=Mike age=18
{"time":"2023-08-09T20:31:05.798984192+09:00","level":"DEBUG","msg":"hello","username":"Mike","age":18}
Run Code Online (Sandbox Code Playgroud)

4.2 用户定义的记录器

通过实现Handler接口,您可以创建完全定制的记录器。

package main

import "log"
import "log/slog"

func main() {
    slog.Info("hello")
    log.SetFlags(log.Ldate | log.Lmicroseconds)
    slog.Info("hello")
}
Run Code Online (Sandbox Code Playgroud)

由于日志级别的类型定义为type Level int,您甚至可以定义自己的日志级别:Go Playground


小智 6

https://github.com/hashicorp/logutils 我发现这非常容易使用,您甚至不需要更改log.Printf对 std 库的方法调用。


Ank*_*nde 5

  • Uber-go / Zap:Go中快速,结构化,分级的日志记录
  • Logrus:Go的结构化,可插入的日志记录。(JSON和文本格式)

这两个库都具有级别挂钩,这是一个非常有趣的功能。可以为特定的日志级别注册钩子。因此,例如发生任何错误(使用记录log.Error()),您可以向某些监视工具等报告。