日志记录的成本取决于你收集的字段、序列化、脱敏、输出和传输。代码仓库包含针对这些操作的微基准测试,但事件构造测量并不等同于端到端请求成本,也不代表传输保证。
evlog 与其他方案对比
对比套件会运行使用不同输出路径的库。在 commit 5bd1c127 中,配置如下:
| 库 | 已包含在输出记录中的工作 | 未包含的工作 |
|---|---|---|
| evlog | 使用 silent: true 构造事件 | 控制台序列化、控制台写入、远程排空 |
| Pino | JSON 序列化以及向 /dev/null 的同步写入 | 远程传输和索引 |
| Winston | JSON 格式化以及写入无操作可写流 | 远程传输和索引 |
| Consola | 通过无操作 reporter 处理 | reporter 序列化和传输 |
这些配置有助于检查单独的代码路径,但无法隔离选择某个库而非另一个库所产生的成本。/dev/null 避免了存储文件,但写入仍然包含系统调用。
结果
本页面的早期版本将 silent: true 构造与序列化输出进行排名,仿佛它们执行了等量的工作。这些排名现已撤回。套件中的请求生命周期场景还将一个累计的 evlog 事件与四条 Pino 或 Winston 记录进行比较,因此输出数量和序列化同时存在差异。
使用以下命令为当前检出的版本生成结果。将原始结果与 commit、lockfile、Node.js 版本、硬件和日志记录器配置一同保存。没有这些上下文的结果不能作为生产吞吐量承诺。
什么是“广泛事件生命周期”?
该场景会创建一个日志记录器,添加三组字段,并输出一个最终事件。多记录版本会在每组字段添加后以及完成时分别写入。对于该场景,从四条记录变为一条记录会使事件数量减少 75%。但这并不能证明字节数、CPU 时间或成本普遍减少。
Pino 和 Winston 也可以只输出一个最终对象。进行库对比时,也要测量这种情况。日志成本指南 区分了基于事件和基于字节的计费方式,并允许你使用自己的流量假设。
哪些因素会影响事件构造?
log.set() 会将字段合并到待处理上下文中。emit() 会选择严重性级别,应用采样和配置的脱敏规则,并准备最终事件。启用 JSON 控制台输出后,序列化会在输出期间运行。排空器可能会再次为自身的协议进行序列化。
数据的数量和形状都很重要:嵌套对象、错误堆栈、脱敏模式和插件钩子会执行不同的路径。在没有输出的情况下测量一个小事件,并不能估算带有自定义丰富信息和导出的大型事件的成本。
当 evlog 可能不会获胜时
Pino transport 可以在 worker 中运行,将传输处理与调用线程分离。初始记录序列化仍会在日志记录器中发生。Winston 的格式化器和传输,或 Consola reporter,可能已经实现了你的应用所需的确切输出。与其迁移,不如保留该配置。
这里没有任何受支持的声明表明 evlog 在所有其他工作负载中都能胜出。请使用你的目标位置、负载和传输策略测量吞吐量与应用延迟。测量内容应包括排队工作和最终刷新,而不只是将事件加入队列所需的时间。
一个真实请求的成本
测量你实际部署的完整路径:
- 使用
enabled: false运行具有代表性的处理器,以建立不记录日志时的基线。 - 启用事件构造、你所使用的脱敏规则和丰富器,以及实际的输出配置。
- 测试成功、错误和预期的最大上下文。除了吞吐量,也要记录请求延迟分布。
- 包括批处理、重试、队列限制,以及关闭或后台传输行为。确认记录已到达目标位置。
不要将无关微基准测试中的平均值相加,并将总和标记为测得的请求成本。工作可能会重叠、采用不同分支,或异步发生。网络传输和后端索引需要单独测量。
打包体积
已输出的入口文件大小并不等于导入它的应用打包体积。共享代码块和选定的导出内容都会影响最终大小。服务器核心、evlog/http、框架集成和排空器适配器也分别面向不同用途。
构建你计划导入的入口点,并测量生成的打包结果。若要与另一个库进行对比,请保持打包器、目标环境、压缩、压缩算法、版本和导入的功能保持一致。服务器打包体积无法证明哪个浏览器日志记录器更小。
详细基准测试
| 套件 | 它有助于回答的问题 |
|---|---|
bench/core/ | 上下文大小、合并、输出和错误会如何影响构造? |
bench/comparison/ | 明确配置的替代方案工作负载成本是多少? |
bench/ 下的其他文件 | 相应的丰富器、中间件、采样或管道操作成本是多少? |
在解读结果之前,请阅读每个设置:静默输出、禁用的排空器和复用的测试夹具都可能改变所包含的工作。采样和配置介绍了你应该针对应用进行匹配的控制项。
方法论与可信度
你能相信这些数字吗?
基准测试源代码可供检查。可信的对比还需要等量的工作、有版本记录的输入和可复现的输出。当前的对比设置不满足等效输出这一条件。
发布一次运行结果时,请记录 commit、依赖版本、运行时、CPU、操作系统、预热和测量设置、负载、脱敏规则以及目标位置。重复运行以揭示变化。说明该数字测量的是构造、序列化、排队传输,还是已完成的传输。
自行运行
在已安装依赖的代码检出目录中运行一次套件,不要让它保持在 watch 模式:
cd packages/evlog
pnpm exec vitest bench --run
pnpm exec vitest bench --run bench/comparison/
pnpm exec tsx bench/scripts/size.ts
Vitest 会将基准测试结果写入 bench/results.json。分享测量结果时,请将该输出与运行元数据一同保存。体积脚本只会测量其声明的导入内容,因此在将结果应用到自己的打包文件之前,请先检查这些导入内容。