跳转到主要内容
LogBrew 是面向开发者和编程智能体的可观测性平台,提供充足的免费额度,无需绑卡。 本指南讲解如何配置 Node.js 日志。它用 Winston 和 Pino 记录日志,添加 Express 记录器,并把每条日志连同请求链路发送到 LogBrew。所有示例都在 Node.js 22、Winston 3.19、Pino 10.4、Express 5.3、@logbrew/sdk 0.1.40、@logbrew/node 0.1.24 和 @logbrew/express 0.1.10 上运行过。每个输出块都是真实输出。

选择 Winston 还是 Pino

两个库都输出结构化的 JSON 日志。继续使用应用已经在用的库。两者接入 LogBrew 的方式不同。

准备 LogBrew 项目

1

创建项目密钥

使用 CLI 登录。创建一个项目,把它的接入密钥保存到仅所有者可访问的文件中。
CLI 不会输出密钥。在生产环境中,使用所在平台的密钥管理服务。
2

安装依赖包

这些包需要 Node.js 18.19 或更高版本。安装 Winston 或 Pino,也可以两者都装。
3

配置密钥和部署标识

createLogBrewNodeClient() 从 LOGBREW_SERVER_API_KEY 读取密钥。服务名称是 package.json 中的 name。要使用其他名称,设置 LOGBREW_SERVICE_NAME。示例使用 ES 模块,所以要在 package.json 中设置 "type": "module"。

Node.js 日志级别

每个库都有自己的级别名称和数值。LogBrew 存储 4 个级别,并把原始级别保留在元数据中。 在 Winston 中,数值越小越严重。在 Pino 中,数值越大越严重。生产环境设置 info,只在短时诊断时使用 debug。

Winston 记录器

把这个文件保存为 winston-app.js。第一个格式会在任何 transport 收到记录之前,丢弃低于记录器级别的记录。LogBrew transport 会收到记录器写入的每条记录,所以需要这一步筛选。
运行 node winston-app.js。终端会为每条 info 及以上级别的记录输出 1 行 JSON。这里缩短了堆栈。
LogBrew 收到同样的 3 条记录。字段会成为 context.* 元数据。 这个 transport 会发送错误名称和消息,但不发送堆栈。要发送堆栈,在 createLogBrewWinstonTransport() 中设置 includeErrorStack: true。每条消息也会成为下一个问题的操作记录(Breadcrumbs)。要关闭这一行为,设置 breadcrumbs: false。

Pino 记录器

把这个文件保存为 pino-app.js。在写第一条日志之前,调用一次 installLogBrewPinoInstrumentation()。它会读取每条写完的 Pino 记录。Pino 仍会写入自己的输出目标。
运行 node pino-app.js。这里缩短了主机名和堆栈。
LogBrew 收到 3 条记录。debug 记录在到达 LogBrew 之前就被 Pino 丢弃了。 LogBrew 中没有 token 字段。LogBrew 会丢弃凭据、Cookie、请求体、查询参数、URL 和堆栈字段,并保留你的 Pino redact 路径作为第二道防线。pid、hostname 和 time 是 Pino 的默认字段,所以 LogBrew 不会复制它们。 自动采集需要 9.x 系列中的 Pino 9.11 或更高版本,或者 Pino 10.1 或更高版本。对于更早的 Pino 版本,把 @logbrew/sdk 中的 createLogBrewPinoDestination() 用作 Pino 输出目标。 在开发环境中,要方便地阅读 Pino 输出,把它通过管道传给 pino-pretty。

Express 记录器

logbrewMiddleware() 为每个请求创建 1 个请求 Span(一次计时操作)。logbrewErrorHandler() 把错误报告为问题。请求内的 Pino 日志会带上该请求的 Trace ID 和 Span ID。把这个文件保存为 express-app.js。
启动应用,然后在另一个终端中发送 2 个请求。
LogBrew 收到以下信号。每个请求的日志和 Span 带有相同的 Trace ID。 Span 名称使用路由模板,而不是具体路径。listening on 3000 日志不属于任何请求,所以没有链路。 让中间件自己创建请求客户端。不要把进程级的 client 传给 logbrewMiddleware() 或 logbrewErrorHandler()。中间件会在每次响应后关闭它的请求客户端。

为 Winston 日志添加链路

对于 Winston,把当前活动的链路传给 transport。
把 logbrewTransport 添加到记录器的 transports 列表。这样,Express 请求内的 Winston 日志就会带上该请求的 Trace ID 和 Span ID。

读回日志

最后一条命令读取 1 个请求的全部日志。从链路或问题中复制 <trace_id>。要从 CI 或编程智能体读取,使用项目只读密钥。参见验证接入。

关闭时不丢日志

客户端会在第一个信号产生 1 秒后,或累计到 50 个信号时,发送队列中的信号。事件循环为空时,客户端最多用 2 秒发送剩余的信号。process.exit() 和进程信号会跳过这一步。像 Express 示例中的 SIGTERM 处理函数那样,在退出前调用 await client.shutdown()。

故障排除

要选择日志字段,参见结构化日志。其他框架参见 SDK 接入。