Skip to content

集成 ​

integration 从平台行为中自动采集日志。它们始终需要主动开启:只有配置了对应的 integration,才会采集相应内容。每条采集到的日志都带有 source: "integration:<name>",便于下游过滤和防止回环。

应该开启哪些采集、如何清洗数据等隐私建议,见 运维。

运行时支持 ​

运行时支持数量说明
浏览器 / 前端@loggerjs/browser 中的一方自动采集器19console、脚本错误、fetch/XHR、WebSocket、Web Vitals、Performance API、路由、用户操作、service worker、浏览器扩展/Electron 渲染进程钩子,以及浏览器 context 传播。
Node.js / 服务端@loggerjs/node 中的一方自动采集器16进程崩溃、diagnostics channel、HTTP 框架、出站客户端、CLI/serverless 生命周期、队列和数据库客户端。
与运行时无关 / core@loggerjs/core 只提供 integration API-core 包定义 integration 契约和防回环辅助工具;具体的平台采集在 browser 和 Node.js 包中。

自定义 integration 应先检测平台能力,不可用时什么也不做。

稳定性分级 ​

integration 的稳定性描述的是公开的 setup/选项契约和拆除行为,并不表示底层平台在每个运行时、浏览器版本、框架版本或部署方式中都会产生每一种信号。

级别含义
Stable受 1.x 兼容承诺保护。选项名、setup/拆除行为以及采集字段的整体结构受保护。
Compatible公开且有测试,但具体字段结构或框架/运行时边界情况的处理仍可能在更早的 minor 中先弃用后再细化。
Runtime-dependent公开 API 稳定,但信号本身取决于平台支持、浏览器策略、框架钩子或部署生命周期。
Integration稳定性原因
captureConsoleIntegration()Stable核心的浏览器采集能力,具备防回环和拆除测试。
captureBrowserErrorsIntegration()Stable标准的浏览器错误和 rejection 采集;CSP 细节因浏览器而异。
captureFetchIntegration() / captureXHRIntegration()Compatible请求/响应采集提供显式的数据清洗钩子,但采集字段仍可能在弃用之后调整。
pageLifecycleIntegration()Runtime-dependentAPI 稳定,但 pagehide/visibility 的触发时机由浏览器决定,只能尽力而为。
captureWebVitalsIntegration()Runtime-dependent依赖 PerformanceObserver 和浏览器对各项指标的支持。
capturePerformanceIntegration()Runtime-dependent能拿到哪些 entry 取决于浏览器、权限策略和页面生命周期。
captureReportingIntegration()Runtime-dependentReportingObserver 及报告类型因浏览器而异。
captureRouterIntegration()Stable通用浏览器路由的 history/hash 采集稳定。
框架路由适配器Compatible公开的适配器有测试,但各框架的钩子形态可能变化。
captureFrameworkErrorsIntegration()Compatible公开的辅助 API 稳定;框架错误钩子的 payload 仍由框架决定。
captureUserActionsIntegration()Compatible隐私优先的默认值稳定;元素元数据的推断规则可能调整。
captureWebSocketIntegration()Compatible构造函数 patch 和事件采集是公开的;采样消息的细节可能变化。
captureServiceWorkerIntegration()Runtime-dependent取决于 service worker 是否可用以及其生命周期消息。
captureRuntimeHostIntegration()Runtime-dependent浏览器扩展和 Electron 的能力与宿主相关,需要按频道显式开启。
browserContextPropagationIntegration()Stable环境 context 绑定契约稳定。
captureProcessIntegration()StableNode 崩溃/警告/退出采集以及有时限的 flush 行为属于生产承诺。
diagnosticsChannelIntegration()Runtime-dependentNode 频道名和 payload 来自 Node 以及已埋点的库。
HTTP 框架 integrationCompatibleExpress/Fastify/Koa/Nest/Hapi 适配器是公开的;框架生命周期细节可能调整。
nodeFetchIntegration() / nodeHttpClientIntegration()Compatible出站 HTTP 采集是公开的;Node/undici/http 的边界细节可能变化。
captureCliIntegration() / serverlessIntegration()Compatible生命周期契约是公开的;平台相关的调用元数据可能细化。
queueIntegration() / bullMqIntegration()Compatible通用队列和 BullMQ 操作采集是公开的;队列 payload 元数据有意设计为可配置。
databaseIntegration() / prismaIntegration() / redisIntegration()Compatible数据客户端的方法包装是公开的;语句/命令的提取规则可能变化。

导入边界 ​

根入口是便捷预设。公开的 integration 子路径都列在这里,方便用户选择更小的 bundle,也防止新的内置 integration 在没有文档的情况下悄悄扩大 API。

运行时公开的 integration 子路径
Browser@loggerjs/browser/integration-console, @loggerjs/browser/integration-context, @loggerjs/browser/integration-errors, @loggerjs/browser/integration-fetch, @loggerjs/browser/integration-xhr, @loggerjs/browser/integration-framework-errors, @loggerjs/browser/integration-framework-routers, @loggerjs/browser/integration-reporting, @loggerjs/browser/integration-router, @loggerjs/browser/integration-runtime-host, @loggerjs/browser/integration-service-worker, @loggerjs/browser/integration-user-actions, @loggerjs/browser/integration-websocket, @loggerjs/browser/integration-web-vitals, @loggerjs/browser/integration-performance, @loggerjs/browser/integration-page-lifecycle
Node.js@loggerjs/node/integration-process, @loggerjs/node/integration-cli, @loggerjs/node/integration-koa, @loggerjs/node/integration-nest, @loggerjs/node/integration-hapi, @loggerjs/node/integration-prisma, @loggerjs/node/integration-redis, @loggerjs/node/integration-queue, @loggerjs/node/integration-bullmq, @loggerjs/node/integration-serverless, @loggerjs/node/integration-database, @loggerjs/node/integration-express, @loggerjs/node/integration-fastify, @loggerjs/node/integration-fetch, @loggerjs/node/integration-http-client, @loggerjs/node/integration-diagnostics

如果某个公开的 integration 子路径被导出却没有列在这里,pnpm verify:component-docs 会失败。新增条目时也应同步更新上方的稳定性表,以及该类 integration 的运行时验证说明。

浏览器 / 前端(@loggerjs/browser) ​

Integration采集内容说明
captureConsoleIntegration()console.debug/info/log/warn/error/trace 调用级别允许列表(levels)、限流(默认每秒 100 条)。拆除时恢复被 patch 的方法;console transport 通过未被 patch 的方法输出,因此不会形成回环。
captureBrowserErrorsIntegration()window.onerror 的脚本/资源错误、unhandledrejection,以及可选的 CSP 违规对短时间内重复出现的相同脚本错误去重。
captureFetchIntegration()失败的(状态码 >= minStatus,默认 400)以及按采样率记录的成功 fetch 调用header 允许列表、URL 清洗函数。采集后错误仍会重新抛给应用。
captureXHRIntegration()XMLHttpRequest 生命周期,包含状态码和耗时与 fetch 相同的清洗选项。
pageLifecycleIntegration()在 pagehide / visibilitychange 时 flush 各 transport合并短时间内的多次 flush;与 HTTP transport 的 Beacon 模式配合使用。
captureWebVitalsIntegration()CLS、FCP、INP、LCP、TTFB通过 PerformanceObserver 输出中间值和最终值。
capturePerformanceIntegration()navigation、resource、longtask、measure、mark 条目去重,并受 maxEntries 限制。
captureUserActionsIntegration()点击、输入、提交按元素节流;默认不采集文本和输入值。
captureRouterIntegration()路由变化(pushState/replaceState/popstate/hashchange)可选的 state 规范化。
captureReportingIntegration()ReportingObserver 报告(CSP、deprecation、intervention、crash)拆除时取出尚未处理的报告。
captureServiceWorkerIntegration()service worker 生命周期、消息、消息错误默认不采集消息数据。
captureWebSocketIntegration()WebSocket 连接/打开/关闭/错误,以及采样的消息包装构造函数;setup 之前创建的 socket 不会被跟踪。
captureFrameworkErrorsIntegration()React/Vue/Solid/Svelte 的错误钩子提供 reactComponentDidCatch()、vueErrorHandler() 等方法;logger 创建前抛出的错误会先缓存(maxPending)。
captureRuntimeHostIntegration()浏览器扩展消息、指定频道上的 Electron IPC默认保守:不监听任何频道。
browserContextPropagationIntegration()session/request/action 以及 trace context为 traceparent、baggage、session id、request id 和最近一次用户操作添加环境 context provider。
nextRouterIntegration() / reactRouterIntegration() / vueRouterIntegration() / nuxtRouterIntegration()框架路由跳转对常见路由 API 的轻量适配;记录前请先清洗 URL。

Node.js / 服务端(@loggerjs/node) ​

Integration采集内容说明
captureProcessIntegration()uncaughtException(fatal)、unhandledRejection、warning、退出启用 exitOnUncaught 后,先记录一条 fatal record,调用 flushSync(),最多等待 flushTimeoutMs 让异步 flush() 完成,然后以退出码 1 退出。 未处理的 rejection 遵循 Node 的 --unhandled-rejections 模式:默认会记录为 fatal,flush 后以退出码 1 退出(exitOnUnhandledRejection)。
diagnosticsChannelIntegration()Node diagnostics_channel 消息(http、undici、自定义频道)默认不采集消息 payload。
expressIntegration(logger)请求完成,包含状态码、路由、耗时、request id返回一个 Express 中间件;可选地为每个请求绑定 withContext。
fastifyIntegration(logger)通过 onRequest/onError/onResponse 钩子采集请求生命周期返回一个 Fastify 插件;状态保存在 WeakMap 中。
nodeFetchIntegration()出站 fetch 调用,包含状态码和耗时采集后错误仍会重新抛出。
nodeHttpClientIntegration()http.request / http.get 调用采集 Node http 客户端的请求生命周期。
captureCliIntegration()CLI 启动、退出码、SIGINT/SIGTERM按 token/password/secret 等模式清洗 argv。
serverlessIntegration(logger, handler)包装 serverless handler:调用、耗时、冷启动、错误支持 promise、callback 和同步 handler。
queueIntegration()队列客户端操作(publish/consume/ack/nack),包含耗时按客户端 patch 你列出的方法。
databaseIntegration()数据库客户端调用(query/execute/...),包含语句和耗时语句取自第一个字符串参数,或 .sql/.text/.query 属性。
koaIntegration() / nestMiddlewareIntegration() / hapiIntegration()框架请求生命周期分别是 Koa、兼容 Express 的 Nest 中间件和 Hapi 请求钩子的轻量适配。Nest 适配器不会接入 Nest 的 exception filter、interceptor、guard,也拿不到原始抛出的 Error。
prismaIntegration()Prisma 原始查询方法只包装 $queryRaw / $executeRaw 系列原始查询方法。不订阅 $on("query"),也不采集 prisma.user.findMany() 这类模型操作。
redisIntegration()Redis 命令方法采集选定的命令方法、耗时、错误和可选的 payload 元数据。
bullMqIntegration()BullMQ Queue 方法调用包装 add、addBulk,以及存在时的旧版 process 方法。不接入 Worker 或 QueueEvents 的 completed、failed、stalled 等生命周期事件。

Context 管理器 ​

它不是 integration,但同样在启动时安装一次:

ts
import { installAsyncLocalStorageContext } from "@loggerjs/node";
installAsyncLocalStorageContext();

安装后,withContext() 设置的值会跨越 await 跟随异步执行流传递。

编写自定义 Integration ​

ts
import type { Integration } from "@loggerjs/core";

export function captureThingIntegration(): Integration {
  return {
    name: "thing",
    setup(api) {
      const original = thing.onEvent;
      const capture = api.guard((payload: unknown) => {
        api.capture({
          level: "info",
          message: "thing event",
          props: { payload },
        });
      });

      thing.onEvent = (payload) => {
        capture(payload);
        return original(payload);
      };

      return () => {
        thing.onEvent = original;
      };
    },
  };
}

setup 上下文(api)提供:

  • capture(input):主要入口,会自动打上 source: "integration:thing"。
  • log/trace/debug/info/warn/error/fatal/event/captureException:当 capture 语义不合适时,可以直接调用这些日志方法。
  • guard(fn):为回调加上重入计数。如果被 patch 的对象本身会被日志管线触发(典型场景是 console 采集 + console transport),递归调用会被丢弃并计入 meta(integration.dropped.reentrant),而不会无限递归。
  • unpatched:原始 console.* / fetch / XMLHttpRequest 实现的注册表,在所有 integration 之间共享,因此多次 patch 可以正确叠加。
  • flush/flushSync/close:供页面隐藏等由生命周期驱动的 integration 使用。

面向 integration 作者的辅助函数在 @loggerjs/core/integration-api 中:createIntegrationSetupContext() 可以在 logger 之外构造 setup context(适合测试),getUnpatchedRegistry() / registerUnpatchedDefaults() 提供共享的平台原始函数注册表,onceTeardown() 让 teardown 只执行一次。Integration 和 IntegrationSetupContext 类型仍从 @loggerjs/core 导入。

注意事项:

  • 始终返回一个拆除函数,恢复你 patch 过的内容。拆除函数会在 logger.close() 时按 setup 的相反顺序各执行一次。
  • setup 对每个 integration 实例 只执行一次;创建两个实例就会 patch 两次。请导出工厂函数并在文档中说明。
  • 优雅降级:先检测平台能力,缺失时什么也不做。
  • 采集原始的结构化数据,让 processor 负责脱敏;不要提前格式化消息。

相关链接 ​

基于 MIT License 发布。