- 后端
- 可观测性
【免费下载链接】zerolog
Zero Allocation JSON Logger
zerolog 专注于高效的 JSON 结构化日志输出,而 PrettyLog 是官方仓库中提供的一个命令行小工具,用于把 JSON 格式的日志流"翻译"成带颜色、易读的文本输出,解决开发调试时日志难以直接阅读的问题。读完本文,你将掌握 PrettyLog 的编译与直跑两种方式、Linux 与 Windows 下 stderr 管道的正确接入方法、-time-format参数用法,以及它基于zerolog.ConsoleWriter的底层实现原理,可以直接在自己的服务日志场景中落地使用。
工具定位:为什么需要 PrettyLog
zerolog 的设计哲学是"专注高效的结构化日志",其核心输出是 JSON 或 CBOR 二进制格式,一条典型的日志长这样:
{"time":"5:41PM","level":"info","message":"Starting listener","listen":":8080","pid":37556}这种格式适合程序解析与存储,却不适合人眼在终端里直接阅读。为此,仓库在 README.md 中明确指出:控制台上的友好输出由内置的(但相对低效的)zerolog.ConsoleWriter提供。PrettyLog 正是把这一能力封装成独立 CLI 的官方示例,位于仓库的 cmd/prettylog 目录。
它的工作方式很直接:从标准输入(或指定文件)逐行读取 JSON 日志,交给zerolog.ConsoleWriter解析并重排为带 ANSI 颜色的可读文本,再写到标准输出。因此它不依赖任何配置文件,也不需要改动你的业务代码——只要日志还是 JSON 格式,就能被美化。
核心前提:zerolog 默认把日志写到 stderr
使用 PrettyLog 之前,必须理解一个关键事实:zerolog 默认并不把日志写到stdout,而是写到stderr。
这一点在 cmd/prettylog/README.md 中有明确说明。从源码看,全局日志器的初始化也印证了这一点:log.go 中的示例使用zerolog.New(os.Stderr)创建日志器,而 README.md 的 Pretty Logging 一节同样使用log.Output(zerolog.ConsoleWriter{Out: os.Stderr})。
因此,把 PrettyLog 接入业务程序时,必须正确重定向 stderr 流,同时保持 stdout 不被污染(例如 HTTP 服务的响应体仍走 stdout)。
编译与运行:两种启动方式
PrettyLog 的源码只有一个文件 cmd/prettylog/prettylog.go,依赖 zerolog 主模块与go-colorable(用于 Windows 下的颜色兼容,见 console.go),编译非常简单。
方式一:编译为可执行文件
在仓库根目录执行:
go build -o prettylog cmd/prettylog/prettylog.go生成prettylog可执行文件后即可在任意终端使用(见下文管道命令)。
方式二:用go run直接运行
无需编译,直接把源码作为程序运行:
go run cmd/prettylog/prettylog.go注意:两种方式都必须从仓库根目录(或模块内对应相对路径)执行,因为go run需要解析github.com/rs/zerolog模块依赖(见 go.mod)。
使用方式:Linux 与 Windows 的管道接入
官方文档给出了两条平台的完整接入命令,以下逐一说明其含义。
Linux / macOS(bash、zsh)
Linux 使用 bash 的进程替换(process substitution)语法,只把 stderr 重定向给 PrettyLog,stdout 完全不受影响:
# 1. 使用编译好的版本 some_program_with_zerolog 2> >(prettylog) # 2. 直接使用 go run some_program_with_zerolog 2> >(go run cmd/prettylog/prettylog.go)这里2>把 stderr 重定向到>(...)进程替换创建的管道,some_program_with_zerolog可以是任何输出 zerolog JSON 日志的程序。
Windows(PowerShell / CMD)
Windows 不支持进程替换语法,官方给出的方案是先把 stderr 合并到 stdout,再整体管道给 PrettyLog:
# 1. 使用编译好的版本 some_program_with_zerolog 2>&1 | prettylog # 2. 直接使用 go run some_program_with_zerolog 2>&1 | go run cmd/prettylog/prettylog.go2>&1将 stderr 重定向到 stdout,随后|把合并后的流管道给 PrettyLog。注意此方式下 stdout 与 stderr 已合并,无法再区分两者,这是 Windows 平台的取舍。
读取日志文件(无管道时)
除了管道模式,PrettyLog 还支持直接指定日志文件(这是官方 README 未展开、但源码明确支持的能力)。不带管道、同时传入文件名时,它会依次扫描每个文件的每一行并美化输出,见 cmd/prettylog/prettylog.go:
prettylog zerolog_output.jsonl仓库根目录恰好提供了一个真实示例文件 example.jsonl,包含 7 条模拟应用日志(启动监听、数据库访问、HTTP 请求、慢请求警告、数据库断连错误)。用以下命令即可复现官方 pretty.png 展示的效果:
go run cmd/prettylog/prettylog.go example.jsonl该文件中的每条日志对应图片里的一行彩色输出:INF(绿色)、DBG(灰色)、WRN(黄色)、ERR(红色),字段名与值以不同颜色区分,正是 PrettyLog 的典型效果。
无参数运行时的用法提示
既没有管道输入,也没有文件名参数时,PrettyLog 会打印如下用法提示并退出(返回码 1),见 cmd/prettylog/prettylog.go:
Usage: app_with_zerolog | 2> >(prettylog) prettylog zerolog_output.jsonl命令行参数:-time-format
PrettyLog 支持一个命令行参数-time-format,用于控制日志时间戳的显示格式,取值如下(定义见 cmd/prettylog/prettylog.go):
| 取值 | 对应 Go 时间布局 | 输出示例 |
|---|---|---|
default(默认值) | time.Kitchen | 5:41PM |
full | time.RFC1123 | Mon, 13 Oct 2026 13:22:09 +0800 |
使用方式:
some_program_with_zerolog 2> >(prettylog -time-format full)传入其他取值时,程序会直接panic("Invalid time-format provided")(见 cmd/prettylog/prettylog.go),因此请严格使用上述两个取值。
值得注意的是,default对应的time.Kitchen正是zerolog.ConsoleWriter的默认时间格式:在 console.go 中定义了consoleDefaultTimeFormat = time.Kitchen,与 example.jsonl 中"time":"5:41PM"的字段值完全一致——这也解释了为什么示例日志的时间戳恰好是这种格式。
底层原理:PrettyLog 与 ConsoleWriter 的分工
PrettyLog 本体很薄,核心逻辑只有两个函数(见 cmd/prettylog/prettylog.go):
isInputFromPipe():通过os.Stdin.Stat()检查标准输入是否为管道(字符设备标志),决定走管道模式还是文件模式(cmd/prettylog/prettylog.go)。processInput():用bufio.Scanner逐行读取输入,把每一行 JSON 原样交给 writer(cmd/prettylog/prettylog.go)。
真正的美化工作在zerolog.NewConsoleWriter()与ConsoleWriter.Write()中完成:
- 每一行 JSON 被
json.Decoder解析为 map(console.go); - 按照默认部件顺序
time → level → caller → message依次渲染(consoleDefaultPartsOrder(),见 console.go); - 时间戳按
TimeFormat格式化,等级根据FormattedLevels/LevelColors映射着色(console.go),消息加粗,字段名用青色、错误字段用红色加粗(console.go); - 其余字段按字母序排列输出,其中
error字段会被特殊提到最前(console.go)。
另外,如果进程环境中设置了NO_COLOR环境变量,ConsoleWriter会自动禁用颜色输出(console.go),适合在无终端或 CI 场景下使用。
使用注意事项与限制
- stdout 保持干净:Linux 的
2> >(prettylog)写法让 stdout 完全不受影响;Windows 的2>&1 |会合并两路流,需按场景选择。 - 逐行处理:
processInput基于bufio.Scanner逐行扫描,输入必须是"一行一条 JSON"的标准 zerolog 格式(如 example.jsonl),不支持多行 JSON 事件;同时单行长度受bufio.Scanner默认 token 上限影响,超长单行可能被截断报错。 - 文件模式错误处理:文件打不开或扫描出错时,PrettyLog 会打印错误并
os.Exit(1)(cmd/prettylog/prettylog.go),便于在 shell 中感知失败。 - 性能取舍:正如 README.md 所述,
ConsoleWriter属于"提供但相对低效"的展示型输出,PrettyLog 只适合开发调试、日志回放等人工阅读场景,生产环境的日志采集仍应保留原始 JSON 输出。
小结
PrettyLog 是理解 zerolog 生态"结构化输出与人类可读输出分离"设计思路的最佳入口:业务代码无需任何改动,只需一行 shell 管道(Linux 用进程替换重定向 stderr,Windows 用2>&1合并后管道),就能把 JSON 日志流变成带颜色、分级明确的终端文本。配合-time-format参数、文件模式与NO_COLOR环境变量,足以覆盖日常开发调试的大部分需求;想深入了解颜色与布局的定制能力,可继续阅读 console.go 中ConsoleWriter的FormatLevel、FormatTimestamp、FormatFieldName等可配置项,以及 console_test.go 中的示例用例。
- 后端
- 可观测性
【免费下载链接】zerolog
Zero Allocation JSON Logger
相关推荐
EVM Opcodes更新历史:从Istanbul到London硬分叉的操作码演进
EVM Opcodes更新历史:从Istanbul到London硬分叉的操作码演进 EVM(以太坊虚拟机)操作码是以太坊区块链运行的基础,它们的每一次更新都深刻
在 OpenCloud 中使用 slog-zerolog:把标准库 slog 接入 zerolog 的结构化日志管线
在 OpenCloud 中使用 slog zerolog:把标准库 slog 接入 zerolog 的结构化日志管线 slog zerolog 是 samber
后端微服务存储认证鉴权告别日志混乱:Zerolog多输出实战指南:同时写入文件与控制台
告别日志混乱:Zerolog多输出实战指南:同时写入文件与控制台 你是否还在为日志管理烦恼?开发时需要清晰的控制台输出,生产环境又需要详细的文件记录,切换配置总
后端可观测性
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考