KernelRanch
返回文章列表

可观测性与日志:从 metrics 到 wrangler tail 的排查路径

2026-11-10 #Cloudflare

读完这一篇,你能判断一个 Worker 出了问题时该看哪一层:请求量异常看 metrics,单条请求失败用 wrangler tail 抓现场,需要回溯历史查 Workers Logs,要长期留存接 Logpush;也知道 console.log 的输出到底去了哪里,以及怎么写出能被过滤的结构化日志。

本篇没有部署中的 Worker 可供 tail,所以 wrangler tail 的输出形态依据文档与既有使用经验给出,命令参数以 wrangler tail --help 为准。第 5 节的观察顺序是实践总结。

1. 四层手段,解决四种问题

层看什么保留时间代价
Metrics请求数、错误率、CPU 时间、P50/P99控制台图表周期免费
Workers Logsconsole.log 与异常堆栈有限天数免费额度内
wrangler tail实时请求流与日志只在会话期间免费
Logpush全量请求日志导出到外部由你的存储决定付费功能

判断顺序通常是从上往下:先确认"是不是整体挂了"(metrics),再抓一条具体失败的请求(tail),再回看历史(Logs),最后才是长期留存(Logpush)。

2. console.log 去了哪里

在 Worker 里写 console.log("hi"),这段文字不会出现在响应里,也不会写到本机终端(除非你在 wrangler dev)。线上它进两个地方:

console.log("order created", orderId);
console.error("upstream failed", status, url);

console.log 进 Workers Logs,同时如果你正开着 wrangler tail,也会实时出现在那个流里。console.error 除了打日志,还会被计入错误指标,tail --status error 能过滤到。

console.log 传对象时会被序列化,深层嵌套或循环引用可能被截断。稳妥的写法是先 JSON.stringify:

console.log(JSON.stringify({ evt: "order_created", orderId, ms: 12 }));

这样在 tail 里能按 order_created 搜索,也能直接喂给日志平台解析。

3. wrangler tail

wrangler tail cf53-demo
wrangler tail cf53-demo --format json
wrangler tail cf53-demo --status error
wrangler tail cf53-demo --search "order_created"

不带参数时连当前目录 wrangler.toml 里的 Worker,带上名字就连指定 Worker。默认是 pretty 格式,人眼友好;--format json 输出一行一个 JSON 对象,方便 jq 或写进文件分析。

--status error 只显示失败请求,--search 按文本匹配日志内容。这两个组合起来很实用:

wrangler tail cf53-demo --status error --search "upstream failed" --format json

连上之后每来一个请求就打印一条,包含时间、方法、路径、状态码、耗时、colo、cf-ray,以及该请求里打的所有日志。cf-ray 是把这个请求和 Cloudflare 支持工单、其他日志对上的唯一凭据,报障时要带上它。

同系列 85 篇在验证响应头那个 Worker 时真跑过一次 wrangler tail --format pretty,输出里能看到三类信息:请求行(方法、路径、状态)、这次请求打出的日志(带 (log) / (error) 前缀)、以及 CF-RAY 和日志会话的过期时间。

那次观测里有个容易误读的地方:tail 显示的 - Ok 是"调用结局",不是 HTTP 状态码。Worker 返回 502 时它也可能显示 Ok。要判断请求成功与否,得看日志里自己打的状态字段或指标面板,不能看这个 Ok。

tail 有三个限制要说清:它只观察当前正在发生的请求,不能回溯;会话断开(Ctrl+C、网络断)之后这一段就没了;高流量下会采样,看到的不一定是全量。要"事后查"就得靠 Logs 或 Logpush。

4. 结构化日志的写法

一条好的日志至少包含四样:事件名、关键标识、耗时、结果。

const t0 = Date.now();
const res = await fetch(upstream, { headers });
console.log(JSON.stringify({
  evt: "upstream_call",
  host: new URL(upstream).host,
  status: res.status,
  ms: Date.now() - t0,
  ray: request.headers.get("cf-ray")
}));

evt 用作过滤键,ray 用来和本次请求的其他日志串联,ms 用来判断慢在哪一段。避免把整个 request 或 env 直接打出来——里面有 authorization、有 secrets,日志会变成泄漏渠道,相关注意点见 64-workers-env-secrets.md。

5. 一条实际可用的排查顺序

第一步看 metrics 的错误率曲线,确认是"全站失败"还是"某个接口失败"。全站失败优先怀疑部署、绑定、上游整体不可用;单接口失败直接进第二步。

第二步 wrangler tail --status error 抓几条现场,看状态码分布和日志里的异常文本。这一步能解决大部分问题:上游 5xx、超时、JSON 解析失败、绑定名字写错。

第三步回看 Workers Logs,找同一 cf-ray 的更早记录,判断是"一直这样"还是"刚刚开始"。如果错误集中在某个时间段,再对照那次时间点有没有部署、有没有改配置。

第四步才是加固观测:给关键路径补 evt 日志,给定时任务写成功时间戳(见 63-workers-cron-triggers.md),需要长期留存就上 Logpush。

这套顺序的价值在于避免"一上来就加日志再重新部署"。大部分线上问题用 metrics 加 tail 就能定位,加日志属于事后改进,不是排查手段。

6. 常见问题

问:wrangler tail 里看不到我自己打的日志? 答:三个常见原因。日志在 scheduled 或队列消费者里打的,那些入口的日志不一定进同一条 tail 流;日志级别被过滤;或者请求根本没到你这条代码路径(比如被 WAF 拦在前面)。先确认请求确实产生了 cf-ray 响应头。

问:免费档的日志保留多久? 答:Workers Logs 的保留时间有限,具体天数以控制台显示为准。需要长期留存只能自己导出,Logpush 是付费功能,另一个办法是在 Worker 里把关键事件写进 KV 或 D1,自己控制保留策略。

问:怎么统计"每分钟有多少次失败"这种自定义指标? 答:轻量做法是往 KV 写计数,但 KV 的写延迟在几百毫秒级且最终一致,不适合高频计数,见 59-workers-kv-tutorial.md。要精确计数用 Durable Objects,要做聚合分析用 Analytics Engine。

小结

观测手段分四层,用途不重叠:metrics 回答"整体健康吗",wrangler tail 回答"这一条请求怎么了",Workers Logs 回答"之前发生过吗",Logpush 回答"能不能留半年"。

tail 是日常最趁手的工具,但它只能看当下,所以关键路径上的日志要提前设计好:带 evt 名字、带 cf-ray、带耗时、不带密钥。排查时按 metrics、tail、Logs 的顺序走,比直接改代码加日志再部署快得多。本地阶段的调试方式见 65-wrangler-dev-debug.md,安全事件的排查顺序见 86-attack-triage-order.md。

数据来源与检索时间

检索时间 2026-11-10。

来源URL对应数据
Workers 可观测性概览https://developers.cloudflare.com/workers/observability/metrics、Logs、tail、Logpush 的分层(未抓取)
实时日志 tailhttps://developers.cloudflare.com/workers/observability/logs/tail-workers/wrangler tail 的参数与限制(未抓取)
Workers Logshttps://developers.cloudflare.com/workers/observability/logs/workers-logs/console.log 的去向与保留策略(未抓取)

核验说明

  • 本篇作者未部署新 Worker;第 3 节的 tail 输出特征来自同系列 85 篇的实测(cf85-log-demo,验证后已删除)。--status / --search / --format json 的行为没有实测,参数以 wrangler tail --help 的输出为准。
  • 未验证:Workers Logs 的具体保留天数、采样率、--status error 对 console.error 的判定口径。文中没有给出这些数字,只说明"有限"。
  • 第 5 节的排查顺序是实践总结,不是某次具体故障的复盘记录。
  • cf-ray 作为请求唯一凭据、console.log 进 Logs 与 tail 这两点,与前几篇在本机部署时观察到的 cf-ray 响应头一致(见 57-workers-request-response.md 的实测记录)。
  • 未做:没有测 Analytics Engine,没有测 Logpush 配置,没有测高流量下的采样比例。