跳转到内容

输入关键词开始搜索文档。

Sentry

最后更新 查看 Markdown 源文件

快速开始

使用 Sentry 蓝图为现有 Flue 项目添加 Sentry 可观测性。在终端或你选择的编码智能体中运行以下命令:

flue add tooling sentry

概述

Sentry 蓝图会在源代码根目录创建 sentry.ts,并从 app.ts 中导入一次。它传递三个信号,每个对话共享一个跟踪:终端失败作为问题,每个 log.* 调用作为 Sentry 日志,并且当 SENTRY_TRACES_SAMPLE_RATE > 0 时,Flue 的 invoke_agent → chat / execute_tool 跨度层次结构包含令牌使用量,遵循 OpenTelemetry GenAI 语义约定。在 Node.js 上,生成的集成核心如下所示:

src/sentry.ts (简化版)
import { createOpenTelemetryInstrumentation } from '@flue/opentelemetry';
import { instrument } from '@flue/runtime';
import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  enabled: Boolean(process.env.SENTRY_DSN),
  tracesSampleRate, // 从 SENTRY_TRACES_SAMPLE_RATE 钳制,默认 0
  traceLifecycle: 'stream', // 交付比其父代存活更久的 gen_ai 子代
  streamGenAiSpans: true,
  enableLogs: true,
  integrations: (defaults) => defaults.filter((i) => !SENTRY_AI_PROVIDER_INTEGRATIONS.has(i.name)),
});

// Sentry 拥有全局 OTel 跟踪器提供者,因此 Flue 的跨度直接落入
// Sentry;内容策略将模型/工具内容排除在跟踪之外,除非记录标志选择加入。
if (tracesSampleRate > 0) {
  instrument(createOpenTelemetryInstrumentation({ content: contentPolicy() }));
}

instrument({
  key: Symbol.for('flue.sentry.bridge'), // 开发重新加载替换,从不堆叠
  observe(event) {
    if (event.type === 'operation' && event.isError) {
      // 问题从实时 `errorInfo` 构建,它携带抛出位置堆栈;
      // 跳过失败提交的结算,因此每个失败恰好引发一个问题。
      captureTerminalFailure(event.errorInfo ?? event.error, correlationTags(event));
      if (event.submissionId) capturedFailedSubmissions.add(event.submissionId);
      return;
    }
    if (event.type === 'submission_settled') {
      /* 仅捕获未捕获的失败 */
    }
    if (event.type === 'log') {
      Sentry.logger[event.level](event.message, logAttributes(event));
    }
  },
  interceptor: (_operation, _ctx, next) => next(),
  async dispose() {
    await Sentry.flush(2000);
  },
});

在 Cloudflare 上,生成的 sentry.ts 包含相同的桥接和检测,但不调用 Sentry.init()。相反,蓝图向每个智能体添加模块本地的 cloudflare 扩展。该扩展使用 instrumentDurableObjectWithSentry(...) 包装最终生成的 Durable Object 类,该函数在每个隔离区初始化 SDK(包括跟踪和日志),同时保持外部 Worker 未检测。

配置

变量用途
SENTRY_DSN事件交付必需 — 标识 Sentry 项目并允许事件提交。
SENTRY_ENVIRONMENT可选 — 在 Sentry 中标识部署环境。
SENTRY_RELEASE可选 — 将事件与已部署的发布关联。
SENTRY_TRACES_SAMPLE_RATE可选 — 0 到 1。0(默认)仅发送错误和日志;高于 0 还发送 AI 跟踪。
SENTRY_AI_RECORD_INPUTS可选 — true 在跟踪跨度中包含提示、指令和工具定义/参数。
SENTRY_AI_RECORD_OUTPUTS可选 — true 在跨度中包含模型输出、工具结果和异常消息/堆栈。

交付事件只需要 SENTRY_DSN。Sentry DSN 允许事件提交,但不授予对项目数据的读取访问权限。将其保留在部署配置中而不是应用源代码中,使轮换和滥用缓解更容易;根据你项目的策略使用密钥或环境绑定。

蓝图会安装 @sentry/node 或 @sentry/cloudflare 加上 @flue/opentelemetry,在适当的运行时边界初始化 SDK,并通过 instrument(...) 注册事件桥接和跨度检测。模型和工具内容保留在跟踪之外,除非记录标志选择加入。

有关 Sentry 与 OpenTelemetry 和 Braintrust 的比较,请参阅可观测性。

集成按目标使用不同的 SDK:

  • Node.js — @sentry/node,在应用源代码中使用模块范围的 Sentry.init(...) 初始化。
  • Cloudflare — @sentry/cloudflare,使用 instrumentDurableObjectWithSentry(...) 围绕每个生成的智能体 Durable Object 初始化。

不要在 Cloudflare 上使用 @sentry/node。

选择报告内容

生成的集成报告:

  • 问题 — 带有 isError: true 的 operation 事件(失败的提示、技能、任务、shell 或压缩操作)和带有 outcome: 'failed' 的 submission_settled 事件,这些事件未从其操作中捕获,因此一个失败引发一个问题;
  • 日志 — 每个 log.info、log.warn 和 log.error 调用在 Sentry 日志中以其自身级别显示,带有清理后的属性和跟踪关联。错误日志是日志,不是问题:报告可恢复错误并继续的智能体永远不会引发问题;
  • 跟踪 — Flue 的 OpenTelemetry 检测发出的跨度层次结构,由 SENTRY_TRACES_SAMPLE_RATE 采样。Sentry 自己的 AI 提供商集成被抑制,因此模型调用不会被重复计算。

捕获包括 flue.* 关联标签 — 智能体实例、智能体名称、对话、会话、操作和提交 — 与跟踪跨度上的属性匹配。有关 Flue 的身份和观察器模型,请参阅可观测性。

当记录标志关闭时,跨度携带时序、令牌使用量、模型标识符和关联 ID,但没有消息或工具内容。启用记录标志会将该方向的内容通过带有 16 KiB 每属性预算的清理转换路由。在扩大该策略之前,请做出明确的数据处理决策。

目标行为

在 Node.js 上,模块范围的初始化足以满足桥接的捕获和 Flue 的跨度。完成 Sentry HTTP 或数据库自动检测需要在应用导入之前进行 Sentry 的预加载设置,并应针对构建的 Flue 服务器进行验证。关闭刷新是尽力而为的:SIGINT/SIGTERM 监听器调用 Sentry.flush(...) 而不拥有进程退出,因此运行期间发送的跟踪和问题是安全的,而最近缓冲的日志可能会被截断。

在 Cloudflare 上,Flue 对每个检测的智能体的最终生成的 Durable Object 类应用模块本地的 wrap 扩展。这保留了 Flue 的路由和持久性行为,同时允许 Sentry 从当前绑定环境初始化,每个隔离区一次。包装器不覆盖外部 Worker 或编写的 Hono 应用;当需要请求检测时,单独添加 HTTP 中间件。

验证

针对非生产 Sentry 项目使用 SENTRY_TRACES_SAMPLE_RATE=1,提示一个使用工具的智能体,并确认一个带有 invoke_agent、chat 和 execute_tool 跨度的跟踪,加上其在 Sentry 日志中的日志。触发一个终端失败,并确认恰好有一个带有原始错误和抛出位置堆栈的问题。确认预期的 flue.* 关联字段,当记录标志关闭时没有模型内容出现,在 Cloudflare 上包装的智能体从工作线程交付,以及应用在没有配置 DSN 的情况下仍然启动。