日志与 Logpush:免费档能看到什么,看不到什么
"日志"在 Cloudflare 上是几件不同的东西,免费与付费的分界线也不同:控制台里的流量分析是聚合指标,没有原始请求行;Security Events 记录被安全功能处理过的请求,能查到单条;Worker 内部打的 console.log 要用 wrangler tail 或 Workers Logs 看;而 Logpush——把原始日志持续推到 S3、R2、Datadog 这类目的地——属于付费能力。
先把这条分界线记清楚,排查问题时就不会在错误的页面里找数据。安全事件的整体排查顺序见 86-attack-triage-order.md,Worker 侧的可观测性配置见 66-workers-observability.md。
1. 四条路径的差别
| 路径 | 免费档 | 数据形态 | 能回答 |
|---|---|---|---|
| Analytics(控制台) | 有 | 聚合指标、图表 | 请求量、状态码分布、缓存命中率、国家分布 |
| Security Events | 有 | 单条事件 | 哪个规则拦了哪个请求、Ray ID、来源 |
| wrangler tail | 有 | 实时流、逐条 | Worker 的 console 输出、异常、耗时 |
| Workers Logs | 有(保留期短) | 结构化、可查询 | 部署后的运行日志,按时间与字段筛 |
| Logpush | 付费 | 批量推送到对象存储或分析平台 | 长期留存、与自有数据管道合并 |
免费档的短板是留存与外送:控制台分析的窗口有限,tail 是实时流不落盘,Security Events 保留时间也不长。要长期留存,要么自己写脚本定期拉,要么升级。
2. 用 tail 看 Worker 日志
部署一个带日志的 Worker:
export default {
async fetch(request) {
const url = new URL(request.url);
console.log(JSON.stringify({
msg: "request",
path: url.pathname,
ua: request.headers.get("user-agent"),
cfRay: request.headers.get("cf-ray")
}));
if (url.pathname === "/boom") {
console.error(JSON.stringify({ msg: "upstream failed", code: 502 }));
return new Response("upstream failed", { status: 502 });
}
return new Response("ok\n", { headers: { "content-type": "text/plain" } });
}
};
终端里开 wrangler tail cf85-log-demo --format pretty,然后发两个请求(一个正常、一个走 /boom),抓到的输出:
Successfully created tail, expires at 2026-11-10T12:44:50Z
Connected to cf85-log-demo, waiting for logs...
GET https://cf85-log-demo.hyysn.workers.dev/hello - Ok @ 2026/11/10 14:45:01
(log) {"msg":"request","path":"/hello","ua":"Mozilla/5.0 ... PowerShell/7.6.3","cfRay":"a58317898cbb1089"}
GET https://cf85-log-demo.hyysn.workers.dev/boom - Ok @ 2026/11/10 14:45:02
(log) {"msg":"request","path":"/boom","ua":"...","cfRay":"a58317905c5984b1"}
(error) {"msg":"upstream failed","code":502}
三个细节值得注意。
第一行 - Ok 说的是这次 Worker 调用的结局,不是 HTTP 状态码。/boom 返回 502,但脚本正常执行完了,所以仍是 Ok;只有未捕获异常才会显示 Exception。用 tail 判断故障时,别把 Ok 当成"请求成功"。
(log) 与 (error) 是级别,分别对应 console.log 与 console.error。级别只影响显示与后续过滤,不影响是否输出。
expires at 是会话时限,tail 不是常驻进程,长时间挂着会断开,要重新连。
--format json 输出适合管道处理:
wrangler tail cf85-log-demo --format json | jq -c 'select(.logs[].level == "error")'
3. 日志怎么写才有用
一次请求一条 JSON,字段固定,便于后续过滤:
| 字段 | 示例 | 用途 |
|---|---|---|
| msg | request | 区分日志类型 |
| path | /api/orders | 定位接口 |
| status | 502 | 结果 |
| ms | 137 | 总耗时 |
| upstream_ms | 120 | 上游耗时,定位是慢在自己还是慢在别人 |
| ray | a58317898cbb1089 | 与控制台事件对齐 |
| err | upstream_timeout | 错误分类,别只打 message |
三条纪律:时间戳用 UTC ISO 格式,别用本地时间;不打印 token、Cookie、手机号这类敏感字段;错误日志带分类码而不是只有一句人话,否则没法统计。
console.log 有次数与体积限制,高频打日志会拖慢 Worker。调试期临时打开,上线前用环境变量控制开关。
4. Logpush:什么时候需要它
Logpush 把日志批量推送到目的地,支持 S3、R2、GCS、Datadog、Splunk、New Relic 等。它解决的是"留存 + 与自有管道合并",这两件事免费档都做不到。
两条不同的产品线容易混:
| 类型 | 内容 | 套餐要求 |
|---|---|---|
| HTTP 请求日志(zone 级) | 每条边缘请求的完整字段 | 通常为 Enterprise |
| Workers Trace Events | Worker 的 console 输出与异常 | Workers 付费档 |
免费档能做的替代方案:用 wrangler tail --format json 在本地落盘,适合短期排查;或者在自己的 Worker 里把关键事件写进 KV / D1 / R2,适合量小且需要长期查的场景。写 KV 要注意每日写入限额,见 56-free-tier-limits-cheatsheet.md。
5. 排查时的取数顺序
出问题时按这个顺序看,能少走弯路:
- Analytics 看整体曲线,确认是全局还是单路径。
- Security Events 看请求是否在边缘就被拦了——很多"站点挂了"其实是被自己的规则拦住。
- wrangler tail 看 Worker 有没有异常、耗时是否异常。
- 需要历史对比时,才去翻自己落盘的日志。
第 2 步经常被跳过。403 与 5xx 在用户眼里都是"打不开",但在日志里是完全不同的两件事。
常见问题
免费档能看到请求的完整 URL 和请求体吗?
能看 URL,看不到请求体。日志里不含 body,需要记录业务数据就在 Worker 里自己打,注意别打敏感信息。
tail 能同时看多个 Worker 吗?
一个 tail 会话对应一个 Worker。要多路同时看,开多个终端,或者用 --format json 分别重定向到文件再合并。
日志里的 Ray ID 有什么用?
它是 Cloudflare 内部的请求标识,控制台的 Security Events、tail 输出、源站日志里都能对上同一个请求。报障时提供 Ray ID 比描述时间点有效得多。
小结
免费档的日志能力是"能看、不能存"。控制台分析看趋势,Security Events 看单条拦截,wrangler tail 看 Worker 内部,三条路覆盖了日常排查的绝大部分场景;Logpush 属于要长期留存或接自有管道时才需要的付费能力。
写日志的习惯比工具更重要:一次请求一条结构化 JSON,带 Ray ID 与耗时分解,错误带分类码。这套习惯在免费档与付费档都适用,换工具时不用重写。
数据来源与检索时间
检索时间 2026-11-10。
| 来源 | URL | 对应数据 |
|---|---|---|
| Workers 限额 | https://developers.cloudflare.com/workers/platform/limits/ | 免费档请求额度、console 日志的限制面 |
| WAF 概览 | https://developers.cloudflare.com/waf/ | Security Events 与安全规则的对应关系 |
| Cloudflare 定价页 | https://www.cloudflare.com/plans/ | Logpush 与请求日志属付费能力 |
核验说明
- tail 输出为本机真实执行:部署
cf85-log-demo后以wrangler tail --format pretty抓取,期间发了一个 200 请求与一个 502 请求,输出原样贴在文中;会话建立时间、过期时间、两条 CF-RAY 都是真实值。验证完执行wrangler delete删除,账号内未留资源。 - 官方页面为本机抓取(HTTP 200)。
- 未执行:无 Zone 权限,Logpush 与 Workers Logs 的控制台页面未打开,留存期与推送目的地未验证;
jq管道示例未运行。 - 未验证:Logpush 各套餐的具体准入条件按文档与定价页描述写成,未在账号内确认;"Workers Logs 保留期短"只说相对短,未给具体天数。