为logrus添加关联ID:Golang

huangapple go评论80阅读模式
英文:

Add correlation Id for logs with logrus:Golang

问题

我正在尝试找到一种方法,在我们的项目中为日志添加相关性/请求ID,以便在出现问题时更容易导航和调试。我找到了这篇文章。从那里的示例中,有一个中间件来添加correlationID,然后在某个处理程序函数中检索它。

中间件函数:

const ContextKeyRequestID ContextKey = "requestID"

func reqIDMiddleware1(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    	ctx := r.Context()
		
		id := uuid.New()

		ctx = context.WithValue(ctx, ContextKeyRequestID, id.String())

		r = r.WithContext(ctx)
		
		log.Debugf("Incoming request %s %s %s %s", r.Method, r.RequestURI, r.RemoteAddr, id.String())

		next.ServeHTTP(w, r)
		
		log.Debugf("Finished handling http req. %s", id.String())
	})
}

处理程序:

const LogFieldKeyRequestID = "requestID"

func handleSomeRequest() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {

		ctx := r.Context()

		reqIDRaw := ctx.Value(ContextKeyRequestID) // reqIDRaw at this point is of type 'interface{}'
		
		reqID, ok := reqIDRaw.(string)
		if !ok {
			// handler error
		}
		
		// if reached here, reqID is ready to be used
		
		// let's use it with logrus FieldLogger!
		logger := log.WithField(LogFieldKeyRequestID, reqID)
		
		// Do something, then log what you did
		logger.Debugf("What I just did!")
		
		// Do more, log more. Handle this request seriously
	}
}

但我想知道是否有一种方法可以在不必重构所有现有处理程序和更改日志功能的情况下实现这一点,通过一些自动配置为每个日志添加ID的方式。在我这种情况下,我们的项目非常庞大,按照上述方式进行更改将需要很多改动。

英文:

I'm trying to find a way to add a correlation/request id for logs in our project to make it easier to navigate through them and debug when some issues occur. I found this article. From the example there, there is a middleware to add the correlationID and then retrieve it in some handler function.

Middleware function:

const ContextKeyRequestID ContextKey = "requestID"

func reqIDMiddleware1(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    	ctx := r.Context()
		
		id := uuid.New()

		ctx = context.WithValue(ctx, ContextKeyRequestID, id.String())

		r = r.WithContext(ctx)
		
		log.Debugf("Incoming request %s %s %s %s", r.Method, r.RequestURI, r.RemoteAddr, id.String())

		next.ServeHTTP(w, r)
		
		log.Debugf("Finished handling http req. %s", id.String())
	})
}

Handler:

const LogFieldKeyRequestID = "requestID"

func handleSomeRequest() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {

		ctx := r.Context()

		reqIDRaw := ctx.Value(ContextKeyRequestID) // reqIDRaw at this point is of type 'interface{}'
		
		reqID, ok := reqIDRaw.(string)
		if !ok {
			// handler error
		}
		
		// if reached here, reqID is ready to be used
		
		// let's use it with logrus FieldLogger!
		logger := log.WithField(LogFieldKeyRequestID, reqID)
		
		// Do something, then log what you did
		logger.Debugf("What I just did!")
		
		// Do more, log more. Handle this request seriously
	}
}

But I was wondering if there is a way to achieve this without having to refactor all the existing handlers and changing the logging functionality, through some automatic configuration that would add id for each log, in my case our project is quite big, and doing it in the way described above would require a lot of changes.

答案1

得分: 2

你是否已经查看了WithContextHooks?你仍然需要修改你的代码,但可以将一些行为集中起来。

https://go.dev/play/p/4YxJMK6Zl5D

英文:

Have you looked at WithContext and Hooks?

You still have to modify your code but you can centralize some behaviours.

https://go.dev/play/p/4YxJMK6Zl5D

huangapple
  • 本文由 发表于 2023年1月5日 01:58:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75009452.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定