跳转到内容
Telemetry
浏览文档

指南更新于 2026年7月28日阅读约需 5 分钟

让编程智能体使用这篇文档

打开 Claude Code、Codex、Cursor 或其他编码代理的集中提示包,然后将其适应此处介绍的工作流程。

本页内容
  1. 你将构建什么
  2. 1.从报告SQL开始
  3. 2.查询Telemetry并发布结果
  4. 3. 安排报告时间
  5. 让失败可见
  6. 设计一份人们会继续阅读的报告

将计划的 SQL 报告发送到 Slack

团队需要定期更新时,可以将计划运行的 SQL 报告发送到 Slack。注明时间范围和分母,方便理解数据。附上仪表板链接,并记录发送是否成功。

本指南使用 Telemetry Query API、Slack 传入 Webhook 和定时运行的 GitHub Actions 工作流。运行计划和 Slack 发送需要你自行配置。

你将构建什么

报告工作将:

  1. 针对 api_request_completed 运行只读 SQL 查询;
  2. 将结果格式化为一个小的 Slack Block Kit 消息;
  3. 通过传入的 webhook 发布它;
  4. 因查询或传递错误而失败,因此调度程序会记录该问题。

您需要 Telemetry API 密钥、Slack 传入 Webhook URL、Node.js 20 或更高版本,以及可以配置加密工作流程机密的存储库。

Slack 将传入的 Webhook 记录为接受 JSON 消息负载的唯一秘密 URL。使 URL 远离源代码控制,如果暴露,则对其进行轮换。参见 Slack 的传入 webhook 指南。

1.从报告SQL开始

保持第一份报告简短并以决策为导向:

SELECT
  route,
  COUNT(*) AS requests,
  SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors,
  ROUND(
    100.0 * SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END)
      / NULLIF(COUNT(*), 0),
    2
  ) AS error_rate_pct
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY route
ORDER BY error_rate_pct DESC, requests DESC
LIMIT 5;

该消息应显示“过去 24 小时”,而不是“今天”,因为调度程序和读取器可能使用不同的时区。 requests 列在两个请求上保持较高的错误率,看起来不像是一个大容量事件。

首先测试 Telemetry 中的查询。确认字段类型并决定重试是否算作单独的请求。 API 错误率配方 包括类型化合约、合成输出、图表和操作边缘情况。

2.查询Telemetry并发布结果

在将运行报告的存储库中将其保存为 scripts/post-telemetry-report.mjs:

const { TELEMETRY_API_KEY, SLACK_WEBHOOK_URL, TELEMETRY_DASHBOARD_URL } =
  process.env;

if (!TELEMETRY_API_KEY || !SLACK_WEBHOOK_URL) {
  throw new Error(
    "TELEMETRY_API_KEY and SLACK_WEBHOOK_URL are required to run this report"
  );
}

const sql = `
SELECT
  route,
  COUNT(*) AS requests,
  SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors,
  ROUND(
    100.0 * SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END)
      / NULLIF(COUNT(*), 0),
    2
  ) AS error_rate_pct
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY route
ORDER BY error_rate_pct DESC, requests DESC
LIMIT 5
`;

const queryResponse = await fetch("https://api.telemetry.sh/query", {
  method: "POST",
  headers: {
    Authorization: TELEMETRY_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ query: sql, realtime: true, json: true }),
});

if (!queryResponse.ok) {
  throw new Error(
    `Telemetry query failed: ${queryResponse.status} ${await queryResponse.text()}`
  );
}

const queryResult = await queryResponse.json();
const rows = Array.isArray(queryResult.data) ? queryResult.data : [];
const lines =
  rows.length > 0
    ? rows.map(
        (row) =>
          `• \`${row.route}\`, ${row.error_rate_pct}% errors ` +
          `(${row.errors}/${row.requests})`
      )
    : ["• No matching requests in the last 24 hours"];

const dashboardLink = TELEMETRY_DASHBOARD_URL
  ? `\n<${TELEMETRY_DASHBOARD_URL}|Open the Telemetry dashboard>`
  : "";

const slackResponse = await fetch(SLACK_WEBHOOK_URL, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    text: "Daily API reliability report",
    blocks: [
      {
        type: "header",
        text: { type: "plain_text", text: "Daily API reliability" },
      },
      {
        type: "section",
        text: {
          type: "mrkdwn",
          text:
            "*Window:* trailing 24 hours\n" +
            lines.join("\n") +
            dashboardLink,
        },
      },
      {
        type: "context",
        elements: [
          {
            type: "mrkdwn",
            text: "Synthetic example format. Validate thresholds and counting rules.",
          },
        ],
      },
    ],
  }),
});

if (!slackResponse.ok) {
  throw new Error(
    `Slack delivery failed: ${slackResponse.status} ${await slackResponse.text()}`
  );
}

console.log(`Posted ${rows.length} report rows to Slack.`);

仅当执行此脚本时才会发生环境检查。它们不会向您的应用程序的导入或启动路径添加新的要求。

避免在 Slack 消息中包含原始错误消息、客户标识符、提示或请求负载。将授权读者链接到仪表板以进行更深入的调查。

3. 安排报告时间

创建.github/workflows/telemetry-report.yml:

name: telemetry reliability report

on:
  schedule:
    - cron: "15 16 * * 1-5"
      timezone: "America/Los_Angeles"
  workflow_dispatch:

jobs:
  post-report:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: node scripts/post-telemetry-report.mjs
        env:
          TELEMETRY_API_KEY: ${{ secrets.TELEMETRY_API_KEY }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          TELEMETRY_DASHBOARD_URL: ${{ vars.TELEMETRY_DASHBOARD_URL }}

GitHub 计划的工作流从默认分支运行。工作流程语法支持 POSIX cron 和 IANA 时区;检查 GitHub的工作流程语法参考 中的当前行为。

添加 TELEMETRY_API_KEY 和 SLACK_WEBHOOK_URL 作为加密的 Actions 密钥。仪表板 URL 通常不是秘密,因此如果 URL 本身未显示敏感标识符,则它可以是存储库变量。

推出报告时保留 workflow_dispatch。它允许审阅者在等待第一次计划执行之前手动运行确切的作业。

让失败可见

静默计划作业不是操作系统。至少:

  • 让非 2xx 查询和 Webhook 响应使工作流程失败;
  • 保持调度程序的失败通知处于启用状态;
  • 在有界报告事件中记录 report_name、window_start、window_end、row_count、delivery_status 和 latency_ms;
  • 避免自动重试格式错误的有效负载或撤销的 Webhook;
  • 如果您稍后迁移到支持它的 API,请使用稳定的幂等密钥。

Slack 可以针对无效负载、禁用的挂钩、存档通道或策略限制返回不同的 4xx 响应。不要盲目地每 4xx 重试一次。将超时或 5xx 视为潜在的暂时性传送失败,并通过回退进行上限重试。

设计一份人们会继续阅读的报告

把决定放在第一位。有用的报告会列出发生的变化、显示分母以及证据链接。精心挑选的 10 行通常比粘贴到聊天中的 CSV 更好。

当读者需要任意过滤时,使用表格或仪表板而不是聊天。当响应无法等待计划的窗口时,请使用告警而不是每日报告。当结果对于消息而言太大时,请使用 出口指南。

可能的后续报告包括 按功能划分的 LLM 成本、后台作业重试结果、Webhook 重试恢复 和 事件期间对客户的影响。

相关功能

将经过验证的查询转变为重点突出、可审查的操作视图。

页面作者和参考资料

Telemetry 编辑团队负责维护本文;产品团队审核功能行为、示例和适用范围。

我们如何审核文档