Zap 日志库学习打卡

package main

import (
    "github.com/gin-gonic/gin"
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "gopkg.in/natefinch/lumberjack.v2"
    "net"
    "net/http"
    "net/http/httputil"
    "os"
    "runtime/debug"
    "strings"
    "time"
)

/*
var logger *zap.Logger

func initlogger() {
    logger, _ = zap.NewProduction()
}

func simplehttpget(url string) {
    resp, err := http.Get(url)
    if err != nil {
       logger.Error(
          "err fethcing",
          zap.String("url", url),
          zap.Error(err),
       )
    } else {
       logger.Info("success..")
       zap.String("status code", resp.Status)
       zap.String("url", url)
       resp.Body.Close()
    }
}

func main() {
    initlogger()
    defer logger.Sync() //文件关闭前将缓冲区的数据弄到磁盘上
    simplehttpget("http://www.baidu.com")
    simplehttpget("www.google.com")
}  */



//==========================自定义日志文件============================

var logger *zap.Logger

func getwriter() zapcore.WriteSyncer {
    //写到文件里
    lumberJackLogger := &lumberjack.Logger{
       Filename:   "./test.log",
       MaxSize:    10,
       MaxBackups: 5,
       MaxAge:     30,
       Compress:   false,
    }
    return zapcore.AddSync(lumberJackLogger)
}
func getencoder() zapcore.Encoder {
    return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()) //json编码
}

func initlogger() {
    encode := getencoder()
    writesync := getwriter()
    core := zapcore.NewCore(encode, writesync, zapcore.DebugLevel) //自定义的话,要手动实现这三个
    logger = zap.New(core, zap.AddCaller())                        //addcaller 添加调用者信息
}
func simplehttpget(url string) {
    resp, err := http.Get(url)
    if err != nil {
       logger.Error(
          "err fethcing",
          zap.String("url", url),
          zap.Error(err),
       )
    } else {
       logger.Info("success.. ", zap.String("状态码", resp.Status))
       zap.String("status code", resp.Status)
       zap.String("url", url)
       resp.Body.Close()
    }
}

//func main() {
//  initlogger()
//  defer logger.Sync()
//  simplehttpget("http://www.baidu.com")
//
//}

//使用Lumberjack进行日志切割归档 将getlogwrite重写

//==========================================
//------------------------------------------

// 如何在gin框架中补充log日志库
func main() {
    initlogger()
    r := gin.New()
    r.Use(GinLogger(logger), GinRecovery(logger, true))
    r.GET("/hello", func(c *gin.Context) {
       c.String(http.StatusOK, "hello")
    })
    r.Run()
}

// GinLogger 接收gin框架默认的日志
func GinLogger(logger *zap.Logger) gin.HandlerFunc {
    return func(c *gin.Context) {
       start := time.Now()
       path := c.Request.URL.Path
       query := c.Request.URL.RawQuery
       c.Next()

       cost := time.Since(start)
       logger.Info(path,
          zap.Int("status", c.Writer.Status()),
          zap.String("method", c.Request.Method),
          zap.String("path", path),
          zap.String("query", query),
          zap.String("ip", c.ClientIP()),
          zap.String("user-agent", c.Request.UserAgent()),
          zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()),
          zap.Duration("cost", cost),
       )
    }
}

// GinRecovery recover掉项目可能出现的panic
func GinRecovery(logger *zap.Logger, stack bool) gin.HandlerFunc {
    return func(c *gin.Context) {
       defer func() {
          if err := recover(); err != nil {
             // Check for a broken connection, as it is not really a
             // condition that warrants a panic stack trace.
             var brokenPipe bool
             if ne, ok := err.(*net.OpError); ok {
                if se, ok := ne.Err.(*os.SyscallError); ok {
                   if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
                      brokenPipe = true
                   }
                }
             }

             httpRequest, _ := httputil.DumpRequest(c.Request, false)
             if brokenPipe {
                logger.Error(c.Request.URL.Path,
                   zap.Any("error", err),
                   zap.String("request", string(httpRequest)),
                )
                // If the connection is dead, we can't write a status to it.
                c.Error(err.(error)) // nolint: errcheck
                c.Abort()
                return
             }

             if stack {
                logger.Error("[Recovery from panic]",
                   zap.Any("error", err),
                   zap.String("request", string(httpRequest)),
                   zap.String("stack", string(debug.Stack())),
                )
             } else {
                logger.Error("[Recovery from panic]",
                   zap.Any("error", err),
                   zap.String("request", string(httpRequest)),
                )
             }
             c.AbortWithStatus(http.StatusInternalServerError)
          }
       }()
       c.Next()
    }
}
{"level":"info","ts":1721963747.5143788,"caller":"zap_demo/main.go:68","msg":"success.. ","状态码":"200 OK"}
{"level":"info","ts":1721964618.9526525,"caller":"zap_demo/main.go:74","msg":"success.. ","状态码":"200 OK"}
{"level":"info","ts":1721964710.8081214,"caller":"zap_demo/main.go:74","msg":"success.. ","状态码":"200 OK"}
分割日志{"level":"info","ts":1721976360.6491218,"caller":"zap_demo/main.go:120","msg":"/hello","status":200,"method":"GET","path":"/hello","query":"","ip":"::1","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0","errors":"","cost":0.000724}
{"level":"info","ts":1721976360.7530072,"caller":"zap_demo/main.go:120","msg":"/favicon.ico","status":404,"method":"GET","path":"/favicon.ico","query":"","ip":"::1","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0","errors":"","cost":0}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值