엔드 투 엔드 SaaS 옵저버빌리티 데모
이 데모는 결정론적인 합성 SaaS 워크플로 이벤트 세트를 Telemetry로 보내고 SQL을 사용하여 다시 쿼리합니다. 신뢰성, 제품 결과, 백그라운드 작업 및 AI 비용을 연결하면서 한 번에 검사할 수 있을 만큼 의도적으로 작습니다.
샘플은 프로덕션 트래픽이나 고객 데이터를 사용하지 않습니다. 모든 실행에는 고유한 run_id가 있으므로 해당 쿼리는 생성된 행을 격리할 수 있습니다.
데모가 증명하는 것
하나의 와이드 이벤트 계약으로 다음과 같은 여러 질문에 답할 수 있습니다.
- 워크플로가 완료되었나요?
- 어떤 단계가 실패했거나 재시도되었나요?
- 각 단계마다 시간이 얼마나 걸렸나요?
- 워크플로로 인해 발생한 AI 비용은 얼마나 예상되나요?
- 어떤 계정 계획과 릴리스가 영향을 받았나요?
코드는 공개 HTTP 엔드포인트를 직접 사용하므로 이벤트, API 요청 및 SQL 결과 사이에 프레임워크 또는 SDK 추상화가 없습니다.
전제 조건
Node.js 20 이상과 Telemetry API 키가 필요합니다. 샘플을 실행할 셸에서만 키를 내보냅니다.
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 핸들러, 큐 페이로드, 작업, 웹훅 및 AI 호출을 통해 전달합니다.
동일한 계약에서 세 가지 뷰 구축
신뢰성
release 또는 region를 기준으로 실패한 단계 및 최대 기간을 차트로 표시합니다. 최소 볼륨과 팀에서 예상되는 응답을 정의한 후에만 알림합니다.
제품 완성
예상된 터미널 이벤트에 도달한 고유한 워크플로 식별자를 계산합니다. 하나의 워크플로가 여러 단계를 내보낼 수 있는 경우 행을 완료된 워크플로로 계산하지 마세요.
비용과 가치
AI 단계에 대해 estimated_cost_usd를 합산하고 이를 활성화, 허용된 출력 또는 성공적인 워크플로 완료와 같은 이후 결과에 결합하거나 연관시킵니다. 버전이 지정된 구성에서 모델 가격을 유지하고 공급자 송장에 대한 견적을 조정합니다.
프로덕션 변경 사항
데모는 추상화보다 가시성을 선호합니다. 프로덕션 구현은 다음을 수행해야 합니다.
- 데모 어레이가 아닌 실제 작업 경계에서 이벤트를 생성합니다.
- 제한된 스키마를 사용하고 경로, 오류, 계획 및 릴리스 값을 정규화합니다.
- 신뢰할 수 없는 입력을 SQL에 삽입하지 마세요.
- API 키를 서버 측 비밀 저장소에 보관합니다.
- 영구적인 실패를 숨기지 않고 이벤트를 일괄 처리하거나 버퍼링합니다.
- 보존 및 삭제 요구 사항을 정의합니다.
- 프로듀서가 독립적으로 진화할 때 스키마 버전을 기록합니다.
- 이벤트 전달 자체가 실패하는지 측정합니다.
계측에는 구조적 로깅을, 분석 모델에는 관측성을 위한 SQL를, 시각적 결과가 포함된 더 큰 6개 테이블 데이터 세트에는 연결된 SQL Lab을 사용하세요.