golang gin 日志中间件

1. 初始化日志配置文件

application.yaml

web-log:
  win-path: "./logs"
  linux-path: "./logs"
  file-name: "web.log"

config_yaml.go

type WebLog struct {
	WinPath   string `yaml:"win-path"`
	LinuxPath string `yaml:"linux-path"`
	FileName  string `yaml:"file-name"`
}

你根据自己项目初始化到全局去

initilize/logger.go

package initilize

import (
	"fmt"
	"os"
	"path"
	"runtime"
	"time"

	"daocloud.io/dmp/demo/common/global"
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/rifflock/lfshook"
	"github.com/sirupsen/logrus"
)

/**
 * 读取配置文件,最先被初始化
 */
var ostype = runtime.GOOS

const FileSuffix = ".log"

func init() {
	logFilePath := global.CONFIG.WebLog.LinuxPath
	if ostype == "windows" {
		logFilePath = global.CONFIG.WebLog.WinPath
	} else if ostype == "linux" {
		logFilePath = global.CONFIG.WebLog.LinuxPath
	}

	log := logrus.New()
	log.Out = os.Stdout
	var loglevel logrus.Level
	err := loglevel.UnmarshalText([]byte("info"))
	if err != nil {
		log.Panicf("设置log级别失败:%v", err)
	}

	// 检查目录是否存在
	if _, err := os.Stat(logFilePath); os.IsNotExist(err) {
		// 目录不存在,创建目录
		err := os.Mkdir(logFilePath, 0755) // 设置目录权限
		if err != nil {
			fmt.Println("Failed to create directory:", err)
			return
		}
		fmt.Println("Directory created successfully.")
	} else {
		fmt.Println("Directory already exists.")
	}

	log.SetLevel(loglevel)

	global.Logger = log

	NewSimpleLogger(global.Logger, logFilePath, 8)
}

/*
*

	文件日志
*/
func NewSimpleLogger(log *logrus.Logger, logPath string, save uint) {

	lfHook := lfshook.NewHook(lfshook.WriterMap{
		logrus.DebugLevel: writer(logPath, "debug", save), // 为不同级别设置不同的输出目的
		logrus.InfoLevel:  writer(logPath, "info", save),
		logrus.WarnLevel:  writer(logPath, "warn", save),
		logrus.ErrorLevel: writer(logPath, "error", save),
		logrus.FatalLevel: writer(logPath, "fatal", save),
		logrus.PanicLevel: writer(logPath, "panic", save),
	}, &logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})

	log.AddHook(lfHook)
}

/*
*
文件设置
*/
func writer(logPath string, level string, save uint) *rotatelogs.RotateLogs {
	logFullPath := path.Join(logPath, level)
	var cstSh, _ = time.LoadLocation("Asia/Shanghai") //上海
	fileSuffix := time.Now().In(cstSh).Format("2006-01-02") + FileSuffix

	logier, err := rotatelogs.New(
		logFullPath+"-"+fileSuffix,
		rotatelogs.WithLinkName(logFullPath), // 生成软链,指向最新日志文件
		// rotatelogs.WithRotationCount(save),        // 文件最大保存份数
		rotatelogs.WithRotationTime(time.Hour*24), // 日志切割时间间隔
		rotatelogs.WithMaxAge(7*24*time.Hour),     // 设置最大保存时间(7天)
	)

	if err != nil {
		panic(err)
	}
	return logier
}

2. 配置middleware

response和global记得换成自己的

package middleware

import (
	"bytes"
	"encoding/json"
	"fmt"
	"runtime"
	"time"

	"daocloud.io/dmp/demo/common/global"
	"daocloud.io/dmp/demo/common/response"
	"github.com/gin-gonic/gin"
)

var ostype = runtime.GOOS

type bodyLogWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (w bodyLogWriter) Write(b []byte) (int, error) {
	w.body.Write(b)
	return w.ResponseWriter.Write(b)
}
func (w bodyLogWriter) WriteString(s string) (int, error) {
	w.body.WriteString(s)
	return w.ResponseWriter.WriteString(s)
}

// 日志记录到文件
func LoggerToFile() gin.HandlerFunc {
	return func(c *gin.Context) {
		bodyLogWriter := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
		c.Writer = bodyLogWriter

		//开始时间
		startTime := time.Now()

		//处理请求
		c.Next()

		responseBody := bodyLogWriter.body.String()

		var responseCode int
		var responseMsg string
		var responseData interface{}

		if responseBody != "" {
			response := response.Response{}
			err := json.Unmarshal([]byte(responseBody), &response)
			if err == nil {
				responseCode = response.Code
				responseMsg = response.Msg
				responseData = response.Data
			}
		}

		//结束时间
		endTime := time.Now()

		if c.Request.Method == "POST" {
			c.Request.ParseForm()
		}

		//日志格式
		// accessLogMap := make(map[string]interface{})

		// accessLogMap["request_time"] = startTime
		// accessLogMap["request_method"] = c.Request.Method
		// accessLogMap["request_uri"] = c.Request.RequestURI
		// accessLogMap["request_proto"] = c.Request.Proto
		// accessLogMap["request_ua"] = c.Request.UserAgent()
		// accessLogMap["request_referer"] = c.Request.Referer()
		// accessLogMap["request_post_data"] = c.Request.PostForm.Encode()
		// accessLogMap["request_client_ip"] = c.ClientIP()

		// accessLogMap["response_time"] = endTime
		// accessLogMap["response_code"] = responseCode
		// accessLogMap["response_msg"] = responseMsg
		// accessLogMap["response_data"] = responseData

		// accessLogMap["cost_time"] = endTime.Sub(startTime)
		// // 记录日志
		// global.Logger.WithFields(accessLogMap).Info()

		// 另一种记录格式
		user_id, exists := c.Get("user_id")
		if !exists {
			user_id = 0
		}
		user_name, exists := c.Get("user_name")
		if !exists {
			user_name = ""
		}
		timeFormat := "2006-01-02 15:04:05"
		global.Logger.Info("============================================= start =============================================")
		global.Logger.Info(fmt.Sprintf("操作人ID:%d", user_id.(int)))
		global.Logger.Info(fmt.Sprintf("操作人姓名: %s", user_name.(string)))
		global.Logger.Info(fmt.Sprintf("请求时间:%s", startTime.Local().Format(timeFormat)))
		global.Logger.Info(fmt.Sprintf("请求地址:%s", c.Request.RequestURI))
		global.Logger.Info(fmt.Sprintf("请求方式:%s", c.Request.Method))
		global.Logger.Info(fmt.Sprintf("请求IP:%s", c.ClientIP()))
		global.Logger.Info(fmt.Sprintf("请求数据:%s", c.Request.PostForm.Encode()))
		global.Logger.Info(fmt.Sprintf("响应Code:%d", responseCode))
		global.Logger.Info(fmt.Sprintf("响应msg:%s", responseMsg))
		global.Logger.Info(fmt.Sprintf("响应数据:%s", responseData))
		global.Logger.Info(fmt.Sprintf("请求耗时:%d ms", endTime.Sub(startTime).Milliseconds()))
		global.Logger.Info("============================================= end =============================================")
	}
}

// 日志记录到 MongoDB
func LoggerToMongo() gin.HandlerFunc {
	return func(c *gin.Context) {

	}
}

// 日志记录到 ES
func LoggerToES() gin.HandlerFunc {
	return func(c *gin.Context) {

	}
}

// 日志记录到 MQ
func LoggerToMQ() gin.HandlerFunc {
	return func(c *gin.Context) {

	}
}

测试成功如下截图

golang gin 日志中间件_第1张图片

你可能感兴趣的:(golang,gin,开发语言,中间件)