jtonyoak
jtonyoak

Reputation: 51

Go - Wrap logger in order to add a specific information in each message of a request

I'm working on a project of an http api and there is a thing I want to implement but I have not find the way to do it. So, in my case I send in a request a transaction id, and the thin I want to do is to get this transaction id and use it in the logger, add this information in each log entry of the current request. I want to do this to have a better filtering of my logs when I want to retrieve information if some issue happens.

For example my transaction id is foo : api | [GIN] 2016/08/19 - 13:00:37 | 201 | 30.791855ms | 192.168.99.1:63922 | POST /v1/my/endpoint api | time="2016-08-19T13:00:39Z" level=info msg="Authenticated API user: tests" transactionId="foo" api | time="2016-08-19T13:00:39Z" level=debug msg="SQL query" args=25 query=" SELECT id, created, information1, information2 FROM mydb.mytable WHERE id = ?; " transactionId="foo" This is the kind of information I want to have in my logs.

So instead injecting the transaction id in each log call, I was wondering if there is a way to use the logger as a singleton and add the information each time the logger is called.

I hope I provided enough details in this issue.

thanks.

Upvotes: 5

Views: 1764

Answers (2)

Plato
Plato

Reputation: 11062

here's a logrus solution copied from my answer here, put this at the top of your middleware chain, and update the fields to grab the request's txid.

func Logrus(logger *logrus.Logger) gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now().UTC()
        path := c.Request.URL.Path
        c.Next()
        end := time.Now().UTC()
        latency := end.Sub(start)
        logger.WithFields(logrus.Fields{
            "status":     c.Writer.Status(),
            "method":     c.Request.Method,
            "path":       path,
            "ip":         c.ClientIP(),
            "duration":   latency,
            "user_agent": c.Request.UserAgent(),
        }).Info()
    }
}
GinEngine.Use(Logger(logrus.StandardLogger()))

Upvotes: 0

Mayank Patel
Mayank Patel

Reputation: 8546

Prefix your transaction id in logger. Standard go logger provide many ways to do it. An example is log.New() method.

func GetLogger(transactionID string) *log.Logger {
    return log.New(os.Stdout, fmt.Sprintf("[transactionId = %s ] ", transactionID),
         log.Lshortfile)
}

GetLogger will give you a logger that will prefix your transactionID in every log.

Upvotes: 2

Related Questions