Golang 1.21.0 log/slog 库实践| 青训营

529 阅读1分钟

var logger slog.Logger

func SlogAddSource(msg string, args ...slog.Attr) {
    var pcs [1]uintptr
    runtime.Callers(2, pcs[:])
    r := slog.NewRecord(time.Now(), slog.LevelInfo, msg, pcs[0])
    r.AddAttrs(args...)
    _ = logger.Handler().Handle(context.Background(), r)
}

下面是一个简单的定义例子

package log

import ( "context" "log/slog" "runtime" "time" )

var logger *slog.Logger

func pc(level slog.Level, msg string, args ...slog.Attr) {
    var pcs [1]uintptr
    runtime.Callers(3, pcs[:])
    r := slog.NewRecord(time.Now(), level, msg, pcs[0])
    r.AddAttrs(args...)
    _ = logger.Handler().Handle(context.Background(), r)
}

func Info(msg string, args ...slog.Attr) { pc(slog.LevelInfo, msg, args...) }

func Error(msg string, args ...slog.Attr) { pc(slog.LevelError, msg, args...) }

我实现了 Info 和 Error 两个方法,用来调用并添加回调。

在我的业务中,我采用下面的内容来输出

var logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: true}))

这段代码的作用是添加一个新的 logger,添加追踪,输出到屏幕。

之后

func SlogAddSource(msg string, args ...slog.Attr) {
    var pcs [1]uintptr
    runtime.Callers(3, pcs[:])
    r := slog.NewRecord(time.Now(), slog.LevelInfo, msg, pcs[0])
    r.AddAttrs(args...)
    _ = logger.Handler().Handle(context.Background(), r)
}

简单解释,修改 runtime.Callers(3, pcs[:]) 中的数字就可以定义跳出的列,比如我这边是一个复用的统一返回接口,那我就要在原先的基础上再多跳一层。

最后调用了logger.Handler().Handle(context.Background(), r) 就打印日志了

调用的话可以用

SlogAddSource(trace, slog.Uint64("code", code), slog.Any("err", err))