go微服务中如何给每条日志添加trace id

我想将跟踪 ID 添加到针对微服务的每个请求完成的日志记录中。我希望这与 springboot 应用程序类似,我们可以在 MDC 中设置跟踪 ID 并获取它并在日志记录时使用它。


我做了一些研究,发现 go lang 中的 MDC 等价物是上下文。所以,我已经在我的上下文中设置了跟踪 ID。现在的问题是我必须使用跟踪 ID 登录的地方,我需要将上下文传递给该函数,这是非常丑陋的方式。我正在为这个问题寻找更好的解决方案。


func HandlerFunction(f gin.HandlerFunc) gin.HandlerFunc{

    return func(cxt *gin.Context) {

        reqraceId := cxt.Request.Header.Get("trace-id")

        requid , _ := uuid.NewRandom()


        if reqTraceId == "" {

            c.Request.Header.Set("trace-id", requid.String())

        }


        f(c)

    }

}


慕森王
浏览 327回答 3
3回答

犯罪嫌疑人X

context.Context其中有一节说:在谷歌,我们要求 Go 程序员将 Context 参数作为第一个参数传递给传入和传出请求之间的调用路径上的每个函数。TL;DR - 传递上下文很好,但最好的方法是什么?有两种主要模式询问上下文给你一个记录器为记录器提供上下文上下文可用于存储值:context.WithValue(ctx, someKey, someValue)这意味着我们可以这样做:somepackage.Log(ctx).Info("hello world") // or sompackage.Info(ctx, "hello world")这两个示例 API 的实现可以与上下文交互以检索所需的值,而无需担心任何日志调用站点的 MDC 中的额外信息。

慕妹3242003

在我这边,我发现使用默认的日志包我们可以将前缀设置为log.SetPrefix(traceId),这样做,日志将打印跟踪 ID 作为实际和子函数/结构中的前缀。import (    "log"    "github.com/google/uuid")func (hdl *HTTPHandler) example() {    var traceId string = uuid.NewString()    log.SetPrefix(traceId + " - ")    log.SetFlags(log.LstdFlags)    // ...    // ...    log.Println("......")}

DIEA

这个问题也可以使用依赖注入容器来解决。我们可以实现“请求范围”注入,因此,对于每个请求,我们将重新创建所有使用请求范围依赖项的依赖树(记录器、错误报告器、通过上下文传播将请求发送到另一个服务的客户端)。但据我所知,使用依赖注入容器并不是最佳实践,也不是“惯用”方式。此外,这种方法可能会有一些性能和内存问题,因为我们将为每个请求重新创建对象。
打开App,查看更多内容
随时随地看视频慕课网APP