cloudflare-workers-otel-utels について
Cloudflare Workers に OTLP テレメトリーと utels エラー追跡を追加する、2 つの TypeScript ラッパーです。OTLP の設定がなくても D1 の遅いクエリを記録でき、ハンドラーのコードを変えずに可観測性を加えたい Worker の開発者向けです。
主な機能
- 01OTLP のトレース、メトリクス、ログ
- 025xx と例外の utels イベント
- 03D1 クエリ時間と遅延ログ
- 04Worker ハンドラー用の合成可能なラッパー
- 05ルートとサービス属性のカスタマイズ
活用シーン
- 01新しい Worker への OTLP 可観測性の追加
- 02utels による Worker エラーの追跡
- 03Workers 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} ハンドラーを囲む、組み合わせ可能な2つのラッパーです。どちらも環境変数が設定されていない場合は何もせず、そのまま処理を通すため、どちらも使わない、一方だけ使う、または両方使うことができます。
withUtelsErrorTracking(withTelemetry(coreHandler))
withTelemetry—OTEL_EXPORTER_OTLP_*エンドポイントが1つでも設定されている場合、OTLP のトレース/メトリクス/ログを送信します。また、OTLP がなくても、すべての D1 バインディングを Proxy でラップし、ダッシュボードの Workers Logs にevent: "d1.slow_query"を記録します。これにより、新規デプロイ直後からスロークエリを確認できます。withUtelsErrorTracking— 5xx レスポンスまたは例外のスローごとにexceptionイベントを1件、utels.dev プロジェクトに送信します。エンドポイント、プロジェクト ID、取り込みトークンは環境変数で設定します。
呼び出すタイミング
次のような場合に使用します。
- 新しい Worker でオブザーバビリティを構築し、Honeycomb、Grafana Cloud、Tempo、Jaeger collector など、任意のバックエンドに OTLP 互換のトレースとメトリクスを送信したい場合。
- ハンドラーのコードを変更せずに、utels によるサーバーサイドのエラートラッキングを追加したい場合。
- スロークエリを調査する場合。しきい値の環境変数を設定し、ダッシュボードの Workers Logs を確認します。
内容
assets/scripts/telemetry-runtime.ts
このファイルと d1-wrap.ts をセットで src/ にコピーしてください。ランタイムは ./d1-wrap.ts をインポートします。withTelemetry と withUtelsErrorTracking をエクスポートし、Cloudflare Vite プラグインを通じて cf build によってバンドルされます。
プロジェクトごとにカスタマイズする主な箇所は次のとおりです。
DEFAULT_SERVICE_NAME— Worker 名に合わせます。EXACT_ROUTES—"unmatched"に正規化しないパスの一覧です。トップレベルのルートを追加します。routeForPath(pathname)—:id形式のパスパラメーターをまとめるよう拡張します。これを行わないと、カーディナリティの高いルート属性によってトレースとメトリクスのラベルのカーディナリティが急増します。
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 チェーン、スローしきい値、レコーダーの形式を検証します。テレメトリーのテストでは、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(),
};
ステージングには、モードごとのサービス名/プロジェクト名を指定します。ローカルのシークレット値は .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
argv やログに露出させずに utels への直接登録とシークレットの受け渡しを行う場合は、utels-project-bootstrap を使用してください。確認済みの cf beta にはライブログのストリーミング機能がありません。d1.slow_query イベントを調べるには、ダッシュボードの Workers Logs または OTLP バックエンドを使用してください。
OTEL_SDK_DISABLED=true または UTELS_DISABLED=true を指定すると、それぞれ個別に無効化できます。
スロークエリの独立性
withTelemetry は常に D1 バインディングを Proxy でラップします。OTLP が設定されていなくても、処理時間が APP_D1_SLOW_THRESHOLD_MS(デフォルトは 250ms)を超えるすべてのクエリは、構造化された console.warn として記録され、Workers Logs で確認できます。これは OTLP の設定とは独立して動作します。
参考資料
- telemetry-runtime.ts — OTLP エンコーダーと utels の例外ペイロードの構築。
- telemetry.test.ts — コピー先プロジェクトのビルド構成に合わせて調整できるペイロードのアサーション。
- cf configuration — バインディング、モード、シークレットの受け渡し。
ソース
ランタイムは、mizchi/cloudflare-starterkit-mbt と mizchi/mnemo をベースとしており、バンドルされたアセットに合わせて兄弟ディレクトリからのインポートを調整しています。