gin自定义日志

gin的默认日志是只输出到终端,缺点:

1、日志没输出到文件

2、日志不分割

通过自定义日志

用自己写的yanglog库基于zap的高性能日志库,轻松实现(自定义配置也极其轻松):

1、日志默认输出到终端,并写到文件

2、按天轮转,超过单文件大小也轮转

3、旧的日志文件,自动压缩,更旧的文件自动删除

4、状态码400以下的写到info日志文件中,状态码大于等于400的同时写到info和error日志文件中

5、该日志方案除了可以写客户请求时的日志,也可以直接应用到内部函数调用时的日志输出

yanglog 的使用和配置,源码都很简单,请按需使用和修改。

直接上代码
go 复制代码
package main

import (
	"context"
	"fmt"
	"time"

	logger "gitee.com/xiaoshanyangcode/yanglog"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func main() {
	// 配置日志
	ctx, cancel := context.WithCancel(context.Background())
	logconf := logger.LogConf{}
	log := logger.NewLogger(ctx, logconf)
	defer log.Sync()
	defer cancel()

	// 生产gin对象
	r := Default(log)

	// 正常gin的用法
	r.GET("/ce", func(c *gin.Context) {
		// 取值
		req := "123"
		fmt.Println("request:", req)
		// 页面接收
		c.JSON(200, gin.H{"request": req})
	})

	r.Run()
}

// 提供gin的Default函数,把日志改为我们自定义的
func Default(log *zap.SugaredLogger) *gin.Engine {
	engine := gin.New()
	// 使用自己的日志模块和默认的recovery
	engine.Use(LoggerWithConfig(log), gin.Recovery())
	return engine
}

// 自定义日志函数
func LoggerWithConfig(log *zap.SugaredLogger) gin.HandlerFunc {
	return func(c *gin.Context) {
		// Start timer
		start := time.Now()
		path := c.Request.URL.Path
		raw := c.Request.URL.RawQuery

		// Process request
		c.Next()

		param := gin.LogFormatterParams{
			Request: c.Request,
			Keys:    c.Keys,
		}

		// Stop timer
		param.TimeStamp = time.Now()
		param.Latency = param.TimeStamp.Sub(start)

		param.ClientIP = c.ClientIP()
		param.Method = c.Request.Method
		param.StatusCode = c.Writer.Status()
		param.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()

		param.BodySize = c.Writer.Size()
		if raw != "" {
			path = path + "?" + raw
		}

		param.Path = path
		// 根据不同的状态码,设置不同的日志等级
		if param.StatusCode < 400 {
			log.Infow(param.ErrorMessage, "code", param.StatusCode, "client", param.ClientIP, "method", param.Method, "path", param.Path, "size", param.BodySize, "duration", param.Latency)
		} else {
			log.Errorw(param.ErrorMessage, "code", param.StatusCode, "client", param.ClientIP, "method", param.Method, "path", param.Path, "size", param.BodySize, "duration", param.Latency)
		}
	}
}
相关推荐
foxsen_xia3 小时前
Go安装、配置和vsCode配置Go
开发语言·vscode·golang
喵个咪5 小时前
初学者导引:在 Go-Kratos 中用 go-crud 实现 Ent ORM CRUD 操作
后端·go
稚辉君.MCA_P8_Java5 小时前
Gemini永久会员 go数组中最大异或值
数据结构·后端·算法·golang·哈希算法
喵个咪5 小时前
初学者导引:在 Go-Kratos 中用 go-crud 实现 GORM CRUD 操作
后端·go
想搞艺术的程序员6 小时前
Go 语言 interface 详解:从源码到实践
golang·interface
foxsen_xia6 小时前
go(基础01)——协程
开发语言·算法·golang
源代码•宸6 小时前
GoLang并发简单例子(goroutine + channel + WaitGroup)
开发语言·经验分享·后端·学习·golang
稚辉君.MCA_P8_Java6 小时前
Gemini永久会员 Go 返回最长有效子串长度
数据结构·后端·算法·golang
前端之虎陈随易8 小时前
基于Go重写的TypeScript 7可以用了
开发语言·golang·typescript