Go Gin 項目記錄日誌的最佳實踐

在任何一個複雜的軟件項目中,日誌記錄是必不可少的。無論是調試程序、監控系統狀態,還是統計用戶行爲,日誌都扮演了重要的角色。在 Go 的世界裏,Gin 是一種快速,簡單,靈活,優雅的 Web 框架,同時也提供了豐富的日誌記錄功能。本文將分享在 Gin 項目中如何進行高效的日誌記錄。

創建 Gin 實例與中間件使用

在創建 Gin 實例時,gin.Default()會默認加載 Logger 與 Recovery 中間件。其中,Logger中間件將日誌寫入gin.DefaultWriter接口,默認爲os.Stdout

r := gin.Default()

如果想自定義日誌的輸出位置,像下面這樣指定gin.DefaultWriter即可:

f, _ := os.Create("gin.log")
gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
r := gin.Default()

自定義日誌格式

Logger插件支持自定義日誌格式。例如,如果想在每條日誌中加入請求頭的User-Agent信息,可以像下面這樣編寫一個新的 Logger。

func MyLogger() gin.HandlerFunc {
    return func(c *gin.Context) {
        t := time.Now()

        // 設置example變量
        c.Set("example""12345")

        // 請求前

        c.Next()

        // 請求後
        latency := time.Since(t)
        log.Print(latency)

        // 訪問日誌
        logger.Infof("Incoming request %s %s %s %s %s UA[%s]",
            c.ClientIP(),
            c.Request.Method,
            c.Request.URL,
            latency,
            c.Writer.Status(),
            c.Request.UserAgent(),
        )
    }
}

...
r := gin.New()
r.Use(MyLogger(), gin.Recovery())
...

這樣,我們就能方便地查看每個請求的處理時間和狀態。

中間件日誌記錄

在 Gin 中,可以爲每個路由單獨添加中間件,並在中間件中處理日誌。下面的例子是一個簡單的 "請求 - 響應" 日誌。

func requestResponseLogger() gin.HandlerFunc {
    return func(c *gin.Context) {
        //開始計時
        startTime := time.Now()
        
        //處理請求
        c.Next()
        
        //結束計時
        endTime := time.Now()

        //執行時間
        executeTime := endTime.Sub(startTime).Seconds()

        //獲取請求信息,方法、主機、路徑
        reqMethod := c.Request.Method
        reqHost := c.Request.Host
        reqPath := c.Request.URL.Path

        // 獲取響應狀態碼和用戶IP
        responseStatus := c.Writer.Status()
        clientIP := c.ClientIP()

        // 記錄
        logger.WithFields(logrus.Fields{
            "status_code": responseStatus,
            "execute_time": executeTime,
            "client_ip": clientIP,
            "req_method": reqMethod,
            "req_host": reqHost,
            "req_path": reqPath,
        }).Info("Message")
    }
}

// 使用中間件
r := gin.New()
r.Use(requestResponseLogger())
...

錯誤日誌記錄

對於錯誤日誌,我們可以使用Recovery中間件,它可以捕獲處理請求過程中出現的 panic,並將其記錄下來。

r := gin.Default() // 默認已經使用了Logger和Recovery中間件
...

你也可以自定義一個 Recovery 中間件,將 panic 相關的錯誤信息記錄到特定的文件中:

func MyRecovery() gin.HandlerFunc {
    return func(c *gin.Context) {
        defer func() {
            if err := recover(); err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{
                    "error": fmt.Sprintf("%s", err),
                })
                // 記錄錯誤日誌
                logger.Error(err)
            }
        }()
        c.Next()
    }
}

r := gin.New()
r.Use(MyLogger(), MyRecovery())
...

總結

本文詳細介紹瞭如何在 Go Gin 項目中進行日誌記錄,一些基本的操作如:創建 Gin 實例與中間件、自定義日誌格式、中間件日誌記錄、錯誤日誌記錄等都詳細給出了示例,以幫助讀者理解和使用。同時願 Go Gin 的日誌記錄功能能幫助大家快速開發和維護項目。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/lGwjw2jRd1jrSgdQlB7KQw