Zap日志库指南

简介: zap基本运用,本文将从入门zap、安装zap、使用zap,zap的进阶使用,来讲述zap的使用。

Zap是由Uber开发的高性能Go日志库,特别适合后端服务。

入门:

第一目:为什么要选择Zap?

在Go语言的日志库中,流行的有 zap、logrus...甚至还有Go自带的原生的log。

zap:极致性能(低延迟、低内存占用)、支持多种日志级别、偏底层、Uber官方维护并持续更新

Logrus:灵活易用、支持多种日志级别、高层封装支持全局调用、基本停滞更新

原生log包:简单易用的基础工具、学习成本低。高并发场景下性能也较低(文末有解释)

第二目:安装Zap

go get -u go.uber.org/zap

image.gif

第三目:go语言简答的启动

package main
import (
  "go.uber.org/zap"
  "time"
)
func main() {
  // 创建生产环境使用的Logger(JSON格式)
  logger, _ := zap.NewProduction()
  defer logger.Sync() // 刷新缓冲区
    // Sync的作用,就是强制输出还在缓存区的内容
  // 记录不同级别的日志
  logger.Info("服务启动",
    zap.String("service", "user-api"),
    zap.Time("start_time", time.Now()),
  )
    // 打印
  logger.Warn("数据库连接缓慢",
    zap.Duration("duration", 150*time.Millisecond),
  )
  logger.Error("无法连接Redis",
    zap.String("host", "redis:6379"),
    zap.Error(err), // 假设有err变量
  )
}

image.gif

输出示例

{"level":"info","ts":1690000000.1234567,"msg":"服务启动","service":"user-api","start_time":"2023-07-22T10:00:00Z"}
{"level":"warn","ts":1690000001.2345678,"msg":"数据库连接缓慢","duration":0.15}
{"level":"error","ts":1690000002.3456789,"msg":"无法连接Redis","host":"redis:6379","error":"connection refused"}

image.gif

进阶:

第一目:自定义Logger配置:

func main() {
  // 创建自定义配置
  config := zap.NewProductionConfig()
  
  // 修改配置
  config.Level = zap.NewAtomicLevelAt(zap.DebugLevel) // 设置日志级别
  config.OutputPaths = []string{"stdout", "logs/app.log"} // 输出到控制台和文件
  config.EncoderConfig.TimeKey = "timestamp" // 自定义时间字段名
  config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // ISO时间格式
  
  // 构建Logger
  logger, err := config.Build()
  if err != nil {
    panic(err)
  }
  defer logger.Sync()
  
  // 使用Logger
  logger.Debug("调试信息", zap.String("module", "authentication"))
}

image.gif

第二目:创建开发环境Logger(易读格式)

func main() {
  // 开发环境使用更易读的控制台输出
  logger, _ := zap.NewDevelopment()
  defer logger.Sync()
  
  logger.Info("开发模式日志",
    zap.String("url", "/api/users"),
    zap.Int("status", 200),
  )
}
// 2023-07-22T10:00:00.123Z INFO  开发模式日志  {"url": "/api/users", "status": 200}

image.gif

第三目:使用Sugar Logger(简化语法)

Sugar是zap提供的一种更灵活,更易用的日志记录接口。

格式化字符串与结构字段,语法更接近传统日志库,缺点就是性能略低

func main() {
  logger, _ := zap.NewProduction()
  defer logger.Sync()
  // 创建Sugar Logger
  sugar := logger.Sugar()
  // 简化语法(性能略低于标准Logger)
  sugar.Infow("用户注册成功",
    "user_id", 12345,
    "email", "user@example.com",
    "registration_time", time.Now(),
  )
  // 格式化日志
  sugar.Infof("新请求: %s %s", "GET", "/api/users")
}
{"level":"info","ts":1753187495.5488393,"caller":"zap/main.go:92","msg":"用户注册成功","user_id":12345,"email":"user@example.com","registration_time":1753187495.5488393}

image.gif

第四目:封装Logger(推荐)

对zap,封装成Init与Sync两个函数,需要时,调用即可。

// logger/logger.go
package logger
import (
  "go.uber.org/zap"
)
var Log *zap.Logger
func Init(debug bool) {
  var err error
  if debug {
    Log, err = zap.NewDevelopment()
  } else {
    Log, err = zap.NewProduction()
  }
  
  if err != nil {
    panic(err)
  }
  
  // 添加全局字段(服务名、版本等)
  Log = Log.With(
    zap.String("service", "user-service"),
    zap.String("version", "1.0.0"),
  )
}
func Sync() {
  _ = Log.Sync()
}

image.gif

第五目:在项目中如何调用

// main.go
package main
import (
  "your-project/logger"
  "net/http"
)
func main() {
  // 初始化Logger
  logger.Init(true) // 开发模式
  defer logger.Sync()
  
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    logger.Log.Info("处理请求",
      zap.String("path", r.URL.Path),
      zap.String("method", r.Method),
    )
    
    w.Write([]byte("Hello, World!"))
  })
  
  logger.Log.Info("启动HTTP服务", zap.String("port", "8080"))
  http.ListenAndServe(":8080", nil)
}

image.gif

第六目:日志切割

一、安装Lumberjack:

go get gopkg.in/natefinch/lumberjack.v2

image.gif

二、配置日志切割

import (
  "go.uber.org/zap"
  "go.uber.org/zap/zapcore"
  "gopkg.in/natefinch/lumberjack.v2"
)
func getLogWriter() zapcore.WriteSyncer {
  lumberJackLogger := &lumberjack.Logger{
    Filename:   "logs/app.log", // 日志文件路径
    MaxSize:    100,           // 单个文件最大大小(MB)
    MaxBackups: 5,             // 保留旧文件的最大个数
    MaxAge:     30,            // 保留旧文件的最大天数
    Compress:   true,          // 是否压缩/归档旧文件
  }
  return zapcore.AddSync(lumberJackLogger)
}
func main() {
  encoder := getEncoder()
  writer := getLogWriter()
  core := zapcore.NewCore(encoder, writer, zapcore.DebugLevel)
  
  logger := zap.New(core)
  defer logger.Sync()
  
  // 使用logger...
}
func getEncoder() zapcore.Encoder {
  encoderConfig := zap.NewProductionEncoderConfig()
  encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
  return zapcore.NewJSONEncoder(encoderConfig)
}

image.gif

项目中,常用的就这些。

后续会补充。


日志级别的合理使用:

  • DEBUG:调试信息
  • INFO:重要流程信息
  • WARN:预期之外但可恢复的情况
  • ERROR:需要立即关注的错误
  • DPANIC/ PANIC/FATAL:严重错误(谨慎使用)

注:

  • Zap 使用 无反射设计(通过预定义字段类型避免运行时反射),且 内存预分配 减少 GC 压力。
  • 原生 log 依赖 fmt.Sprintf() 进行字符串拼接,在高并发下性能损耗显著。
目录
相关文章
|
5月前
|
设计模式 Java Go
Go中的switch的8种使用场景:没有你想的那么简单
在 Go 中灵活使用 switch,可以使代码更清晰、更易维护。 switch 是 Go 中不可或缺的控制结构之一
969 0
|
5月前
|
编译器 项目管理 C语言
蓝桥杯Dev-C++ 5.11(编译器)使用细节排坑!!!
为适用各种比赛,教你如何用 DEV C++ 细节( ̄︶ ̄)↗ 
451 1
|
5月前
|
机器学习/深度学习 人工智能 Java
优先队列 priority_queue详解
说到,priority_queue优先队列。必须先要了解啥是堆与运算符重载(我在下方有解释)。否则只知皮毛,极易忘记==寸步难行。但在开头,还是简单的说下怎么应用。
733 1
|
5月前
CLion中文乱码的解决方案
CLion中文乱码的解决方案
341 1
|
5月前
|
缓存 人工智能 Go
go.work
Go语言在1.18版本引入的go.work文件是一种工作区管理工具,用于简化多模块开发。它通过在项目根目录创建go.work文件,使用use指令关联本地模块路径,使开发者能够直接调用不同模块(如主应用myapp和共享库mylib)的函数,无需修改go.mod文件或发布未完成版本。相比replace机制,go.work提供了更便捷的本地开发方案,既能保持生产环境依赖完整性,又解决了多模块协同开发时版本不匹配的问题,尤其适合大型项目和微服务架构。
1246 2
|
5月前
|
机器学习/深度学习 算法 Java
模拟算法(竞赛必备)
模拟算法,简单来说,就是按照题目描述的步骤或规则,一步一步地用代码实现解决问题的过程。就像是你在玩一个游戏,游戏有它自己的规则,而你需要根据这些规则来做出相应的动作以完成特定的目标。
185 0
|
3月前
|
人工智能 搜索推荐 JavaScript
别再手动刷热搜了——我让Hermes每天自动分析热点和产品的结合点,还帮我出好了选题
Hermes Agent是Nous Research开源的自进化AI智能体(MIT协议),支持私有部署、持久记忆与闭环学习。本文介绍如何用它自动抓取微博、抖音等多平台热点,结合你的产品信息每日生成精准选题与大纲——三步配置,省去手动刷榜筛热的低效劳动。
1191 2
|
2月前
|
NoSQL Linux 网络安全
linux安装 redis-5.0.5.tar.gz 详细步骤(源码编译、配置、启动)
本指南详解Redis 5.0.5在Linux下的编译安装全流程:从安装gcc依赖、下载解压源码,到make编译、指定目录安装;配置后台运行、密码认证、远程访问,并提供启动验证、防火墙开放及常见报错解决方案,简洁可靠,适用于生产环境部署。(239字)
|
4月前
|
安全 API
敏感词过滤-文本审核-敏感词审核-违禁词审核-敏感词检测-违禁词检测
本服务提供智能文本审核,精准识别违禁词、色情低俗、恶意推广、辱骂攻击及低质灌水内容,并校验广告法合规性,适用于评论过滤、注册信息筛查、文章发布等场景,保障内容安全与平台合规。
885 1
|
5月前
|
Java Go
io.copy
本文将会从定义、用法、底层源码逐一来讲解。并在文末通过项目见闻,来加深大家的io.Copy的理解与思考。
406 1