Add correlation Id for logs with logrus:Golang

725 views Asked by At

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

There are 1 answers

0
Stéphane Jeandeaux On

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