gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 10:09:15 25 4
gpt4 key购买 nike

我有一些使用 go http 的 Web 应用程序服务器,我希望每个请求都具有 uuid 上下文,为此我可以使用 http 请求上下文 https://golang.org/pkg/net/http/#Request.Context

我们正在使用 logrus我们在一个文件中启动它并在其他文件中使用记录器实例。

我需要的是在所有日志中打印请求 ID,但不向每个日志打印添加新的参数,我想在每个 http 请求中执行一次(传递 req-id)并且所有日志打印都会有它没有对它做任何事情

例如如果 id=123 那么 log.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

最佳答案

每次调用 logger 函数时,您都会创建一个新的 *log.Entry 并再次将请求 ID 写入其中。从您的问题来看,您似乎不想这样。

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
}

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

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

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

注意 2:同时我们正在用 zerolog 替换 logrus 以更轻量级。

关于go - 在所有记录器中使用请求 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65566386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com