テック技報最新号へ →
インフラ

Workers のトレースで trace ID をレスポンスに返し、ルート名でスパンを付け直す(spanContext() / setStatus() / updateName())

@CFchangelog · 2026-10-28
#infra#cloudflare#workers#observability#opentelemetry#tracing

Workers のカスタムスパンが OpenTelemetry のスパン API を 3 つ追加でサポートした(2026-10-26)。エラー応答に trace ID を載せて問い合わせとトレースを突き合わせたり、ルーティング後に root スパンの名前を GET /users/:id のように付け直したりできる。

使いどころ

  • ユーザーから「500 が出た」と言われたとき、レスポンスやログに入っている trace ID から Workers Observability / 外部の OTel バックエンドの該当トレースへ直接飛びたい
  • root スパンの名前がどのリクエストも同じで、ルート単位で集計・検索しづらい
  • 例外を握りつぶしてフォールバック応答を返す処理でも、エクスポート先でエラーとして数えたい

追加された 3 つのメソッド

メソッドできること
span.spanContext()traceId / spanId / traceFlags を取得。Workers Observability やエクスポート先の ID と一致する
span.setStatus({ code, message? })"unset" / "ok" / "error" を設定。エラー時はメッセージも付けられる
span.updateName(name)開始後にスパン名を変更。tracing.getActiveSpan() で取れる呼び出しの root スパンにも使える

例

ts
import { tracing } from "cloudflare:workers";

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const root = tracing.getActiveSpan();
    const route = router.match(request);
    // ルートが決まった時点で root スパンの名前を付け直す
    root?.updateName(`${request.method} ${route.pattern}`);

    return tracing.startActiveSpan("handle", async (span) => {
      try {
        const res = await route.handler(request, env);
        span.setStatus({ code: "ok" });
        return res;
      } catch (err) {
        span.recordException(err as Error);
        span.setStatus({ code: "error", message: "Route handler failed" });
        // trace ID をクライアントに返して問い合わせ時に使ってもらう
        return Response.json(
          { error: "Internal error", traceId: root?.spanContext().traceId },
          { status: 500 },
        );
      } finally {
        span.end();
      }
    });
  },
};

注意点

出典

X の元の投稿を開く