关于 cloudflare-workers-otel-utels
这组 TypeScript 包装器为 Cloudflare Workers 添加可选的 OTLP 遥测和 utels 错误跟踪,即使未配置 OTLP,也会记录 D1 慢查询。适合希望不改处理器代码即可加入可观测性的 Worker 维护者。
主要功能
- 01OTLP 链路、指标和日志
- 02为 5xx 和异常发送 utels 事件
- 03D1 查询计时与慢查询日志
- 04可组合的 Worker 处理器包装器
- 05自定义路由和服务属性
适用场景
- 01为新 Worker 添加 OTLP 可观测性
- 02通过 utels 跟踪 Worker 错误
- 03在 Workers Logs 中排查 D1 慢查询
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mizchi/ skills --skill cloudflare-workers-otel-utels安装后在 Claude Code 中输入/cloudflare-workers-otel-utels确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdassets/scripts/d1-wrap.tstelemetry-runtime.tsassets/tests/d1-wrap.test.tstelemetry.test.ts详细介绍
Cloudflare Workers OTel + utels 边界
两个包装器围绕 Worker 的 {fetch, scheduled} 处理程序组合使用。除非存在相应的环境变量,否则两者都只是空操作式透传;因此可以两个都不使用、只用一个,或同时使用。
withUtelsErrorTracking(withTelemetry(coreHandler))
withTelemetry— 配置任意OTEL_EXPORTER_OTLP_*端点后,即会推送 OTLP traces / metrics / logs。它还会用 Proxy 包装每个 D1 绑定,并在仪表板的 Workers Logs 中记录event: "d1.slow_query",即使没有 OTLP 也会记录,因此全新部署后也能查看慢查询。withUtelsErrorTracking— 每个 5xx 响应或抛出的异常都会向 utels.dev 项目推送一个exception事件。端点、项目 ID 和摄取令牌均通过环境变量配置。
何时使用
适用于以下情况:
- 为新的 Worker 搭建可观测性,希望将兼容 OTLP 的 traces 和 metrics 发送到任意后端(Honeycomb、Grafana Cloud、Tempo、Jaeger collector,……)。
- 添加基于 utels 的服务端错误跟踪,而不更改处理程序代码。
- 排查慢查询:设置阈值环境变量,然后在仪表板的 Workers Logs 中查看。
内容
assets/scripts/telemetry-runtime.ts
将此文件和 d1-wrap.ts 一起复制到 src/;runtime 会导入 ./d1-wrap.ts。该文件导出 withTelemetry 和 withUtelsErrorTracking,并通过 Cloudflare Vite 插件由 cf build 打包。
各项目需要自定义的重点:
DEFAULT_SERVICE_NAME— 与你的 Worker 名称保持一致。EXACT_ROUTES— 不应规范化为"unmatched"的路径集合。添加你的顶层路由。routeForPath(pathname)— 扩展此函数以折叠:id样式的路径参数。如果不处理,高基数的路由属性会导致 trace 和 metric 标签基数暴增。
assets/scripts/d1-wrap.ts
D1 Proxy 包装器。独立运行。它会在 prepare → bind 链中传递 SQL 模板,确保最终终端操作(first / run / all / raw)记录正确的语句。会记录 bindingName、op、sql、durationMs、ok。类型定义严格,可安全地用作其余遥测管线的类型入口。
导出 Recorder = (query: RecordedQuery) => void,如果你采用了不同的聚合方式,可以将其接入捆绑的 withTelemetry 以外的其他实现。
assets/tests/d1-wrap.test.ts 和 telemetry.test.ts
参考测试。d1-wrap 测试使用模拟 D1 绑定验证 Proxy 链、慢查询阈值和 recorder 数据结构。telemetry 测试断言 5xx 响应和抛出的异常都会生成 utels 事件。
接入
// src/worker.ts
import { withTelemetry, withUtelsErrorTracking } from "./telemetry-runtime.ts";
const coreHandler = { fetch(req, env, ctx) { /* ... */ } };
const fetchHandler = withUtelsErrorTracking(withTelemetry(coreHandler));
export default {
fetch: fetchHandler.fetch,
};
// cloudflare.config.ts: merge these into worker.env.
import { bindings } from "cf/config";
const telemetryBindings = {
OTEL_SERVICE_NAME: bindings.text("my-app"),
OTEL_SERVICE_VERSION: bindings.text("0.1.0"),
DEPLOY_ENV: bindings.text("production"),
UTELS_ENDPOINT: bindings.text("https://utels.dev/__utels?v=1"),
UTELS_PROJECT_ID: bindings.text("my-app-prod"),
UTELS_RELEASE: bindings.text("0.1.0"),
// Declare only the secrets for enabled integrations:
// OTEL_EXPORTER_OTLP_ENDPOINT: bindings.secret(),
// OTEL_EXPORTER_OTLP_HEADERS: bindings.secret(),
// UTELS_INGEST_TOKEN: bindings.secret(),
};
为 staging 选择与模式对应的服务名称和项目名称。在 .dev.vars 中提供本地密钥值;部署值应放在已忽略的 JSON 或 dotenv 文件中。部署验证时必须提供已声明的密钥绑定。使用 dotenvx 解密到 CLI 进程中的值不会自动成为 Worker 绑定。
pnpm exec cf workers types
pnpm exec cf deploy --dry-run --secrets-file .env.production
pnpm exec cf deploy --secrets-file .env.production
如需直接注册 utels 并传递密钥,同时避免密钥暴露在 argv 或日志中,请使用 utels-project-bootstrap。已检查的 cf beta 不支持实时日志流;请使用仪表板中的 Workers Logs 或 OTLP 后端检查 d1.slow_query 事件。
可分别使用 OTEL_SDK_DISABLED=true 或 UTELS_DISABLED=true 禁用对应功能。
慢查询独立运行
withTelemetry 始终会用 Proxy 包装 D1 绑定。即使未配置 OTLP,每个耗时超过 APP_D1_SLOW_THRESHOLD_MS(默认 250ms)的查询都会以结构化的 console.warn 形式记录,并可在 Workers Logs 中查看。此功能独立于 OTLP 配置运行。
参考资料
- telemetry-runtime.ts — OTLP 编码器和 utels 异常载荷构造。
- telemetry.test.ts — 可根据复制后项目的构建布局调整的载荷断言。
- cf 配置 — 绑定、模式和密钥传递。
来源
运行时基于 mizchi/cloudflare-starterkit-mbt 和 mizchi/mnemo,并调整了同级导入以适配捆绑的资源。