【Go Zap 日志库】#1 |快速上手 + 配置详解

一、Zap 简介

zap 是 Uber 开源的高性能结构化日志库,兼顾结构化日志与 printf 风格日志,速度快,广泛用于 Go 后端项目。 官方仓库:uber-go/zap: Blazing fast, structured, leveled logging in Go.

日志库核心能力(日常开发掌握这 6 点基本够用)

  1. 时间格式化
  2. 输出美化
  3. 预设字段
  4. 使用全局日志
  5. 日志双写(同时输出控制台 + 文件)
  6. 日志分片

安装

复制代码
go get -u go.uber.org/zap

二、快速开始:两种 Logger

Zap 提供两套日志 API:

  1. SugarLogger:支持 printf 风格,使用简单,性能略低
  2. Logger:强类型结构化日志,性能高,写法繁琐

重要:defer logger.Sync(),程序退出时把缓冲区日志刷入文件,防止日志丢失。

示例 1:SugarLogger

Go 复制代码
logger, _ := zap.NewProduction()
defer logger.Sync() // 程序结束同步缓存日志
sugar := logger.Sugar()

// 结构化键值输出
sugar.Infow("failed to fetch URL",
  "url", url,
  "attempt", 3,
  "backoff", time.Second,
)
// printf风格
sugar.Infof("Failed to fetch URL: %s", url)

示例 2:原生 Logger(高性能强类型)

Go 复制代码
logger, _ := zap.NewProduction()
defer logger.Sync()

logger.Info("failed to fetch URL",
  zap.String("url", url),
  zap.Int("attempt", 3),
  zap.Duration("backoff", time.Second),
)

TIP:Zap 上手简单,难点在于自定义适配项目的日志配置。官方示例较少,复杂配置建议阅读源码注释。

三、Zap 配置 Config 结构体

Zap 支持 yaml/json 配置文件反序列化加载配置,但高级配置官方示例不足,需要手动配置。

Go 复制代码
type Config struct {
    // 最小日志级别
   Level AtomicLevel `json:"level" yaml:"level"`
    // 开发模式,影响堆栈跟踪
   Development bool `json:"development" yaml:"development"`
    // 是否关闭调用者追踪(打印日志所在行号)
   DisableCaller bool `json:"disableCaller" yaml:"disableCaller"`
    // 是否关闭堆栈信息
   DisableStacktrace bool `json:"disableStacktrace" yaml:"disableStacktrace"`
    // 采样配置:限制日志输出量,选择性记录日志,降低性能开销
   Sampling *SamplingConfig `json:"sampling" yaml:"sampling"`
    // 编码格式:json / console
   Encoding string `json:"encoding" yaml:"encoding"`
    // 编码细节配置(时间、级别格式化等)
   EncoderConfig zapcore.EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"`
    // 日志输出路径,可多个
   OutputPaths []string `json:"outputPaths" yaml:"outputPaths"`
    // 错误日志单独输出路径
   ErrorOutputPaths []string `json:"errorOutputPaths" yaml:"errorOutputPaths"`
    // 全局预设字段,每条日志默认携带
   InitialFields map[string]interface{} `json:"initialFields" yaml:"initialFields"`
}

EncoderConfig 编码配置(日志输出格式化核心)

控制日志各个字段的 key 名称、格式化方式。

Go 复制代码
type EncoderConfig struct {
   // 各个字段的key名称,为空则不输出该字段
   MessageKey     string `json:"messageKey" yaml:"messageKey"`
   LevelKey       string `json:"levelKey" yaml:"levelKey"`
   TimeKey        string `json:"timeKey" yaml:"timeKey"`
   NameKey        string `json:"nameKey" yaml:"nameKey"`
   CallerKey      string `json:"callerKey" yaml:"callerKey"`
   FunctionKey    string `json:"functionKey" yaml:"functionKey"`
   StacktraceKey  string `json:"stacktraceKey" yaml:"stacktraceKey"`
   SkipLineEnding bool   `json:"skipLineEnding" yaml:"skipLineEnding"`
   LineEnding     string `json:"lineEnding" yaml:"lineEnding"`

   // 各类自定义编码器
   EncodeLevel    LevelEncoder    `json:"levelEncoder" yaml:"levelEncoder"`
   EncodeTime     TimeEncoder     `json:"timeEncoder" yaml:"timeEncoder"`
   EncodeDuration DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
   EncodeCaller   CallerEncoder   `json:"callerEncoder"`
   EncodeName NameEncoder `json:"nameEncoder" yaml:"nameEncoder"`

   // 反射编码器,处理interface{}类型
   NewReflectedEncoder func(io.Writer) ReflectedEncoder `json:"-" yaml:"-"`
   // console模式下字段分隔符
   ConsoleSeparator string `json:"consoleSeparator" yaml:"consoleSeparator"`
}

四、Option 配置项

Option 用于对 Logger 做附加配置,底层是接口:

Go 复制代码
type Option interface {
   apply(*Logger)
}

// 底层实现
type optionFunc func(*Logger)
func (f optionFunc) apply(log *Logger) {
  f(log)
}

// 示例:开启开发模式
func Development() Option {
  return optionFunc(func(log *Logger) {
    log.development = true
  })
}

五、ZapCore 三大核心组件(理解 zap 的关键)

Go 复制代码
type ioCore struct {
   LevelEnabler // 日志级别开关:低于该级别直接丢弃
   enc Encoder  // 编码器:负责日志内容格式化(json/console)
   out WriteSyncer // 日志写入器:输出到控制台/文件,支持Sync刷缓存
}
  • Encoder:日志格式化、编码,定义长什么样
  • WriteSyncer:日志输出目标,控制台、文件等
  • LevelEnabler:日志级别过滤,控制哪些级别日志放行

自定义日志(双写、日志分割)基本都是基于zapcore组合这三个组件实现。

相关推荐
我命由我123454 分钟前
Python 实用操作 - 文件操作(打开与关闭文件、读取文件、文件写入)
java·开发语言·前端·javascript·数据库·python·java-ee
冻柠檬飞冰走茶11 分钟前
PTA刷题集之Battle Over Cities - Hard Version(C语言实现)
c语言·开发语言·数据结构·算法
dora14 分钟前
接口被疯狂调用怎么办?聊聊接口限流
后端·安全
1360967572316 分钟前
评测结果怎么用:从失败样本到提示词规则
后端
不一样的少年_26 分钟前
为什么你写的 Agent 一报错就死循环?很多人都漏掉了这层“错误自救与熔断”机制
前端·后端·agent
ZhengEnCi35 分钟前
Agent 自动化系统怎么搭:从 Super-agent 架构到事件驱动调度(全文可跑)
后端·架构
学长毕设41 分钟前
基于SpringBoot的网上流浪狗救助捐赠平台-附源码
java·spring boot·后端
xiaoqiMikko42 分钟前
Redis 实战(三):持久化出错 —— fork 失败、磁盘写满、AOF 膨胀与损坏,逐个复现(6.2.4)
redis·后端
Дерек的学习记录43 分钟前
Unreal Engine 5:第三人称运动系统和人物动画
开发语言·学习·ue5