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) {
}
}
测试成功如下截图