端到端 SaaS 可觀測性示範
該示範將一組確定性的合成 SaaS 工作流程事件傳送到 Telemetry,並使用 SQL 查詢它們。它故意設計得足夠小,可以一次性檢查,同時仍然連線可靠性、產品結果、後台工作和人工智慧成本。
該範例不使用生產流量或客戶資料。每次執行都有一個唯一的 run_id,因此它的查詢可以隔離它建立的行。
示範證明了什麼
一份廣泛的事件合約可以回答幾個問題:
- 工作流程完成了嗎?
- 哪一步失敗或重試?
- 每個步驟花了多長時間?
- 該工作流程產生的 AI 預估成本是多少?
- 哪些帳戶計劃和版本受到影響?
該程式碼直接使用公共 HTTP 端點,因此事件、API 請求和 SQL 結果之間沒有框架或 SDK 抽象。
先決條件
您需要 Node.js 20 或更高版本以及 Telemetry API 金鑰。僅在將執行範例的 shell 中匯出金鑰:
export TELEMETRY_API_KEY="YOUR_API_KEY"
該儲存庫還將可執行源保留在 examples/saas-observability-demo 中。完整的程式如下所示,因此資料協定和查詢在此頁面上仍然可見。
完整的程式
將其另存為 demo.mjs:
import { randomUUID } from "node:crypto";
const apiKey = process.env.TELEMETRY_API_KEY;
if (!apiKey) {
throw new Error("TELEMETRY_API_KEY is required to run this demo");
}
const apiOrigin = process.env.TELEMETRY_API_ORIGIN || "https://api.telemetry.sh";
const runId = randomUUID();
const table = "saas_observability_demo";
const base = {
run_id: runId,
account_id: "synthetic_acme",
plan: "growth",
release: "demo-2026.07",
region: "us-west",
};
const events = [
{
...base,
event_name: "checkout_started",
workflow: "subscription_checkout",
step: "checkout",
outcome: "started",
duration_ms: 18,
retry_count: 0,
estimated_cost_usd: 0,
},
{
...base,
event_name: "payment_authorized",
workflow: "subscription_checkout",
step: "payment",
outcome: "success",
duration_ms: 284,
retry_count: 0,
estimated_cost_usd: 0,
},
{
...base,
event_name: "invoice_job_completed",
workflow: "subscription_checkout",
step: "invoice_job",
outcome: "success",
duration_ms: 618,
retry_count: 1,
estimated_cost_usd: 0,
},
{
...base,
event_name: "welcome_email_completed",
workflow: "subscription_checkout",
step: "welcome_email",
outcome: "failed",
duration_ms: 910,
retry_count: 2,
error_type: "provider_timeout",
estimated_cost_usd: 0,
},
{
...base,
event_name: "ai_summary_completed",
workflow: "subscription_checkout",
step: "ai_summary",
outcome: "success",
duration_ms: 742,
retry_count: 0,
model: "configured-demo-model",
input_tokens: 820,
output_tokens: 146,
estimated_cost_usd: 0.0042,
},
];
const ingestResponse = await fetch(`${apiOrigin}/log`, {
method: "POST",
headers: {
Authorization: apiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({ table, data: events }),
});
if (!ingestResponse.ok) {
throw new Error(
`Ingest failed: ${ingestResponse.status} ${await ingestResponse.text()}`
);
}
const sql = `
SELECT
workflow,
COUNT(*) AS event_count,
SUM(CASE WHEN outcome = 'failed' THEN 1 ELSE 0 END) AS failed_steps,
SUM(retry_count) AS retries,
SUM(estimated_cost_usd) AS estimated_cost_usd,
MAX(duration_ms) AS slowest_step_ms
FROM ${table}
WHERE run_id = '${runId}'
GROUP BY workflow
ORDER BY workflow
`;
const queryResponse = await fetch(`${apiOrigin}/query`, {
method: "POST",
headers: {
Authorization: apiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({ query: sql, realtime: true, json: true }),
});
if (!queryResponse.ok) {
throw new Error(
`Query failed: ${queryResponse.status} ${await queryResponse.text()}`
);
}
const result = await queryResponse.json();
console.log(JSON.stringify({ run_id: runId, rows: result.data }, null, 2));
執行它:
node demo.mjs
預期的形狀是一個彙總行:
{
"run_id": "generated-for-this-run",
"rows": [
{
"workflow": "subscription_checkout",
"event_count": 5,
"failed_steps": 1,
"retries": 3,
"estimated_cost_usd": 0.0042,
"slowest_step_ms": 910
}
]
}
JSON 回應中的確切數字編碼可能因查詢結果序列化而異。以形義為契約。
檢查原始時間線
聚合告訴您工作流程有一個失敗的步驟。相關的時間線會告訴您哪個步驟失敗了以及周圍發生了什麼:
SELECT
timestamp_utc,
event_name,
step,
outcome,
duration_ms,
retry_count,
error_type
FROM saas_observability_demo
WHERE run_id = 'PASTE_RUN_ID'
ORDER BY timestamp_utc ASC;
run_id 的作用類似於工作流程關聯識別符號。在實際應用程式中,使用在工作流程邊界建立的穩定識別符號,並將其傳遞到 API 處理程式、佇列有效負載、作業、Webhook 和 AI 呼叫。
從同一個合約建置三個檢視
可靠性
按 release 或 region 繪製失敗步驟和最大持續時間的圖表。僅在定義最小量和團隊期望的回應後發出警示。
產品完成
計算到達預期終端事件的不同工作流程識別符號。當一個工作流程可以發出多個步驟時,請勿將行計為已完成的工作流程。
成本和價值
對 AI 步驟求和 estimated_cost_usd 並將其加入或關聯到後續結果,例如啟用、接受的輸出或成功的工作流程完成。將模型定價保留在版本化設定中,並將估算值與提供商發票進行核對。
生產變更
該示範更注重可見性而不是抽象性。生產實施應該:
- 在實際操作邊界而不是在示範陣列中建立事件;
- 使用有界模式並標準化路線、錯誤、計劃和發布值;
- 避免將不受信任的輸入插入到 SQL 中;
- 將 API 金鑰儲存在伺服器端秘密儲存中;
- 批次或緩衝事件而不隱藏永久性故障;
- 定義保留和刪除要求;
- 記錄生產者獨立演化時的模式版本;
- 衡量事件傳遞本身是否失敗。
使用 結構化記錄 進行檢測,使用 SQL 用於可觀測性 進行分析模型,使用 連線SQL實驗室 進行更大的六資料表資料集的視覺化結果。