Rails 8.1 Structured Event Reporter(Rails.event)+ OpenTelemetry + CloudWatch の統合デモ。
OTelの3シグナル(Traces, Logs, Metrics)を同時稼働させ、CloudWatchで確認できる構成を実現する。
Rails 8.1 アプリ ──OTLP──▶ OTel Collector ──SigV4──▶ CloudWatch
├─ Traces(自動計装) ├─ X-Ray(Traces)
├─ Logs(EventReporter→OTel Logs API) ├─ CloudWatch Logs(Logs)
└─ Metrics(Counter/Histogram) └─ CloudWatch Metrics(Metrics)
| コンテナ | 役割 | ポート |
|---|---|---|
| web | Rails アプリ + OTel SDK | 3000 |
| db | PostgreSQL | 5432 |
| otel-collector | ADOT Collector | 4317(gRPC), 4318(HTTP) |
- Docker, Docker Compose
- AWSアカウント(CloudWatchへの送信に必要)
OTel CollectorがCloudWatchにテレメトリを送信するため、以下の権限を持つIAMユーザーまたはロールが必要。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:UpdateTraceSegmentDestination",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"cloudwatch:PutMetricData"
],
"Resource": "*"
}
]
}X-RayのOTLPエンドポイント経由でトレースを送信するには、トレースの保存先をCloudWatch Logsに設定する必要がある。
まず、X-Rayサービスがaws/spansロググループに書き込めるよう、CloudWatch Logsのリソースポリシーを設定する。ACCOUNT_IDとREGIONは環境に合わせて置き換える。
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION=$(aws configure get region)
aws logs put-resource-policy \
--policy-name XRayLogAccess \
--policy-document "{
\"Version\": \"2012-10-17\",
\"Statement\": [
{
\"Sid\": \"TransactionSearchXRayAccess\",
\"Effect\": \"Allow\",
\"Principal\": {
\"Service\": \"xray.amazonaws.com\"
},
\"Action\": \"logs:PutLogEvents\",
\"Resource\": [
\"arn:aws:logs:${REGION}:${ACCOUNT_ID}:log-group:aws/spans:*\",
\"arn:aws:logs:${REGION}:${ACCOUNT_ID}:log-group:/aws/application-signals/data:*\"
],
\"Condition\": {
\"ArnLike\": {
\"aws:SourceArn\": \"arn:aws:xray:${REGION}:${ACCOUNT_ID}:*\"
},
\"StringEquals\": {
\"aws:SourceAccount\": \"${ACCOUNT_ID}\"
}
}
}
]
}"次に、トレースの保存先をCloudWatch Logsに切り替える。
aws xray update-trace-segment-destination --destination CloudWatchLogsデフォルトではトレースのインデキシング率が1%のため、デモ用途では100%に変更する。
aws xray update-indexing-rule --name Default \
--rule '{"Probabilistic": {"DesiredSamplingPercentage": 100}}'これらの設定はリージョンごとに1回だけ実行すればよい。
トレースの確認は CloudWatch → X-Ray traces → Traces(Transaction Search)で行う。aws/spansロググループに保存されたトレースが検索対象となる。
参考: Enable transaction search - Amazon CloudWatch
EventReporterイベントの送信先となるロググループとログストリームを事前に作成する。
aws logs create-log-group --log-group-name /otel/bookstore-demo
aws logs create-log-stream --log-group-name /otel/bookstore-demo --log-stream-name eventsCloudWatch Metrics OTLPエンドポイントは以下の5リージョンでPublic Preview(2026年4月時点)。
- us-east-1, us-west-2, ap-southeast-1, ap-southeast-2, eu-west-1
Traces(X-Ray)とLogs(CloudWatch Logs)のOTLPエンドポイントはGA済みで、他のリージョンでも利用可能。3シグナル全てを動作させるには上記5リージョンのいずれかを選択する。
.env.exampleをコピーして.envを作成し、AWSの認証情報を記入する。
cp .env.example .env# .env
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=ap-southeast-1Docker Composeは.envファイルを自動的に読み込む。
# コンテナ起動
docker compose up -d
# DB作成・マイグレーション
docker compose exec web bin/rails db:create db:migrate
# シードデータ投入
docker compose exec web bin/rails db:seedhttp://localhost:3000 でアプリにアクセスできる。
docker compose run --rm \
-e RAILS_ENV=test \
-e DATABASE_URL=postgres://postgres:password@db:5432/bookstore_otel_demo_test \
web bin/rails db:create db:migrate test任意のページ操作でTraceが生成される。
操作: ブラウザで http://localhost:3000/books にアクセス
CloudWatch確認手順:
- AWSコンソール → CloudWatch → X-Ray traces → Traces
- Service Map または Trace一覧にて
bookstore-otel-demoサービスのSpanを確認 - 各TraceにはController(Action Pack)、DBクエリ(Active Record)、View(Action View)のSpanがネストされている
4種のビジネスイベントがLog Recordとして送信される。
操作: 書籍の詳細ページを開く(例: http://localhost:3000/books/1)
ペイロード: book_id, title
操作: 注文を作成する
- http://localhost:3000/orders/new を開く
- 書籍と数量を選択して「注文を確定する」をクリック
ペイロード:
order.created:order_number,book_id,quantity,total_amountinventory.low(残在庫5以下の場合のみ):book_id,remaining_stock
操作: 注文一覧からステータスを進める
- http://localhost:3000/orders を開く
- pending状態の注文の「pending → confirmed」ボタンをクリック
ペイロード: order_number, from_status, to_status
CloudWatch確認手順:
- AWSコンソール → CloudWatch → Logs → Log groups
- OTel Collectorが自動作成するロググループを確認(
/aws/otelや サービス名ベースのグループ) - Log eventsを開き、bodyフィールドにイベント名(例:
order.created)、attributesにペイロードが含まれていることを確認 - 各Log Recordの
trace_id/span_idがX-RayのTrace IDと一致することを確認 — これによりTraceとLogの関連付けが機能していることがわかる
注文作成時にメトリクスが記録される。
操作: 注文を複数回作成する(異なる書籍・数量で)
CloudWatch確認手順:
- AWSコンソール → CloudWatch → Metrics → All metrics
- カスタム名前空間を探す(OTel Collectorのデフォルト名前空間)
- 以下のメトリクスを確認:
orders.created(Counter) — 注文ごとに1ずつ増加orders.amount(Histogram) — 注文金額の分布
EventReporterイベントのLog RecordにはOTel SDKが自動的にtrace_idとspan_idを付与する。
- CloudWatch Logsでイベントの
trace_idをコピー - X-Ray TracesでそのTrace IDを検索
- 該当リクエストのTrace配下にController Spanが存在し、そのSpan内で発行されたイベントであることが確認できる
opentelemetry-instrumentation-all(use_all)による自動計装。
| Span | 計装元 |
|---|---|
| HTTPリクエスト処理 | Action Pack |
| DBクエリ | Active Record / PG |
| ビューレンダリング | Action View |
| メール送信 | Action Mailer |
| バックグラウンドジョブ | Active Job |
| イベント | タイミング | ペイロード |
|---|---|---|
book.viewed |
書籍詳細表示 | book_id, title |
order.created |
注文作成 | order_number, book_id, quantity, total_amount |
order.status_changed |
ステータス変更 | order_number, from_status, to_status |
inventory.low |
在庫5以下 | book_id, remaining_stock |
| メトリクス | 種別 | 単位 | タイミング |
|---|---|---|---|
orders.created |
Counter | {orders} | 注文作成時 |
orders.amount |
Histogram | JPY | 注文作成時 |
- Ruby 4.0.2 / Rails 8.1.3
- PostgreSQL 17
- OpenTelemetry SDK 1.11.0
- OpenTelemetry Logs SDK 0.5.0(Development)
- OpenTelemetry Metrics SDK 0.13.0(Development)
- AWS Distro for OpenTelemetry Collector(ADOT)