TypeScript 日志库应该让下一个 bug 更容易理解。如果你花在拼凑请求信息上的时间比修复问题还多,evlog 可以将你收集的上下文汇总到一个事件中:谁发起了请求、请求执行了什么,以及最终结果如何。
本指南将帮助你确定 evlog 在项目中的定位。要查看一个可运行的示例,请参阅 Node.js 中的结构化日志。
围绕你向日志提出的问题进行选择
脚本可能只需要报告进度。对于单条结构化消息,可以使用 evlog 的简单日志 API。
当一次结账流程跨越身份验证、库存和支付代码时,有用的答案通常是整个操作过程。宽事件让每个步骤都能向同一个事件添加上下文。这样,你就可以按客户、支付提供商或订单金额筛选失败的结账流程,而不必先合并彼此独立的消息。
如果你当前的日志记录器已经能提供所需的答案,可以继续保留它。当你希望同时获得上下文累积、请求生命周期处理和结构化错误时,evlog 就会发挥作用。上面的功能对比涵盖了与其他日志记录器的差异,包括你可能希望保留的功能。
让 TypeScript 保持上下文一致
随着越来越多的人添加日志记录,一个地方名为 orderId 的字段可能会在另一个地方变成 orderID。evlog 允许你选择使用共享上下文类型,这样编辑器和编译器就能在你工作时发现这些不一致。
例如,下面这个结账日志记录器接受一组已知的结果,以及一个数值类型的支付金额:
import { createLogger, initLogger } from 'evlog'
initLogger({ env: { service: 'checkout' }, pretty: false })
type CheckoutContext = {
orderId: string
payment: { chargeId: string, amount: number }
outcome: 'paid' | 'declined'
}
const log = createLogger<CheckoutContext>()
log.set({ orderId: 'order-123' })
log.set({ payment: { chargeId: 'ch_123', amount: 2999 } })
log.emit({ outcome: 'paid' })
类型检查会在 set() 和 emit() 中捕获以字符串形式传入的金额,或不属于该联合类型的结果。字段可以逐步添加;该类型不会要求在发出事件前提供所有字段,也不会验证传入的数据。类型化字段介绍了类型模式和框架配置。
带上你现有的配置
从一个路由或后台任务开始。在其他地方继续使用现有的日志记录器。在更广泛地采用 evlog 之前,先使用生成的事件调查一个真实问题。
简单日志中的迁移示例将 console.log、Pino、Consola 和 Winston 中常见的调用映射到 evlog。由于 API 存在差异,更新调用时可以参考这些示例。如果你将多条记录合并为一个事件,也要相应更新读取这些记录的查询。
当你的可观测性后端具有受支持的 drain adapter 时,可以继续使用它。日志记录器会在应用程序中收集上下文;适配器会将其发送到你用来搜索和存储事件的服务。
在你的项目中尝试
使用上面的快速开始了解 API,然后选择你的框架集成。对于脚本和后台任务,Standalone TypeScript介绍了初始化和传送。有关打包体积和基准测试条件,请参阅性能。