为了账号安全,请及时绑定邮箱和手机立即绑定

在所有记录器中使用请求 ID

在所有记录器中使用请求 ID

Go
开心每一天1111 2022-08-01 11:09:04
我有一些使用go http的Web应用程序服务器,我希望每个请求都有uuid的上下文,为此,我可以使用http请求上下文 https://golang.org/pkg/net/http/#Request.Context我们正在使用logrus,我们在一个文件中启动它,并在其他文件中使用记录器实例。我需要的是在所有日志中打印请求ID,但不要在每个日志打印中添加新的paremeters,我想在每个http请求中对它做一次(传递req-id),所有日志打印都将拥有它而无需对它做任何事情例如,如果这样会打印id=123log.info("foo")// id=123 foo 我已经尝试了以下内容,但不确定这是正确的方法,请建议。package mainimport (    "context"    "errors"    log "github.com/sirupsen/logrus")type someContextKey stringvar (    keyA = someContextKey("a")    keyB = someContextKey("b"))func main() {    ctx := context.Background()    ctx = context.WithValue(ctx, keyA, "foo")    ctx = context.WithValue(ctx, keyB, "bar")    logger(ctx, nil).Info("did nothing")    err := errors.New("an error")    logger(ctx, err).Fatal("unrecoverable error")}func logger(ctx context.Context, err error) *log.Entry {    entry := log.WithField("component", "main")    entry = entry.WithField("ReqID", "myRequestID")    return entry}https://play.golang.org/p/oCW09UhTjZ5
查看完整描述

1 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

每次调用该函数时,都会创建一个新的 *log。输入并再次将请求 ID 写入其中。从你的问题来看,听起来你不希望这样。logger


func main() {

    ctx := context.Background()

    ctx = context.WithValue(ctx, keyA, "foo")

    ctx = context.WithValue(ctx, keyB, "bar")


    lg := logger(ctx)

    lg.Info("did nothing")

    err := errors.New("an error")

    lg.WithError(err).Fatal("unrecoverable error")

}


func logger(ctx context.Context) *log.Entry {

    entry := log.WithField("component", "main")

    entry = entry.WithField("ReqID", "myRequestID")


    return entry

}

这样做的缺点是,您必须将变量传递给此请求调用的每个函数,并且该函数还应记录请求 ID。lg


我们在公司所做的是创建一个薄层,该层具有一个额外的方法,因此我们可以传入请求上下文,它将提取请求ID本身(我们已经在中间件中写入了上下文)。如果不存在任何请求 ID,则不会向日志条目添加任何内容。但是,这确实将请求 ID 再次添加到每个日志条目中,就像您的示例代码一样。logrusWithRequestCtx


注意:我们围绕logrus的薄层具有更多的功能和默认设置,以证明额外的努力是合理的。从长远来看,有一个地方能够调整我们所有服务的日志记录是非常有帮助的。


注意2:同时,我们正在用零日志替换logrus,以使其更加轻量级。


查看完整回答
反对 回复 2022-08-01
  • 1 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信