go-gin使用logrus实现记录错误日志并加入数据库

282 阅读1分钟

第一步 安装logrus

go get github.com/sirupsen/logrus

第二步编写logger.go 中间件

package middleware

import (
	"fmt"
	"os"
	"time"

	"webgin/model"
	"webgin/utils"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
)

var logger *logrus.Logger

func InitLogger() gin.HandlerFunc {
	// 创建一个新的 logrus 实例
	logger = logrus.New()
	if _, err := os.Stat(utils.LogPath); os.IsNotExist(err) {
		err := os.Mkdir(utils.LogPath, os.ModePerm)
		if err != nil {
			fmt.Println("创建日志目录失败:", err)
		}
	}

	logTime := utils.LogPath + time.Now().Format("2006_01_02") + utils.LogName
	file, err := os.OpenFile(logTime, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err == nil {
		logger.SetOutput(file)
	}
	// 设置 logrus 日志级别
	logger.SetLevel(logrus.InfoLevel)

	// 设置 logrus 日志格式
	logger.SetFormatter(&logrus.TextFormatter{})

	return func(c *gin.Context) {
		startTime := time.Now()
		// 设置 logrus 输出到文件
		c.Next()
		// 结束时间
		endTime := time.Now()
		latencyTime := endTime.Sub(startTime)
		msg, _ := c.Get("err")
		if msg != nil {
			logger.WithFields(logrus.Fields{
				"error_message":  msg.(string),
				"status_code":    c.Writer.Status(),
				"request_uri":    c.Request.RequestURI,
				"client_ip":      c.ClientIP(),
				"request_method": c.Request.Method,
				"execTime":       latencyTime,
			}).Error()
			saveLogToDatabase(c.Writer.Status(), msg.(string), c.ClientIP(), c.Request.RequestURI, c.Request.Method, latencyTime)
		}
	}
}

func saveLogToDatabase(code int, err string, ip string, uri string, method string, latencyTime time.Duration) {
	// 这里可以调用数据库存储接口

	errMsgStruct := model.Logger{
		StatusCode:    fmt.Sprintf("%d", code),
		IP:            ip,
		Method:        method,
		Path:          uri,
		ErrorContent:  err,
		ExecutionTime: fmt.Sprintf("%.4fms", latencyTime.Seconds()*1000), // 将时间转换为毫秒并格式化为字符串,                    // 使用自定义时间类型
	}
	errMsgStruct.RecordLog()

}


/*

日志文件数据库模型
package model

import f "webgin/utils/formatdate"

type Logger struct {
	ID            uint          `json:"id" gorm:"primary_key,autoIncrement"`
	StatusCode    string        `json:"statusCode" gorm:"type:varchar(5)"`     // 状态码
	IP            string        `json:"ip" gorm:"type:varchar(20)"`            // 请求用户的ip
	Method        string        `json:"method" gorm:"type:varchar(10)"`        // 请求类型
	Path          string        `json:"path" gorm:"type:varchar(50)"`          // 请求的路径
	ErrorContent  string        `json:"errorContent" gorm:"type:varchar(255)"` // 错误信息
	ExecutionTime string        `json:"executionTime" gorm:"type:varchar(10)"`
	CreatedAt     *f.CustomTime `json:"created_at"`
}

func (l *Logger) RecordLog() {
	// 开始数据库事务
	tx := db.Begin()
	if err := tx.Create(l).Error; err != nil {
		tx.Rollback()
	}
	// 提交事务
	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
	}
}

*/


第三步 注册中间件及使用

注册中间件: r.Use(middleware.InitLogger())

使用:我只记录数据库出错 其他的验证啥的错误没记录

// 添加用户
func AddAdminUser(c *gin.Context) {
	var AdminUser model.CreateAdminUserRequest
	if err := c.ShouldBind(&AdminUser); err != nil {
		errStr := validator.TranslateValidationError(err)
		msgjson.ErrorMsg(c, errStr)
		return
	}

	// 查询用户
	if err := model.GetAdminUser(AdminUser.Username); err != "" {
		msgjson.ErrorMsg(c, err)
		return
	}

	userInfo := HandleAdminUser(&AdminUser)
	// 添加用户
	if err := model.CreateAdminUser(&userInfo); err != nil {
                 // 记录错误日志
		c.Set("err", "添加后台用户失败错误信息:"+err.Error())
		msgjson.ServerErrorMsg(c)
		// msgjson.ErrorMsg(c, err.Error())
		return
	}

	msgjson.SuccessMsg(c, "用户创建成功", nil)
}

image.png

image.png