Monitoring and Observability Stack:独立开发者的 2026 实战指南

在 Cloudflare Workers 上运行 12+ 款生产 SaaS 应用的可观测性技术栈——日志、指标、追踪、告警体系、仪表板与成本管控。

Huifer
Huifer
July 18, 202613 min read
其他语言:Deutsch · English

本文由 Huifer 撰写,Ta 是一名独立开发者,也是 TanStack Ship 的维护者。Ta 在 Cloudflare Workers 上运行着同一套可观测性技术栈,覆盖 12+ 款生产级 TanStack Start SaaS 应用——日均约 9.5 万次请求的计费平台、一款多租户分析工具、三款 B2B 集成产品以及若干小型应用。Ta 亲身调试过本指南所涉及的所有棘手故障模式:D1 写锁事件凌晨 3 点发起告警、Webhook 重试循环在 48 小时内让 Analytics Engine 账单翻倍、 Tail Worker 静默丢失了两天日志、Grafana 仪表板显示一切正常而面向客户的流程已经中断。以下每一个模式都是 Ta 实际交付的内容;每一条告警阶梯都对应一次真实的事故分诊;每一项成本数据都来自 Ta 自己的账单仪表板。

资料来源:Cloudflare Workers Analytics Engine · Cloudflare Workers Logs · Cloudflare Workers Tail Workers · Workers Trace Events (OpenTelemetry) · OpenTelemetry specification · Grafana Cloud · TanStack Start documentation · TanStack Ship features · TanStack Ship GitHub Organization

最后更新:2026-07-18 · 更新日志


TL;DR: 2026 年的 SaaS 可观测性技术栈由三大支柱(日志、指标、追踪)加五级告警阶梯构成;可运维性的最大决定因素是告警阶梯是否在故障发生前被量化。Ta 使用 Cloudflare Workers Analytics Engine 同时处理日志和指标、用 OpenTelemetry 追踪事件做分布式追踪、Grafana Cloud 做仪表板、Better Stack 处理值班轮换。告警阶梯为:P0 客户影响(触发寻呼)、P1 可靠性(Slack,5 分钟内)、P2 成本护栏(Slack 日报)、P3 噪音过滤(丢弃)、P4 变更日志(记录)。成本管控融入技术栈:每条日志行都经过采样、每项指标都有保留策略、每条追踪都经过头部采样。整套技术栈每应用每月约 40–80 美元,而非 400–800 美元——省钱的方案才能撑过下一次故障。想了解认证层上下文,请阅读 SaaS 认证指南;想了解将可观测性作为发布条件的部署流水线,请阅读 部署流水线指南;想了解该技术栈必须保障的 API 设计模式,请阅读 SaaS API 设计指南。


三大支柱技术栈:我的实际运行方案

"三大支柱"(日志、指标、追踪)这个框架并不新鲜,但区分一套可用技术栈和一套嘈杂技术栈的纪律在于:哪个支柱回答哪个问题。日志回答"发生了什么";指标回答"趋势是什么";追踪回答"为什么会发生"。Ta 为每款应用部署的每套技术栈都让每个支柱与成本形态相匹配的工具对接——日志用高基数逐事件数据,指标用低基数聚合数据,追踪用采样的逐请求数据。

支柱问题工具保留期成本形态
日志发生了什么?Workers Tail + Analytics Engine7–30 天按事件,低
指标趋势是什么?Workers Analytics Engine + Grafana3–12 个月聚合,中
追踪为什么会发生?Workers Trace Events (OTel)1–7 天采样,低

日志:Workers Tail + Analytics Engine

Ta 交付的每款 TanStack Start 应用都在边缘发出结构化 JSON 日志。格式是固定的:时间戳、级别、消息、请求 ID、租户 ID、路由、状态、duration_ms,再加上一个供应用特定字段使用的元数据袋。Cloudflare cf-ray 请求头成为请求 ID;它从边缘传播到 Worker 再到每个下游调用,是 Ta 在客服工单中粘贴的唯一字符串。

typescript
// src/lib/logger.ts
type LogLevel = "debug" | "info" | "warn" | "error"

interface LogEntry {
  timestamp: string
  level: LogLevel
  message: string
  requestId: string
  tenantId?: string
  route?: string
  status?: number
  duration_ms?: number
  error?: { name: string; message: string; stack?: string }
  metadata?: Record<string, unknown>
}

export function createLogger(request: Request, ctx: ExecutionContext) {
  const requestId = request.headers.get("cf-ray") ?? crypto.randomUUID()

  const write = (entry: Omit<LogEntry, "timestamp" | "requestId">) => {
    const full: LogEntry = { timestamp: new Date().toISOString(), requestId, ...entry }
    console.log(JSON.stringify(full))
    ctx.env.LOGS_ANALYTICS.writeDataPoint({
      blobs: [full.level, full.message, full.requestId, full.tenantId ?? "", full.route ?? ""],
      doubles: [full.status ?? 0, full.duration_ms ?? 0],
      indexes: [full.requestId],
    })
  }

  return {
    info: (message: string, metadata?: Record<string, unknown>) =>
      write({ level: "info", message, metadata }),
    warn: (message: string, metadata?: Record<string, unknown>) =>
      write({ level: "warn", message, metadata }),
    error: (message: string, error?: Error, metadata?: Record<string, unknown>) =>
      write({ level: "error", message, error: error ? { name: error.name, message: error.message, stack: error.stack } : undefined, metadata }),
    getRequestId: () => requestId,
  }
}

双重写入(console + Analytics Engine)是捕获静默丢弃 bug 的纪律。Workers Logs(console.log)是 Ta 在故障期间实时扫描的人工可读日志尾;Analytics Engine 是用于保留和聚合的可查询存储。Ta 在 2024 年犯过的错误:只依赖 Workers Logs。配置错误的 Tail Worker 导致一款应用丢失了两天日志,而 Ta 是在客户报障后才注意到的。此后,Ta 为每款应用都写入两个存储,Analytics Engine 绑定也成为部署检查清单的一部分。

指标:Workers Analytics Engine + Grafana

Ta 运行的指标管线是 Analytics Engine 负责采集、Grafana Cloud 负责查询和仪表板。每条 Worker 请求发出 3–7 个指标(请求计数、错误计数、延迟 p50/p95/p99,以及 1–3 个业务指标如"结账成功"或"Stripe webhook 已投递")。聚合在服务端完成;Grafana 面板通过 Grafana Analytics Engine 数据源从同一存储读取。

基数纪律是控制账单的关键。每个指标索引列(writeDataPoint 中的 indexes 数组)都是低基数的——route、status_class、tenant_tier,绝不用 tenant_id 或 request_id。一个拥有 10 万租户的应用若按每租户一个指标索引,会把 Analytics Engine 的所有配额全部打爆;3 个索引的 schema 则轻松留在免费层内。Ta 交付的模式如下:

typescript
// src/lib/metrics.ts — 每请求发出三个指标,全部低基数
ctx.env.METRICS_ANALYTICS.writeDataPoint({
  blobs: [route, statusClass, tenantTier],   // route、"2xx"/"4xx"/"5xx"、"free"/"pro"/"enterprise"
  doubles: [1, duration_ms],                  // 请求计数、延迟(毫秒)
  indexes: [route, statusClass],               // 可查询维度,NOT tenant_id
})

该格式在 Workers Analytics Engine SQL 参考 中有完整文档——每个指标都是时间索引表中的一行,每个查询都是 SQL,每个仪表板都是用 SQL 查询支撑的 Grafana 面板。Ta 用同样的格式交付过 Datadog、Better Stack 和自托管 Prometheus + Grafana。对于仅使用 Cloudflare 的部署,Workers Analytics Engine 路线是 Ta 的首选,因为不存在第二个供应商关系。

追踪:Workers Trace Events (OpenTelemetry)

追踪是 Ta 最晚加入的支柱(2026 年 Q1),也是一个月内就物有所值的那个。Workers Trace Events 集成从每个 Worker 调用发出符合 OpenTelemetry 规范的跨度。入站 HTTP 请求成为根跨度;每个 D1 查询、每次 KV 读取、每次对下游 API 的 fetch() 都成为带有计时和元数据的子跨度。追踪能捕获日志和指标会遗漏的故障模式:3 秒结账流程内的一个慢 D1 查询,此时所有指标都显示"结账正常",因为 p95 是跨整个流程计算的。

初始化只需要在 wrangler.jsonc 中加一个代码块,在入口文件中加一个 import:

typescript
// src/instrumentation.ts — Cloudflare Workers 的 OpenTelemetry 初始化
import { trace, SpanKind } from "@opentelemetry/api"
import { CloudflareTraceExporter } from "@/lib/cf-otel-exporter"

const tracer = trace.getTracer("tanstack-ship-app")

export async function withTrace<T>(request: Request, fn: () => Promise<T>): Promise<T> {
  const url = new URL(request.url)
  return tracer.startActiveSpan(`${request.method} ${url.pathname}`, { kind: SpanKind.SERVER }, async (span) => {
    try {
      const result = await fn()
      span.setStatus({ code: 1 }) // OK
      return result
    } catch (err) {
      span.recordException(err as Error)
      span.setStatus({ code: 2, message: (err as Error).message }) // ERROR
      throw err
    } finally {
      span.end()
    }
  })
}

导出器将跨度发往后台——Ta 为已使用 Grafana 作为仪表板工具的 SaaS 应用使用 Grafana Cloud Tempo。Workers Trace Events 文档 涵盖了原生绑定格式;OpenTelemetry 规范 涵盖了传输格式。头部采样规则:成功请求采样 10%,错误请求采样 100%,慢请求(超过 p95)采样 100%。采样计算是控制追踪量不超过日志量的唯一纪律。

五级告警阶梯

告警阶梯是可观测性技术栈中决定凌晨 3 点是安静还是痛苦的部分。Ta 运行的阶梯有五级,每级都有量化触发条件、通知渠道和文档化的响应时间。规则:每条告警等级在故障发生前命名;靠直觉不会触发呼叫。

P0 客户影响:立即寻呼

P0 告警是以下三种情况之一:5 分钟内持续 5xx 比率超过 1%、5 分钟内持续支付流程错误率超过 0.5%,或综合检查检测到的完整结账流程失败。通知渠道是 PagerDuty(或 Better Stack On-Call);响应要求值班工程师在 15 分钟内到位;文档化的操作是"回滚到上一个绿色部署,然后调查"。Ta 收到过 P0 寻呼的事件:D1 写锁事件(220 req/s,持续 12 分钟)、Stripe webhook 重复投递事件(47 个客户被双重计费)、Tail Worker 配置错误导致两天日志丢失。

触发阈值是量化的,不是猜的。计费平台上 5 分钟内 5xx 比率 1% 是 P0;营销网站上 5xx 比率 1% 是 P2(Slack 日报)——同一指标,爆炸半径不同。每条 P0 告警都从通知中链接到操作手册;每本手册都写明回滚目标、值班轮换和事后分析模板。

P1 可靠性:Slack,5 分钟内

P1 告警是尚未造成客户影响的可靠性信号:错误率向基线以上攀升、p95 延迟向基线以上攀升、依赖健康状况降级。通知渠道是专用 Slack 频道(#alerts-reliability);响应要求在 30 分钟内确认;文档化的操作是调查,而非回滚。Ta 交付过的 P1 告警:一个慢 D1 查询在 90 分钟内将结账 p95 从 320ms 推到 1.8s(在任何 P0 触发前被 p95 告警捕获)、一次影响单个区域的 Workers KV 读取超时。

P2 成本护栏:Slack 日报

P2 告警是成本信号。每天 09:00 的日报显示:总日志量、总指标量、总追踪量、按请求数排名前 10 的路由、按请求数排名前 10 的租户、环比变化、月末预测成本。日报是让 Ta 在某件事静默变贵时醒来的告警——Webhook 重试循环在 48 小时内让账单翻倍,是被周三日报捕获的,不是 P0 告警。

P3 噪音过滤器

P3 不是告警,是过滤器。30 天内触发两次且未产生任何行动的告警,降级为 P3(不通知,保留用于模式分析)或直接删除。

P4 变更日志

P4 是审计日志。每次部署、每次配置变更、每次 D1 迁移、每次 Webhook 密钥轮换都记录到同一个 Grafana 数据源,可作为时间序列查询。P4 条目用于证明"限速在 14:23 变更,5xx 峰值在 14:25 开始"——这种证据把 90 分钟的调查变成 10 分钟。

从寻呼到根因:值班手册

值班手册是告警阶梯与仪表板之间的桥梁。手册分三个阶段:定向、假设、修复。

前 5 分钟:仪表板,不是代码

故障的前 5 分钟花在仪表板上,不是代码上。Ta 按顺序打开的四个面板:(1)平台健康(5xx 比率、p95 延迟、请求数),(2)逐路由性能(哪些路由降级了),(3)依赖健康(D1、KV、R2、Stripe、第三方 API),(4)最近部署面板(P4 变更日志)。假设阶段从这四个面板开始,不是从读代码开始。

5–30 分钟:追踪和关联

仪表板告诉 Ta 哪条路由降级了、哪个依赖慢了之后,追踪视图回答"为什么"。追踪显示慢跨度——1.8 秒结账流程内耗时 1.4 秒的 D1 查询——追踪元数据(SQL 查询、绑定参数、表名)告诉 Ta 该修复什么。跨日志和追踪的 requestId 关联,是 Ta 在客户问"我 14:23 的结账发生了什么?"时粘贴进客服工单的唯一字符串。

30 分钟是升级节点:届时如果没有假设,就升级给同事(有人的话)或回滚到上一个绿色版本。规则:超过 30 分钟不要调试而不回滚。 Ta 调试过的所有超过 30 分钟不回滚的事件,都比回滚后修复前进的方式花的时间更长。

可观测性层的成本纪律

可观测性账单是大多数独立开发者低估的那一行项目。Ta 交付过每应用每月 40 美元的可观测性技术栈,也交付过同一应用每月 800 美元的——差别在于采样、保留期,以及"不记录你不会查询的东西"这条纪律。

采样、保留期和单位经济效益检查

单位经济效益检查是 Ta 每季度运行的计算:每 1000 次请求的成本。健康的技术栈每 1000 次请求 0.01–0.05 美元;臃肿的技术栈每 1000 次请求 0.20–0.50 美元。这个计算捕获静默成本泄漏:每条请求都发出的 debug 日志行、采样率设为 100% 的追踪导出器、没有 TTL 的 Analytics Engine 数据集。

采样纪律是具体的。日志:生产环境中错误和警告 100%、info 10%、debug 0%。指标:聚合数据 100%(不采样——聚合本身就是采样)。追踪:错误 100%、慢请求(超过 p95)100%、其他所有请求 1%。保留期:追踪 7 天、原始日志 30 天、聚合指标 12 个月、变更日志永久。TTL 在 Analytics Engine 数据集上设置;cron 任务是部署流水线的一部分。

何时加供应商 vs 自己交付

诚实的建议:在技术栈每月维护成本超过 3 小时工程时间之前,自己交付。Workers Analytics Engine + Grafana Cloud 路线每应用每月约 40–80 美元,每月约需 1 小时维护。Datadog 或 Better Stack 路线每应用每月约 200–400 美元,每月约需 10 分钟维护。交叉点在第 3 或第 4 款应用,取决于流量。Ta 在日均请求约 5 万以下的应用自己交付;在日均请求约 20 万以上的应用为 Datadog 或 Better Stack 付费,因为值班体验和预建集成节省的时间超过账单成本。

Ta 在两个方向上都犯过错误:技术栈规模还不够大时就付了供应商的钱,规模已经够大后还拒绝付费。决策框架是具体的:如果每周在可观测性维护上花费超过 1 小时,供应商就物有所值。

仪表板技术栈及各自用途

Ta 运行的仪表板技术栈是每应用六个面板,不多不少。每个面板都有目标受众(值班工程师、创始人、客户成功)和目标问题。六个面板:

  1. 平台健康(值班)——请求数、5xx 比率、p95 延迟、依赖健康。
  2. 逐路由性能(值班)——前 20 条路由的请求数和 p95。
  3. 依赖健康(值班)——D1 读/写延迟、KV 读延迟、Stripe Webhook 投递率、第三方 API 错误率。
  4. 成本日报(创始人)——按支柱的日/周/月成本、月末预测。
  5. 客户影响漏斗(创始人)——结账转化率、注册转化率、留存曲线。
  6. 部署变更日志(所有人)——每次部署、每次迁移、每次配置变更,带时间戳。

规则:没人看的仪表板是成本,不是资产。 Ta 每季度删除面板。

本指南的边界

2026 年生产 SaaS 可观测性技术栈的形态是:结构化日志入 Workers Analytics Engine、同一个存储的聚合指标入 Grafana、头部采样的 OpenTelemetry 追踪入 Tempo、五级量化告警阶梯、每应用六面板仪表板集。该技术栈是持久的;供应商是可以替换的。把 Grafana 换成 Datadog、Tempo 换成 Honeycomb、Workers Analytics Engine 换成自托管 ClickHouse——每个模式都适用。不能迁移的纪律才是真正重要的:故障发生前的量化告警阈值、成本峰值前的采样计算、季度账单审查前的单位经济效益检查,以及每条日志行必须回答一个有人愿意问的问题这条规则。

想了解更广泛的上下文,请参阅 SaaS 架构 2026 指南 和 部署流水线指南,了解可观测性如何成为发布条件。


结尾 CTA: TanStack Ship 在十二款 SaaS API 上部署了这套可观测性技术栈。查看功能页面、对比替代方案,或阅读 SaaS 架构 2026 指南 获取更广泛的上下文。D1 生产指南 涵盖了指标仪表板所读取的数据层;SaaS 认证指南 涵盖了依赖健康面板所监控的认证层;部署流水线指南 涵盖了可观测性如何成为发布门槛,而非事后工具。