Zap学习个人总结
本文最后更新于 146 天前,其中的信息可能已经有所发展或是发生改变。如有疑问或错误请反馈至邮箱super.lucky.qu@gmail.com

前言

Zap个人总结由本人跟学教材时的个人理解与做题总结而来,难免具有很多错误,如发现请指正,谢谢!

电脑端可以于左栏“文章目录”来索引到指定小节,手机端可以通过左上角按钮唤出菜单索引到指定小节


草稿

package main

import (
	"encoding/json"

	"go.uber.org/zap"
)

func main() {
	// 对于某些用户来说,NewProduction、NewDevelopment 和 NewExample 提供的预设可能不适用。
	// 对于大多数这类用户,Config 结构体提供了灵活性和便利性的平衡。
	// (对于更复杂的需求,请参阅 AdvancedConfiguration 示例。)
	//
	// 关于 Config 和 zapcore.EncoderConfig 的所有可用选项,请参阅文档。
	rawJSON := []byte(`{
	  "level": "debug",                 // 日志级别
	  "encoding": "json",              // 输出格式:JSON
	  "outputPaths": ["stdout", "/tmp/logs"], // 输出路径:标准输出和指定文件
	  "errorOutputPaths": ["stderr"],         // 错误输出路径
	  "initialFields": {"foo": "bar"},        // 初始字段:键值对
	  "encoderConfig": {
	    "messageKey": "message",             // 消息字段的键名
	    "levelKey": "level",                 // 日志级别字段的键名
	    "levelEncoder": "lowercase"          // 日志级别编码:小写形式
	  }
	}`)

	// 定义一个 zap.Config 对象
	var cfg zap.Config
	// 将 JSON 数据反序列化到 Config 对象
	if err := json.Unmarshal(rawJSON, &cfg); err != nil {
		panic(err) // 如果解析失败,则抛出异常
	}
	// 使用配置构造一个 Logger,出错时直接终止程序
	logger := zap.Must(cfg.Build())
	defer logger.Sync() // 确保日志缓冲区被正确清空

	// 输出一条 Info 级别的日志
	logger.Info("logger construction succeeded")
}

const (
// DebugLevel 通常用于详细信息日志,通常在生产环境中禁用。
DebugLevel = zapcore.DebugLevel
// InfoLevel 是默认的日志优先级。
InfoLevel = zapcore.InfoLevel
// WarnLevel 比 Info 更重要,但不需要单独人工审查。
WarnLevel = zapcore.WarnLevel
// ErrorLevel 表示高优先级日志。如果应用程序运行正常,不应生成任何错误级别的日志。
ErrorLevel = zapcore.ErrorLevel
// DPanicLevel 表示特别重要的错误。在开发环境中,记录此级别的日志后会引发 panic。
DPanicLevel = zapcore.DPanicLevel
// PanicLevel 记录一条日志消息后会引发 panic。
PanicLevel = zapcore.PanicLevel
// FatalLevel 记录一条日志消息后会调用 os.Exit(1) 退出程序。
FatalLevel = zapcore.FatalLevel
)

Zap 是一个高性能的日志库,通常用于 Go 语言中。它提供了快速、结构化、并且能够处理高并发的日志记录功能。以下是如何在 Go 语言项目中使用 Zap 日志的基本步骤:

1. 安装 Zap

首先,你需要安装 Zap。可以通过以下命令在你的 Go 项目中安装它:

go get -u go.uber.org/zap

2. 创建 Zap 日志记录器

在你的 Go 代码中,导入 Zap 包,并创建一个日志记录器。以下是一个基本的示例:

package main

import (

    “go.uber.org/zap”

)

func main() {

    // 创建一个默认的日志记录器,通常是带有开发模式的日志(开发模式输出会包含文件位置、行号等)

    logger, _ := zap.NewDevelopment()

    defer logger.Sync() // 确保日志被正确写入

    // 记录一些日志

    logger.Info(“This is an info message”)

    logger.Warn(“This is a warning message”)

    logger.Error(“This is an error message”, zap.String(“error”, “example error”))

    // 使用更复杂的结构化日志

    logger.Info(“Structured logging”, zap.Int(“user_id”, 123), zap.String(“operation”, “login”))

}

3. 日志级别

Zap 支持多个日志级别,常见的有:

• Debug:调试信息,通常用于开发阶段。

• Info:一般的运行时信息。

• Warn:警告信息,表示可能会导致问题的事件。

• Error:错误信息,表示发生了问题。

• Fatal:致命错误,通常会导致程序终止。

示例:

logger.Debug(“This is a debug message”)

logger.Info(“This is an info message”)

logger.Warn(“This is a warning message”)

logger.Error(“This is an error message”)

4. 配置日志输出格式

你可以根据需要自定义日志的输出格式,Zap 提供了两种主要的日志格式:

JSON 格式:适用于日志聚合工具(如 ELK Stack)。

文本格式:适合人类阅读。

// JSON 格式

logger, _ := zap.NewProduction()  // 生产模式,日志会以 JSON 格式输出

// 文本格式

logger, _ := zap.NewDevelopment()  // 开发模式,日志以文本格式输出

5. 自定义字段

你可以为日志条目添加自定义字段,以便在日志中记录更多的上下文信息:

logger.Info(“User logged in”, zap.String(“username”, “johndoe”), zap.Int(“user_id”, 42))

6. 异常处理

Zap 允许你记录带有附加错误信息的日志,通常使用 zap.Error():

err := someFunction()

if err != nil {

    logger.Error(“An error occurred”, zap.Error(err))

}

7. 使用 Sugared Logger

如果你需要更简洁的日志记录方式,可以使用 Zap 的 SugaredLogger。它提供了类似于 fmt 的 API,但保持了结构化日志的优势。

sugar := logger.Sugar()  // 获取一个 SugaredLogger

sugar.Infow(“User logged in”, “username”, “johndoe”, “user_id”, 42)

sugar.Infof(“Hello, %s”, “world”)

这样,你就可以使用更简洁的方式记录日志了。

8. 配置日志文件输出

如果你需要将日志输出到文件中,可以使用以下代码:

file, _ := os.Create(“app.log”)

logger, _ := zap.NewProduction(zap.Output(zap.AddSync(file)))

这样,日志就会写入到 app.log 文件中。

总结

Zap 是一个强大的日志库,通过它你可以高效地记录结构化日志,支持多种输出格式和日志级别。你可以根据自己的需求选择合适的配置和日志记录方式。




Zap 的 Config 是一个核心配置结构体,包含所有关于日志的关键设置。以下是对 Config 中的所有字段的详细讲解,包括每个字段的作用和可选值:

1. Config 结构体概述

zap.Config 是 Zap 的主要配置结构体,用于初始化日志记录器。

type Config struct {

Level             AtomicLevel

Development       bool

DisableCaller     bool

DisableStacktrace bool

Sampling          *SamplingConfig

Encoding          string

EncoderConfig     zapcore.EncoderConfig

OutputPaths       []string

ErrorOutputPaths  []string

InitialFields     map[string]interface{}

}

2. 字段详解

2.1 Level

类型: AtomicLevel

作用: 设置日志的最低输出级别。仅高于或等于该级别的日志会被输出。

可选值:

• zap.DebugLevel

• zap.InfoLevel

• zap.WarnLevel

• zap.ErrorLevel

• zap.DPanicLevel

• zap.PanicLevel

• zap.FatalLevel

示例:

Level: zap.NewAtomicLevelAt(zap.InfoLevel), // 输出 info 及以上级别的日志

2.2 Development

类型: bool

作用: 指定是否为开发模式。

• 如果为 true:

• 输出更易读的日志。

• 启用 DPanicLevel,在开发模式下记录更严格的错误。

示例:

Development: true, // 开启开发模式

2.3 DisableCaller

类型: bool

作用: 是否禁用记录调用日志的文件名和行号。

• false:记录调用者信息(推荐)。

• true:不记录调用者信息(提升性能)。

示例:

DisableCaller: false, // 启用调用者信息

2.4 DisableStacktrace

类型: bool

作用: 是否禁用记录堆栈跟踪信息。

• false:在 Error 及以上级别记录堆栈信息。

• true:不记录堆栈信息。

示例:

DisableStacktrace: false, // 启用堆栈跟踪

2.5 Sampling

类型: *SamplingConfig

作用: 控制日志采样,防止高频日志影响性能。

配置项:

• Initial: 初始允许输出的日志数量。

• Thereafter: 后续允许的日志输出频率。

示例:

Sampling: &zap.SamplingConfig{

Initial:    100, // 初始 100 条

Thereafter: 10,  // 之后每 10 条输出一次

},

2.6 Encoding

类型: string

作用: 设置日志输出格式。

可选值:

• “json”:JSON 格式,适合机器处理(推荐生产环境)。

• “console”:人类可读的控制台格式。

示例:

Encoding: “json”, // 输出 JSON 格式

2.7 EncoderConfig

类型: zapcore.EncoderConfig

作用: 自定义日志字段和格式。详见 EncoderConfig 配置详解

2.8 OutputPaths

类型: []string

作用: 设置日志的输出路径。

可选值:

• “stdout”:标准输出。

• “stderr”:标准错误。

• 文件路径:如 “./app.log”。

示例:

OutputPaths: []string{“stdout”, “./logs/output.log”},

2.9 ErrorOutputPaths

类型: []string

作用: 设置错误日志的输出路径。

可选值: 同 OutputPaths。

示例:

ErrorOutputPaths: []string{“stderr”, “./logs/error.log”},

2.10 InitialFields

类型: map[string]interface{}

作用: 设置日志中默认包含的字段。

用法: 适合在所有日志中加统一的上下文信息。

示例:

InitialFields: map[string]interface{}{

“app”: “myapp”,

“env”: “production”,

},

3. EncoderConfig 配置详解

EncoderConfig 是 Zap 的子配置,用于定义日志的具体显示样式。

type EncoderConfig struct {

TimeKey        string

LevelKey       string

NameKey        string

CallerKey      string

MessageKey     string

StacktraceKey  string

LineEnding     string

EncodeLevel    LevelEncoder

EncodeTime     TimeEncoder

EncodeDuration DurationEncoder

EncodeCaller   CallerEncoder

EncodeName     NameEncoder

}

3.1 常用字段

字段 类型 作用

TimeKey string 时间字段名,不填则不显示时间

LevelKey string 日志级别字段名,不填则不显示级别

CallerKey string 调用者字段名,不填则不显示调用信息

MessageKey string 日志消息字段名

StacktraceKey string 堆栈信息字段名,不填则不显示堆栈信息

LineEnding string 每条日志的行尾字符

EncodeLevel LevelEncoder 日志级别的格式化器

EncodeTime TimeEncoder 时间戳的格式化器

EncodeDuration DurationEncoder 时间间隔的格式化器

EncodeCaller CallerEncoder 调用者信息的格式化器

3.2 常用格式化器

LevelEncoder:

• CapitalLevelEncoder:INFO

• LowercaseLevelEncoder:info

• CapitalColorLevelEncoder:INFO(带颜色)

• LowercaseColorLevelEncoder:info(带颜色)

TimeEncoder:

• ISO8601TimeEncoder:2023-01-01T15:04:05.000Z07:00

• EpochTimeEncoder:秒级时间戳

• EpochMillisTimeEncoder:毫秒级时间戳

CallerEncoder:

• FullCallerEncoder:显示全路径。

• ShortCallerEncoder:显示短路径(推荐)。

4. 实践案例

下面是一个结合所有配置的完整示例:

package main

import (

“go.uber.org/zap”

“go.uber.org/zap/zapcore”

)

func main() {

config := zap.Config{

Level:       zap.NewAtomicLevelAt(zap.DebugLevel),

Development: false,

Encoding:    “json”,

EncoderConfig: zapcore.EncoderConfig{

TimeKey:        “timestamp”,

LevelKey:       “level”,

CallerKey:      “caller”,

MessageKey:     “message”,

StacktraceKey:  “stacktrace”,

EncodeLevel:    zapcore.CapitalLevelEncoder,

EncodeTime:     zapcore.ISO8601TimeEncoder,

EncodeCaller:   zapcore.ShortCallerEncoder,

},

OutputPaths:      []string{“stdout”, “./logs/app.log”},

ErrorOutputPaths: []string{“stderr”, “./logs/error.log”},

InitialFields: map[string]interface{}{

“service”: “my-service”,

},

}

logger, err := config.Build()

if err != nil {

panic(err)

}

defer logger.Sync()

logger.Info(“Example log”, zap.String(“key”, “value”))

}

通过灵活配置 zap.Config 和 EncoderConfig,可以满足几乎所有日志记录需求!

上一篇
下一篇