本文我们通过在 Gin 构建的应用中,使用 Zap 记录请求日志,介绍了 Zap 的使用方式,最后还通过 lumberjack 日志切割库进行切割日志 。?1、介绍我们在之前的文章中介绍过标准库 log 包的使用方式,它虽然使用方便,但是它支持的功能比较简单 。
本文我们介绍 uber 开源的日志库 zap?,首先使用 Gin 框架构建一个 Web 应用,然后通过在该 Web 应用中记录日志,来介绍 zap 的使用方式 。
最后,我们再使用开源的日志切割库 lumberjack,进行日志切割 。
2、使用 Gin 构建一个 Web 应用本文重点不是介绍 gin 框架的使用方式,所以我们仅使用 gin 框架构建一个简单的 Web 应用,代码如下:
func main() { r := gin.Default() r.GET("/ping", ping) r.Run()}func ping(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "pong", })}
阅读上面这段代码,访问 http://127.0.0.1:8080/ping?,返回结果是 {"message":"pong"} 。
然后,我们使用 zap? 记录 ping 函数的请求日志 。
3、Gin 框架使用 zap 日志库Zap 支持两种模式,分别是 SugaredLogger? 和 Logger?,其中 SugaredLogger? 模式比 Logger 模式执行速度更快 。
SugaredLogger 模式
使用 Zap 日志库,首先需要使用 New? 函数创建一个 Logger,代码如下:
func New(core zapcore.Core, options ...Option) *Logger
使用 New? 函数,接收一个 zapcore.Core? 类型的参数和一个 Option? 类型的可选参数,返回一个 *Logger 。
其中 zap.Core? 类型的参数,可以使用 NewCore? 函数创建,接收三个参数,分别是 zapcore.Encoder? 类型,zapcore.WriteSyncer? 类型和 zapcore.LevelEnabler 类型,分别用于指定日志格式、日志路径和日志级别 。
func NewCore(enc Encoder, ws WriteSyncer, enab LevelEnabler) Core
其中 zapcore.Encoder? 类型的参数,可以使用 NewProductionEncoderConfig 函数创建,返回一个用于生产环境的固定日志编码配置 。
// NewProductionEncoderConfig returns an opinionated EncoderConfig for// production environments.func NewProductionEncoderConfig() zapcore.EncoderConfig { return zapcore.EncoderConfig{TimeKey:"ts",LevelKey:"level",NameKey:"logger",CallerKey:"caller",FunctionKey:zapcore.OmitKey,MessageKey:"msg",StacktraceKey:"stacktrace",LineEnding:zapcore.DefaultLineEnding,EncodeLevel:zapcore.LowercaseLevelEncoder,EncodeTime:zapcore.EpochTimeEncoder,EncodeDuration: zapcore.SecondsDurationEncoder,EncodeCaller:zapcore.ShortCallerEncoder, }}
我们可以修改任意配置选项的值 。
其中 zapcore.WriteSyncer? 类型的参数,可以使用 AddSync? 函数创建,该函数接收一个 io.Writer 类型的参数 。
func AddSync(w io.Writer) WriteSyncer
其中 zapcore.LevelEnabler? 类型的参数,可以使用 zapcore? 包定义的常量 zapcore.DebugLevel?,该常量是 zapcore.Level? 类型,并且 zapcore.Level? 类型实现了 zapcore.LevelEnabler 接口 。
完整代码:
var sugaredLogger *zap.SugaredLoggerfunc main() { InitLogger() defer sugaredLogger.Sync() r := gin.Default() r.GET("/ping", ping) r.Run()}func ping(c *gin.Context) { sugaredLogger.Debug("call func ping") c.JSON(http.StatusOK, gin.H{"message": "pong", })}func InitLogger() { core := zapcore.NewCore(enc(), ws(), enab()) logger := zap.New(core) sugaredLogger = logger.Sugar()}func enc() zapcore.Encoder { cfg := zap.NewProductionEncoderConfig() cfg.TimeKey = "time" cfg.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05") return zapcore.NewJSONEncoder(cfg)}func ws() zapcore.WriteSyncer { logFileName := fmt.Sprintf("./%v.log", time.Now().Format("2006-01-02")) logFile, err := os.Create(logFileName) if err != nil {log.Fatal(err) } return zapcore.AddSync(logFile)}func enab() zapcore.LevelEnabler { return zapcore.DebugLevel}
运行程序,执行 curl http://127.0.0.1:8080/ping 。
可以看到,生成的日志文件 xxx.log?,文件中是 json 格式的日志内容,我们可以根据实际需求修改为其他格式 。
开发中,可能我们希望日志可以同时输出到日志文件和终端中,可以使用函数 NewMultiWriteSyncer,代码如下:
func wsV2() zapcore.WriteSyncer { return zapcore.NewMultiWriteSyncer(ws(), zapcore.AddSync(os.Stdout))}
除了使用 zap.New()? 创建 Logger? 之外,Zap 还提供了开箱即用的三种创建 Logger? 的方式,分别是函数 NewProduction,NewDevelopment? 和 Example(),感兴趣的读者朋友们,可以试用一下 。
推荐阅读
- 放弃ElasticSearch,GitHub从零打造搜索引擎!2亿代码仓库怎么搜?
- Java到底能不能使用异常来控制流程?
- 如何使用Buddy自动部署到SFTP服务器
- ap100编程教程视频!ap100破解版怎么注册
- 矮人dos工具箱怎么用-矮人DOS工具箱的作用是什么?
- 苹果手机序列号查询官网激活日期.苹果手机序列号怎么查,到那个网址查?
- 患上了甲肝怎么办? 治疗甲型肝炎
- 黑蚂蚁怎么吃效果好 黑蚂蚁怎么吃
- 怎么取消页码设置,如何消除ppt页码
- 金士顿防伪码在.怎么识别金士顿内存条真伪 从哪里可以看得出来