Logrus

简介

  • 最常用的第三方日志框架
  • 方便运用在gin当中

示例

  • 每一次request结束后,记录必要信息
  • 输出到日志文件和stdout
  • 利用rotatelogs+lfshook实现日志切分
func Logger() gin.HandlerFunc {
	logFilePath := "logs/"
	logFileName := "gin.log"

	//日志文件
	fileName := path.Join(logFilePath, logFileName)

	// 实例化
	logger := logrus.New()

	// 设置输出
	//logger.Out = src

	// 设置日志级别
	logger.SetLevel(logrus.InfoLevel)

	// 设置 rotatelogs
	logWriter, _ := rotatelogs.New(
		// 分割后的文件名称
		logFilePath+"%Y%m%d.log",

		// 生成软链,指向最新日志文件
		rotatelogs.WithLinkName(fileName),

		// 设置最大保存时间(7天)
		//rotatelogs.WithMaxAge(7*24*time.Hour),

		// 设置日志切割时间间隔(1天)
		rotatelogs.WithRotationTime(24*time.Hour),
	)

	writeMap := lfshook.WriterMap{
		logrus.InfoLevel: logWriter,
	}

	lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})

	// 新增 Hook
	logger.AddHook(lfHook)

	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.SetFormatter(&logrus.JSONFormatter{
			TimestampFormat: "2006-01-02 15:04:05",
		})
		logger.WithFields(logrus.Fields{
			"status_code":  statusCode,
			"latency_time": latencyTime.String(),
			"client_ip":    clientIP,
			"req_method":   reqMethod,
			"req_uri":      reqUri,
		}).Info()
	}
}

//output
{"client_ip":"::1","latency_time":"94.340688ms","level":"info","msg":"","req_method":"POST","req_uri":"/upload/precreate","status_code":200,"time":"2022-07-05 13:34:18"}

参考文档