目的
低レイテンシを実現するEdge層はトラブル時の再現が難しいため、観測性(Observability)を“最初から”組み込むことが重要です。本記事では実運用に必要な最小構成をコード例で提示します。
ベストマッチ
最短で課題解決する一冊
この記事の内容と高い親和性が確認できたベストマッチです。早めにチェックしておきましょう。
基本設計:W3C Trace Context+相関ID
- クライアント→エッジ→オリジンの全経路で
traceparentを伝播。 - ログはJSONで構造化し、
trace_id/span_id/correlation_idを必ず含める。 - デフォルトは低レベル(
info)+サンプリング、エラー時は詳細(debug/trace)。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
ミドルウェアで相関IDとtraceparentを付与
// middleware.ts
import { NextResponse } from 'next/server';
function newId() { return crypto.randomUUID(); }
export const config = { matcher: ['/((?!_next|favicon).*)'] };
export function middleware(req: Request) {
const url = new URL(req.url);
const requestId = req.headers.get('x-request-id') ?? newId();
const traceparent = req.headers.get('traceparent') ?? `00-${newId().replace(/-/g,'')}${newId().replace(/-/g,'').slice(0,16)}-01`;
const res = NextResponse.next();
res.headers.set('x-request-id', requestId);
res.headers.set('traceparent', traceparent);
// 上流へのfetchでもヘッダを使い回せるようにCookieへ(短期)
res.cookies.set('x_request_id', requestId, { path: '/', httpOnly: false });
res.cookies.set('traceparent', traceparent, { path: '/', httpOnly: false });
return res;
}さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
エッジRoute Handlerでの構造化ログ
// app/api/edge-log-demo/route.ts
export const runtime = 'edge';
type Log = { ts: string; level: 'info'|'error'; msg: string; trace_id: string; span_id?: string; attrs?: Record<string,unknown> };
function log(entry: Log) {
// 実運用では外部ログ収集エンドポイントへ送信(例)
console.log(JSON.stringify(entry));
}
export async function GET(req: Request) {
const trace = req.headers.get('traceparent') ?? '';
const traceId = trace.split('-')[1] ?? '';
log({ ts: new Date().toISOString(), level: 'info', msg: 'edge received', trace_id: traceId, attrs: { ua: req.headers.get('user-agent') } });
try {
const r = await fetch('https://example.com/api', { headers: { traceparent: trace } });
return new Response(await r.text(), { headers: { 'content-type': 'application/json' } });
} catch (e: any) {
log({ ts: new Date().toISOString(), level: 'error', msg: 'origin fetch failed', trace_id: traceId, attrs: { error: String(e) } });
return new Response(JSON.stringify({ ok: false }), { status: 502 });
}
}さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
サンプリングとPII対策
- 1%サンプルを常時収集、エラー時のみ100%収集(ダイナミックサンプリング)。
- PIIは送信前にマスク。メール/電話/住所は正規表現でフィルタ。
const SAMPLE_RATE = 0.01;
function shouldSample(status: number) { return status >= 500 || Math.random() < SAMPLE_RATE; }さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
メトリクスとSLO
- 成功率、p50/p95レイテンシ、タイムアウト率、オリジンへのフォールバック率を可視化。
- SLO逸脱時はNode Runtimeへフォールバックするルールを定義。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
チェックリスト
-
traceparent/x-request-idの伝播 - 構造化JSONログとPIIマスク
- 例外時の詳細ログとダイナミックサンプリング
- レイテンシ/成功率の可視化とSLO
- フォールバック戦略(Edge→Node→キャッシュ)
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
まとめ
観測性は“後付け”より“最初から”。最小限のトレース+構造化ログ+メトリクスで、エッジのデバッグ可能性と復旧速度を大幅に高められます。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
この記事をシェア
![はじめてでもここまでできる Stable Diffusion画像生成[本格]活用ガイド](https://m.media-amazon.com/images/I/51ZTahsGlKL._SL500_.jpg)


![Ansible実践ガイド 第4版[基礎編] impress top gearシリーズ](https://m.media-amazon.com/images/I/516W+QJKg1L._SL500_.jpg)

