在我的项目开发中,日志模块必不可少。Golang作为新兴的语言,第三方日志包也越来越多,其中star数最多的是logrus。云盘我的项目中应用的日志包就是logrus,上面就介绍一下该日志包的个性和应用办法。目前我的项目中应用的服务端框架是gin,日志就以gin中间件的形式来应用。

一、logrus个性:

  • 齐全兼容golang规范库日志模块:logrus提供了6中日志级别:debug、info、warn、error、fatal和panic,这是golang规范日志模块的超集,须要留神的是:fatal间接调用的os.Exit(),来不及执行defer。
  • 可扩大的hook机制:容许使用者通过hook的形式将日志发送到任意的中央,如:本地文件系统、规范输入、logstash和elasticsearch或者mq等,也能够通过hook自定义日志的内容或格局。
  • 可选的日志输入格局:logrus内置两种日志格局:JSONFormatter和TextFormatter,如果这两种格局不满足需要,能够本人手动实现接口,定义日志的输入格局。
  • Field机制:logrus激励通过Field机制进行精细化和结构化的日志记录,而不是通过简短的音讯来记录日志。

二、根本应用

  • 写入文件:先从配置中获取到日志文件的门路和日志文件名,关上文件,以追加写的模式写入日志

    // 写入文件f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_APPEND, os.ModeAppend)if err != nil {  fmt.Println("err", err)}
  • 创立实例、设置输入和日志输入级别

    // 实例化logger := logrus.New()// 设置输入logger.Out = f// 设置日志级别logger.SetLevel(logrus.DebugLevel)
  • 设置rotatelogs

    // 设置rotatelogs和writeMaplogWriter, _ := rotatelogs.New(  // 宰割后的文件名称  fileName+".%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,  logrus.FatalLevel: logWriter,  logrus.DebugLevel: logWriter,  logrus.WarnLevel:  logWriter,  logrus.ErrorLevel: logWriter,  logrus.PanicLevel: logWriter,}
  • 增加自定义的hook

    lfhook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{  TimestampFormat: "2006-01-02 15:04:05",})// 新增hooklogger.AddHook(lfhook)
  • 设置日志输入的格局

    startTime := time.Now()// 解决申请c.Next()endTime := time.Now()// 执行工夫latencyTime := endTime.Sub(startTime)// 申请形式reqMethod := c.Request.Method// 申请路由reqUrl := c.Request.URL// 状态码statuCode := c.Writer.Status()// 申请IPclientIP := c.ClientIP()// 日志格局logger.Infof("| %3d | %13v | %15s | %s | %s",  statuCode,  latencyTime,  clientIP,  reqMethod,  reqUrl,)
  • 中间件的应用:间接在gin的router配置中应用router.use(中间件名称)即可。
  • 输入的成果:

    {"level":"info","msg":"| 200 |   27.394785ms |       127.0.0.1 | GET | /api/v1/token/folder/?user_id=1","time":"2021-09-04 16:06:09"}{"level":"info","msg":"| 200 |   19.440787ms |       127.0.0.1 | GET | /api/v1/token/trash/?user_id=1","time":"2021-09-04 16:06:09"}{"level":"info","msg":"| 200 |  135.751439ms |       127.0.0.1 | DELETE | /api/v1/token/trash/file?id=2\u0026type=1\u0026file_sha1=3dd360aadc76a400518e4084b9992024cdd10d9f\u0026user_id=1\u0026folder_id=1","time":"2021-09-04 16:06:11"}{"level":"info","msg":"| 200 |   53.791428ms |       127.0.0.1 | DELETE | /api/v1/token/trash/file?id=3\u0026type=0\u0026file_sha1=\u0026user_id=1\u0026folder_id=4","time":"2021-09-04 16:06:13"}

三、残缺代码

package middlewareimport (    "file-store/utils"    "fmt"    "os"    "path"    "time"    "github.com/gin-gonic/gin"    rotatelogs "github.com/lestrrat-go/file-rotatelogs"    "github.com/rifflock/lfshook"    "github.com/sirupsen/logrus")// logrus: 日志到文件func LoggerToFile() gin.HandlerFunc {    logFilePath := utils.GlobalConfig.Log.FilePath    logFileName := utils.GlobalConfig.Log.FileName    // fileName拼接    fileName := path.Join(logFilePath, logFileName)    // 写入文件    f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_APPEND, os.ModeAppend)    if err != nil {        fmt.Println("err", err)    }    // 实例化    logger := logrus.New()    // 设置输入    logger.Out = f    // 设置日志级别    logger.SetLevel(logrus.DebugLevel)    // 设置rotatelogs    logWriter, _ := rotatelogs.New(        // 宰割后的文件名称        fileName+".%Y%m%d.log",        // 生成软链,指向最新的日志文件        rotatelogs.WithLinkName(fileName),        // 设置最长保留工夫        rotatelogs.WithMaxAge(7*24*time.Hour),        // 设置日志切割间隔时间        rotatelogs.WithRotationTime(24*time.Hour),    )    writeMap := lfshook.WriterMap{        logrus.InfoLevel:  logWriter,        logrus.FatalLevel: logWriter,        logrus.DebugLevel: logWriter,        logrus.WarnLevel:  logWriter,        logrus.ErrorLevel: logWriter,        logrus.PanicLevel: 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        // 申请路由        reqUrl := c.Request.URL        // 状态码        statuCode := c.Writer.Status()        // 申请IP        clientIP := c.ClientIP()        // 日志格局        logger.Infof("| %3d | %13v | %15s | %s | %s",            statuCode,            latencyTime,            clientIP,            reqMethod,            reqUrl,        )    }}
文章借鉴自:https://cloud.tencent.com/dev...和 https://www.cnblogs.com/it-33...两篇文章,非原创。