猿问

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

我有一些使用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 main


import (

    "context"

    "errors"


    log "github.com/sirupsen/logrus"

)


type someContextKey string


var (

    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


开心每一天1111
浏览 130回答 1
1回答

潇湘沐

每次调用该函数时,都会创建一个新的 *log。输入并再次将请求 ID 写入其中。从你的问题来看,听起来你不希望这样。loggerfunc 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,以使其更加轻量级。
随时随地看视频慕课网APP

相关分类

Go
我要回答