轨道 · 写下来的字

logrus

2020.04.08

logrus 特性

  • 完全兼容golang标准库日志模块:logrus拥有六种日志级别:debug、info、warn、error、fatal和panic,这是golang标准库日志模块的API的超集.如果您的项目使用标准库日志模块,完全可以以最低的代价迁移到logrus上.
    • logrus.Debug(“Useful debugging information.”)
    • logrus.Info(“Something noteworthy happened!”)
    • logrus.Warn(“You should probably take a look at this.”)
    • logrus.Error(“Something failed but I’m not quitting.”)
    • logrus.Fatal(“Bye.”) //log之后会调用os.Exit(1)
    • logrus.Panic(“I’m bailing.”) //log之后会panic()
  • 可扩展的Hook机制:允许使用者通过hook的方式将日志分发到任意地方,如本地文件系统、标准输出、logstash、elasticsearch或者mq等,或者通过hook定义日志内容和格式等.
  • 可选的日志输出格式:logrus内置了两种日志格式,JSONFormatter和TextFormatter,如果这两个格式不满足需求,可以自己动手实现接口Formatter,来定义自己的日志格式.
  • Field机制:logrus鼓励通过Field机制进行精细化的、结构化的日志记录,而不是通过冗长的消息来记录日志.
  • logrus是一个可插拔的、结构化的日志框架.
  • Entry: logrus.WithFields会自动返回一个 *Entry,Entry里面的有些变量会被自动加上
    • time:entry被创建时的时间戳
    • msg:在调用.Info()等方法时被添加
    • level

gin logrus middleware

package middleware

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

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

// LoggerToFile 日志记录到文件
func LoggerToFile() gin.HandlerFunc {

	logFilePath := "log"
	logFileName := "gin.log"

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

	if _, err := os.Stat(fileName); os.IsNotExist(err) {
		// log path does not exist
		os.Create(fileName)
	}
	//写入文件
	src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
	if err != nil {
		fmt.Println("err", err)
	}

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

	//设置输出
	logger.Out = src

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

	//设置日志格式
	logger.SetFormatter(&logrus.TextFormatter{
		// TimestampFormat: "2006/01/02 15:04:05",
	})

	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()

		// reference
		referer := c.Request.Referer()

		clientUserAgent := c.Request.UserAgent()

		errors := c.Errors

		entry := logger.WithFields(logrus.Fields{
			"statusCode": statusCode,
			"latency":    latencyTime, // time to process
			"clientIP":   clientIP,
			"method":     reqMethod,
			"path":       reqURI,
			"referer":    referer,
			"userAgent":  clientUserAgent,
			"errors":     errors,
		})

		msg := fmt.Sprintf("| %3d | %13v | %15s | %s | %s | %s | %s |", statusCode, latencyTime, clientIP, reqMethod, reqURI, referer, clientUserAgent)
		if statusCode > 499 {
			entry.Error(msg)
		} else if statusCode > 399 {
			entry.Warn(msg)
		} else {
			entry.Info(msg)
		}

		// 日志格式
		// logger.Infof("| %3d | %13v | %15s | %s | %s |",
		// 	statusCode,
		// 	latencyTime,
		// 	clientIP,
		// 	reqMethod,
		// 	reqURI,
		// )
	}
}

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

	}
}

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

	}
}

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

	}
}
← 回到文章