智慧線上客服系統原始碼GOFLY開發日誌- 4. gin框架增加日誌中介軟體

taoshihan發表於2022-02-13

專案裡面的web框架是gin,這個框架給我的感覺就是非常的小巧實用。使用的時候,基礎運用非常的簡單,相信看看文件大家都能執行起來,沒什麼可說的。如果現在需求是增加一個日誌中介軟體,記錄下http請求的一些資料,並且需要按日期來生成每天的日誌檔案,我是這麼做的。

使用的日誌庫是 github.com/sirupsen/logrus

我新建了一個lib包,裡面專門放對第三方庫的一些封裝,比如我這個日誌庫

這個裡面,使用了一下單例模式,不用每次都生成logrus結構實體。但是還需要每次都檢測下每天的日誌檔案是否存在,所以專門加個函式處理,每天生成的日誌檔案,設定好logrus的輸出物件

package lib

import (
    "github.com/sirupsen/logrus"
    "log"
    "os"
    "path"
    "time"
)

var logrusObj *logrus.Logger

func NewLogger(logDir string) *logrus.Logger {
    if logrusObj != nil {
        src, _ := setOutputFile(logDir)
        //設定輸出
        logrusObj.Out = src
        return logrusObj
    }

    //例項化
    logger := logrus.New()
    src, _ := setOutputFile(logDir)
    //設定輸出
    logger.Out = src
    //設定日誌級別
    logger.SetLevel(logrus.DebugLevel)
    //設定日誌格式
    logger.SetFormatter(&logrus.TextFormatter{
        TimestampFormat: "2006-01-02 15:04:05",
    })
    logrusObj = logger
    return logger
}
func setOutputFile(logFilePath string) (*os.File, error) {
    now := time.Now()
    logFileName := now.Format("2006-01-02") + ".log"
    //日誌檔案
    fileName := path.Join(logFilePath, logFileName)
    if _, err := os.Stat(fileName); err != nil {
        if _, err := os.Create(fileName); err != nil {
            log.Println(err.Error())
            return nil, err
        }
    }
    //寫入檔案
    src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
    if err != nil {
        log.Println(err)
        return nil, err
    }
    return src, nil
}

我又建了一個middleware的包專門放中介軟體用
給gin use方法用的中介軟體函式,必須返回函式型別 gin.HandlerFunc

package middleware

import (
    "github.com/gin-gonic/gin"
    "github.com/sirupsen/logrus"
    "time"
)

func NewMidLogger(logger *logrus.Logger) gin.HandlerFunc {
    return func(c *gin.Context) {
        // 開始時間
        startTime := time.Now()
        // 處理請求
        c.Next()
        // 結束時間
        endTime := time.Now()
        // 執行時間
        latencyTime := endTime.Sub(startTime)
        // 請求方式
        reqMethod := c.Request.Method
        // 請求路由
        reqUri := c.Request.RequestURI
        // 狀態碼
        statusCode := c.Writer.Status()
        // 請求IP
        clientIP := c.ClientIP()
        //日誌格式
        logger.Infof("| %3d | %13v | %15s | %s | %s |",
            statusCode,
            latencyTime,
            clientIP,
            reqMethod,
            reqUri,
        )
    }
}

最後就是在use一下上面的中介軟體就可以了

engine := gin.Default()
logger := lib.NewLogger(common.LogDirPath)
engine.Use(middleware.NewMidLogger(logger))

gorm也整合上,非常簡單,呼叫一下db物件的一個方法,把logger傳進去

DB.SetLogger(logger)

後面還遇到了哪些問題和知識點將會繼續進行總結。

演示網站:
gofly.sopans.com

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章