go - 访问没有 http.Request 的上下文

标签 go

我在中间件的 context 中设置 X-Request-Id(如下所示),这样我就可以在那里使用它是 *http.Request 结构 - 例如req.Context().Value(middleware.ReqIdKey)。但是,在我的代码库中有些地方我无法访问 *http.Request 结构,因此我无法使用 context 来获取 X-Request-Id。在 Go 中有什么方法还是我试图做一些根本错误的事情?

internal/middleware/requestid.go

这是我在 context 中设置 X-Request-Id 的中间件。目前在我的“服务器”包中称为 http.ListenAndServe(":8080", middleware.RequestId(SomeHandler))

package middleware

import (
    "context"
    "github.com/google/uuid"
    "net/http"
)

type val string
const ReqIdKey val = "X-Request-Id"

func RequestId(handler http.Handler) http.Handler {
    return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
        val := req.Header.Get("X-Request-Id")
        if val == "" {
            val = uuid.New().String()
        }

        ctx1 := context.WithValue(req.Context(), ReqIdKey, val)
        ctx2 := req.WithContext(ctx1)

        handler.ServeHTTP(res, ctx2)
    })
}

internal/logger/logger.go

这是另一个我需要访问 context 或只是 X-Request-Id 值的包。顺便说一句,调用 logger.Config 发生在启动服务器之前。

package logger

import (
    "github.com/sirupsen/logrus"
    "os"
)

var Log *logrus.Entry

func Config() {
    logrus.SetLevel(logrus.InfoLevel)
    logrus.SetOutput(os.Stdout)
    logrus.SetFormatter(&logrus.JSONFormatter{})

    Log = logrus.WithFields(logrus.Fields{
        "request_id": ..., // I need X-Request-Id value to go here so that all logs have it
    })
}

最佳答案

如果您有一个 http.Request,您可以访问其中的 Context 和 Values。如果您没有请求但需要上下文:获取上下文并将其作为显式参数(按照惯例是第一个参数)传递到您的调用树中。

(Go 中没有魔法,任何没有直接或间接传递给函数的东西都不存在。)

关于go - 访问没有 http.Request 的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58011031/

相关文章:

go - 如何提高执行时间

go - ([]Constructor)(nil) 是什么意思

go - 导入本地模块

logging - 从文本文件中删除前 N 个字节

go - 如何重用监听器/连接?戈兰

date - 如何将日期转换为不同的格式?

go - 如何在Go中获取结构体中字段的真正指针?

database - SQLX "missing destination name"在结构标记中使用表名时

go - http.StripPrefix : Serving a file from a custom folder

go - 如何通过 json 为 Golang 解码嵌套数组中的对值