Cloudflare Workers
Debugging
Logs
Workers Tail
Observabilidade

Workers:调试、日志和 Workers Tail — 无需日志服务器即可在边缘进行观察

没有持久的进程,没有文件系统,如果没有活动的尾部会话,console.log 将无处可去——调试 Workers 需要不同的思维模型。

Workers:调试、日志和 Workers Tail — 无需日志服务器即可在边缘进行观察

当工程师第一次在生产 Worker 上设置 0 且没有看到任何东西出现时,本能地怀疑部署中存在错误。日志就这样消失了。没有具有持久性标准输出的应用程序服务器,磁盘上没有日志文件,没有在调用之间累积输出的进程。每个 Worker 执行都发生在 V8 隔离内,该隔离会诞生、处理请求并消失——除非您主动捕获它,否则不会留下任何痕迹。理解这个模型是任何真正在边缘发挥作用的可观察性策略的先决条件。

牧马人尾巴:它是什么和不是什么

1 会打开与 Cloudflare 基础设施的流连接,并实时重新传输 Workers 调用的事件:每个请求的元数据(方法、URL、响应状态、CPU 持续时间、原产国)、2 和 3 的整个输出、堆栈跟踪未捕获的异常以及 4 完成时的结果。

5 不做的事:坚持。当您关闭会话时,尚未到达的事件将丢失。在您打开会话之前发生的事件对您来说也不存在。 6 是一种实时调查工具,可用于重现你观察到的问题,但对于重建一小时前发生的情况毫无用处。

您可以使用7 过滤输出以仅查看错误,或8 以对 10% 的流量进行采样,并且不会在高负载下被淹没。在每秒数百个请求的服务中,未经过滤的尾部很快就会使终端变得不可读。

静默异常的陷阱

有一种运行时行为会吸引经验丰富的工程师:Worker 可以向客户端发送 200 响应,但仍然会抛出异常 — 只要该异常是在发送 9 后抛出的。

具体场景:响应后调用10做后台工作。如果 11 推出,客户已经收到 200 个并且很高兴。该异常作为与请求关联的错误事件出现在 12 中,但不会更改客户端看到的 HTTP 状态。如果尾部不打开,则永远不会出现错误。

这同样适用于您不在处理程序中执行的任何承诺。如果您在没有等待和错误处理的情况下触发 14,并且它拒绝,则未捕获的拒绝会出现在尾部,但不会影响客户端收到的响应。在 15° 的本地环境中,这种行为可能会有所不同 - 警告更加明显。生产过程中,一片寂静。

防御是系统性的:每个处理程序都必须有一个最高级别的 16 来捕获、用 17 记录并返回显式的 HTTP 500。传递到 18 的每个承诺都必须有内部错误处理。不是因为运行时会记住你——它不会。

牧马人开发本地与 --remote

没有标志的 19 使用 Miniflare(Workers 运行时的 Node.js 实现)运行本地服务器。对于大多数开发案例来说,这已经足够了:KV、D1、R2 和队列绑定可与本地内存或 SQLite 实现配合使用,并且反馈循环是即时的,无需涉及 Cloudflare 网络。

20 有​​所不同:它将 Worker 发送到真正的 Cloudflare 基础设施,并通过真正的边缘路由开发请求。当您需要测试 Miniflare 无法忠实模拟的行为时,这是必要的——生产中具有真实状态的持久对象、CDN 缓存行为或当前版本的 Miniflare 尚未实现的运行时功能。

权衡是显而易见的:21 需要 [40 身份验证,具有网络延迟,并且对 KV 或 D1 的任何写入操作都会转到真实资源(除非您设置单独的命名空间/暂存库,这应该是标准的)。在不隔离临时环境的情况下使用 22 是开发过程中破坏生产数据的最短路径。

Logpush:从短暂的尾部到真正的保留

对于任何需要重建事后发生的事情的服务(审计、事后调试、分析错误模式),23 是不够的。 Logpush 通过将 Workers 事件导出到配置的存储目标来解决此问题。

支持的目的地包括 R2(Cloudflare 自己的存储,导出每百万行 0.05 美元)、S3、Datadog、Splunk 等。配置通过仪表板或 API 完成:您选择数据集 (24)、目标以及要导出的字段 - 25、26、27、2829(其中包括30的输出)。

关于 31 字段的重要一点是:它捕获您传递给 32 的内容,但作为序列化文本。如果您记录了复杂的 JavaScript 对象,则到达 Logpush 的是该对象的字符串表示形式,而不是结构化 JSON。对于需要在目的地进行解析和过滤的日志(在 Datadog 中创建警报或在 Splunk 中进行查询),在记录之前显式序列化为 JSON:33。 Logpush 传递字符串;目标解析 JSON。

在生产环境中要监控什么——以及运行时不提供什么

Worker 本身并不发出分布式跟踪跨度。没有与 [OpenTelemetry41 的自动集成,如果没有手动实现,子请求之间就不会传播跟踪上下文。如果一个 Worker 通过 34 调用三个服务,其中一个需要 800 毫秒,则 35 会显示总持续时间,但不会细分时间花费的位置。为了获得这种可见性,您可以手动计时:提取之前 36 小时,之后 37 小时,并使用服务名称记录结构化结果。

Cloudflare 收购了 Baselime,并以 Cloudflare Observability 的名义集成其功能 - 日志和指标分析比手动尾部更符合人体工程学,但真正的分布式跟踪仍然需要在代码或跨子请求传播 38° 的 SDK 中进行检测。

在客户端注意到之前检测降级的最有用指标:CPU 持续时间百分位数分布(p50、p95、p99)、按路由分段的错误率以及每次调用的子请求计数。没有一个是脱离运行时的——它们需要构建、通过 Logpush 导出,并在目的地转变为警报。您信心十足地运营的服务与您担心投入生产的服务之间的区别几乎总是在于您在第一次事故发生之前构建的仪器的质量。

另请阅读

  • [生产中的 Cloudflare Workers:hello world 之后发生了什么变化42
  • [分布式系统中的可观察性:日志、指标和跟踪43
  • [超越日志的可观察性:OpenTelemetry 在实践中发生了什么变化44
  • [Workers + D1 + KV + R2:在同一服务中组合绑定45
  • [工人:CPU 和内存限制 - 文档没有很好地解释46
  • [测试 Workers:单元、集成以及如何在不依赖 Cloudflare 的情况下模拟运行时47