通用技术 Golang 写测试工具的日志介绍(二)

陈子昂 · 2021年02月15日 · 981 次阅读

lumberjack

日志介绍 (一)
lumberjack 可以选择 v2 版本 ,地址:https://github.com/natefinch/lumberjack/tree/v2.1
这个库的主要作用如下:
1.定义日志文件的大小和超过文件设置的数量开心的文件。
2.按保留天数去删除历史日志文件。
3.现存日志文件进行压缩。

func NewLog(){
   //省略部分
    fileConfig := &lumberjack.Logger{
        Filename:   viper.GetString(`settings.log.path`),    // 日志文件名
        MaxSize:    viper.GetInt(`settings.log.maxsize`),    // 日志文件大小
        MaxAge:     viper.GetInt(`settings.log.maxsave`),     // 最长保存天数
        MaxBackups: viper.GetInt(`settings.log.maxBackups`), // 最多备份几个
        LocalTime:  viper.GetBool(`settings.log.localtime`), // 日志时间戳
        Compress:   viper.GetBool(`settings.log.compress`),  // 是否压缩文件,使用gzip
    }
}

lumberjack.Logger 是一个结构体
地址:https://github.com/natefinch/lumberjack/blob/v2.1/lumberjack.gotype可以看到 Logger struct{......}
上面的 MaxAge 和 MaxBackups 都为 0,则不会删除日志文件,fileConfig 被传入到第一个文章里面的。

func NewLog(){
      var writers []zapcore.WriteSyncer 
     //上面fileConfig设置。
      if viper.GetBool("settings.log.consoleStdout") {
           //追加到zapcore的写入缓存和zapcore同步输出日志到控制台
            writers = append(writers, zapcore.AddSync(os.Stdout))
      }
     if viper.GetBool("settings.log.fileStdout") {
          //同步输出到output文件,fileConfig后面会讲到,因为zap没有包含这部分功能。
            writers = append(writers, zapcore.AddSync(fileConfig))
      }
}

设置日志输出方式

基础四件套 Debug,Info,Warn,Error 和他们的 fmt 版本。

func Debug(args ...interface{}) {
    log.Debug(args...)
}

func Debugf(format string, args ...interface{}) {
    log.Debugf(format, args...)
}

func Info(args ...interface{}) {
    log.Info(args...)
}

func Infof(format string, args ...interface{}) {
    log.Infof(format, args...)
}

func Warn(args ...interface{}) {
    log.Warn(args...)
}

func Warnf(format string, args ...interface{}) {
    log.Warnf(format, args...)
}

func Error(args ...interface{}) {
    log.Error(args...)
}

func Errorf(format string, args ...interface{}) {
    log.Errorf(format, args...)
}

log.Fatal 和 log.Panic 这个不推荐,所以这里不会列出来。如果要上生产和高精度工具,可以对于 Panic 和 Fatal(不可恢复)可以建其他方法去处理,类似以下的方法。

func PanicError(c *gin.Context) {
    defer func(){
        if err := recover();err!=nil{
            //当前的context被终止了,该方法返回true
            if c.IsAborted(){
                 c.Status(http.StatusOK)
           }
       }
    }()
   c.Next()  //核心是这句话
}

gin 下面一段稍微做一些介绍,日志文件基本内容告一个段落。

日志输出文件

对日志文件包装了一层 wrapLogFiles(),提供给 golang 封装 saas 的使用,比如 gin。 gin 这里先不做特别介绍,日志是放在工程的 middleware 里面的,wrapLogFiles 如下:

func WrapLogFiles() gin.HandlerFunc {
    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() //通过上下文写入状态码
        clientIP := c.ClientIP() // 请求IP
        logger.Infof(" %s %3d %13v %15s %s %s",
            startTime.Format("2006-01-02 15:04:05.9999"),
            statusCode,
            latencyTime,
            clientIP,
            reqMethod,
            reqUri,
        )
    }
}

添加到 gin web 框架方式如下:

func NewRouter(r *gin.Engine){
       r  := gin.New()
       g := r.Group("/api/v1", wrapLogFiles(),gin.Recovery())
       {
               g.POST("api名称",HandlerChain)     
               //其他的Http请求方式
      }
}

WrapLogFiles() 里面有上下文的 c.next(),所以 gin.Recovery() 后面的会生效,Group 第二个参数是传入不定长的 HandlerFunc。
也可以用以下的方式,更建议是用 InitMiddleware(),设置和路由 Group 分开。

func NewRouter(r *gin.Engine){
       r  := gin.New()
       g := r.Group("/api/v1")
       g.Use(wrapLogFiles())
       g.Use(gin.Recovery())
       {
               g.POST("api名称",HandlerChain)     
               //其他的Http请求方式
      }
}

gin 部分这个篇幅先不继续写了,就如上面这样被添加进去的。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册