将计划的 SQL 报告发送到 Slack
计划的 SQL 报告将审核的查询变成了经常性的团队习惯。有用的版本不仅仅将行粘贴到聊天中:它命名时间窗口,包括分母,链接回持久仪表板,并记录交付是否成功。
本指南使用 Telemetry 查询 API、Slack 传入 Webhook 和计划的 GitHub 操作工作流。这是一种集成模式,而不是声称 Telemetry 具有本机 Slack 报告按钮。
你将构建什么
报告工作将:
- 针对
api_request_completed运行只读 SQL 查询; - 将结果格式化为一个小的 Slack Block Kit 消息;
- 通过传入的 webhook 发布它;
- 因查询或传递错误而失败,因此调度程序会记录该问题。
您需要 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 重试恢复 和 事件期间对客户的影响。