第26章: Workers Analytics Engine によるメトリクス集計(実践チュートリアル)
APIのレスポンスタイム、アクセス元国、ユーザーの行動イベントをリレーショナルDB(D1やPostgres)に毎秒何万件も書き込むと、DBの書き込み上限に達してクラッシュしてしまいます。 Workers Analytics Engine は、高スループットな時系列テレメトリデータをエッジから直接書き込めるように設計された専用分析基盤です。
本チュートリアルのゴール
wrangler.jsoncでの Analytics Engine データセットの有効化- Workers からの非同期データポイント書き込み(
writeDataPoint) - Cloudflare SQL API を叩き、時系列集計クエリを実行してダッシュボード用のJSONを取得
【データフロー】[ エッジWorkers (秒間10,000リクエスト) ] │ writeDataPoint (非ブロッキング・超高速書き込み) ▼[ Workers Analytics Engine (時系列データレイク) ] │ SQLクエリ (avg(double1), count(), group by) ▼[ 管理画面ダッシュボード / Grafana / API ]Step 1: wrangler.jsonc の設定
データセット名(例: api_performance)をバインドします。
{ "name": "telemetry-service", "main": "src/index.ts", "compatibility_date": "2024-09-01", "analytics_engine_datasets": [ { "binding": "METRICS", "dataset": "api_performance" } ]}型定義を更新します。
npx wrangler typesStep 2: メトリクス収集ミドルウェアの実装(src/index.ts)
すべてのAPIリクエストのレイテンシ、ステータスコード、国コードを自動記録します。
import { Hono } from 'hono';
type Bindings = { METRICS: AnalyticsEngineDataset;};
const app = new Hono<{ Bindings: Bindings }>();
// 1. メトリクス収集ミドルウェアapp.use('*', async (c, next) => { const startTime = Date.now();
// 次のハンドラーを実行 await next();
const durationMs = Date.now() - startTime; const status = c.res.status; const path = c.req.path; const method = c.req.method; const country = c.req.header('cf-ipcountry') || 'XX';
// Analytics Engine へデータポイントを書き込み(処理速度に一切影響を与えません) c.env.METRICS.writeDataPoint({ // 文字列データ(blobs: 最大20個まで) blobs: [ method, // blob1: HTTPメソッド path, // blob2: リクエストパス country, // blob3: 国コード ], // 数値データ(doubles: 最大20個まで、集計対象) doubles: [ durationMs, // double1: レイテンシ(ms) status, // double2: HTTPステータス ], // インデックスキー(サンプリングやグループ化用) indexes: [method], });});
// サンプルAPIエンドポイントapp.get('/api/products', (c) => c.json([{ id: 1, name: '商品A' }]));app.get('/api/orders', (c) => c.json([{ id: 101, amount: 2500 }]));
export default app;Step 3: SQL APIによるリアルタイム集計クエリの実行
CloudflareのAnalytics Engineは、専用のSQLエンドポイントを提供しています。ターミナルから curl で集計結果を取得してみます。
# アカウントIDとAPIトークンを設定ACCOUNT_ID="your-cloudflare-account-id"API_TOKEN="your-api-token"
# 直近24時間のエンドポイント別リクエスト数と平均レスポンス時間を集計curl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/analytics_engine/sql" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Content-Type: text/plain" \ -d " SELECT blob2 AS endpoint, count() AS total_hits, round(avg(double1), 2) AS avg_duration_ms, max(double1) AS max_duration_ms FROM api_performance WHERE timestamp > NOW() - INTERVAL '1' DAY GROUP BY endpoint ORDER BY total_hits DESC LIMIT 5; "出力例(JSON):
{ "data": [ { "endpoint": "/api/products", "total_hits": 45200, "avg_duration_ms": 12.45, "max_duration_ms": 184.0 }, { "endpoint": "/api/orders", "total_hits": 8900, "avg_duration_ms": 28.10, "max_duration_ms": 320.0 } ]}自前でPrometheusやDatadogを立ち上げることなく、わずか数行のコードでエンタープライズ規模の時系列メトリクス集計基盤が完成します。
まとめ
- 高スループット: 大量アクセス時もDBと違ってロックや接続制限の心配がゼロ。
- 標準SQL互換:
avg(),count(),quantile()などの強力な集計関数でダッシュボードを即座に構築可能。
💡 用語解説コラム
[!NOTE] テレメトリ (Telemetry)
遠隔のシステムからパフォーマンスデータや稼働状態、エラー情報を自動収集して集約・送信する仕組み。
[!NOTE] 時系列データベース (Time Series DB)
時間の経過に沿って発生するデータ(アクセス数、CPU使用率、センサー値等)の記録・集計に特化したデータベース。