監視ツールを入れるたびに、ベンダー固有のSDKを追加で組み込んでいませんか。
X-Rayのトレース、DatadogのAPM、PrometheusのExporter——それぞれ個別に設定していると、移行コストがどんどん膨らみます。特定のクラウドやツールに深く依存した監視構成は、将来の選択肢を狭めるリスクがあります。
OpenTelemetry(OTel) は、このベンダーロックイン問題を解消するための業界標準です。一度SDKを組み込めば、送り先をCloudWatch・X-Ray・Prometheus・Datadogなど複数のバックエンドに切り替えられます。
この記事では、OpenTelemetryの基本概念から、AWSが提供する AWS Distro for OpenTelemetry(ADOT) を使ったCloudWatch連携の具体的な手順まで解説します。
この記事でわかること
– OpenTelemetryの基本概念(API・SDK・Collectorの役割)
– AWS Distro for OpenTelemetry(ADOT)の特徴
– ADOTコレクターでCloudWatchにメトリクスを送信する設定手順
– X-Rayへのトレース送信方法
– 本番環境でのコスト管理とベストプラクティス
前提条件: AWS基礎知識(IAM・EC2・ECS/EKSのいずれかの操作経験)があると理解しやすい内容です。

OpenTelemetryとは何か
OpenTelemetry(OTel)は、アプリケーションの テレメトリデータ(メトリクス・ログ・トレース) を収集・処理・エクスポートするためのオープンソースのフレームワークです。Cloud Native Computing Foundation(CNCF)のプロジェクトとして、Google・Microsoft・Datadogなど主要企業が共同開発しています。
なぜOpenTelemetryが生まれたのか
OTelが生まれる以前、オブザーバビリティ領域にはOpenTracingとOpenCensusという2つの競合標準が存在していました。両者は設計思想が異なり、開発者はどちらを選ぶか迷う状況が続いていました。
2019年、この2プロジェクトが統合して誕生したのがOpenTelemetryです。現在は CNCFのインキュベーティングプロジェクト として、事実上の業界標準になっています。
OTelが解決する最大の問題は ベンダーロックイン です。DatadogやNew Relicなど各社のAPMエージェントを直接組み込むと、移行時にコードの大規模修正が必要になります。OTelを挟むことで、送り先のバックエンドを切り替えてもアプリケーションコードは変更不要になります。
OTelの3つのシグナル
OpenTelemetryが扱うテレメトリデータは、以下の3種類(シグナル)に分類されます。
| シグナル | 内容 | AWSでの受け取り先例 |
|---|---|---|
| メトリクス | CPU使用率・リクエスト数・レイテンシなどの数値データ | CloudWatch, Amazon Managed Service for Prometheus |
| ログ | アプリケーションのイベントログ・構造化ログ | CloudWatch Logs |
| トレース | リクエストが複数サービスをまたぐ処理の追跡データ | AWS X-Ray |
これまで別々のツールで収集していた3種類のデータを、OTelは統一的な方法で扱えます。これにより、「エラーが発生したときのメトリクス・ログ・トレースを同時に確認する」という相関分析が現実的になります。
API・SDK・Collectorの3コンポーネント
OpenTelemetryは以下の3つのコンポーネントで構成されています。
graph TD A["アプリケーション (Java/Python/Node.js等)"] B["OTel API / SDK (計装・データ生成)"] C["OTel Collector (受信・処理・エクスポート)"] D["CloudWatch (メトリクス・ログ)"] E["AWS X-Ray (トレース)"] F["Amazon Managed Service for Prometheus"] A --> B --> C C --> D C --> E C --> F
- API: 計装(テレメトリデータの生成)のためのインターフェース定義。特定の実装に依存しない
- SDK: APIの実装。データのサンプリング・処理・エクスポートを担当
- Collector: テレメトリデータの受信・変換・転送を行うプロキシ。アプリとバックエンドの間に置くことで、バックエンドの切り替えをアプリ側に影響なく行える
AWS Distro for OpenTelemetry(ADOT)とは
AWS Distro for OpenTelemetry(ADOT)は、AWSがOpenTelemetryプロジェクトのコンポーネントを AWS向けに最適化・サポートを付けて 配布するディストリビューションです。
オープンソースのOTelそのものを使うことも可能ですが、ADOTを使うとAWSサービスとのインテグレーションがより簡単になります。
ADOTの主な特徴
- AWS認証(SigV4)の自動サポート: CloudWatchやX-Rayへの認証設定がシンプル
- マネージドコレクター: EKSではAdd-Onとして、Lambdaではマネージドレイヤーとして利用可能
- AWSサポート対象: OSSのアップストリームに追随しつつ、AWSが品質保証・セキュリティパッチを提供
ADOTがサポートする主なエクスポート先
| エクスポート先 | データ種別 | 用途 |
|---|---|---|
| Amazon CloudWatch | メトリクス・ログ(EMF形式) | 既存のCW監視に統合 |
| AWS X-Ray | トレース | 分散トレーシングの可視化 |
| Amazon Managed Service for Prometheus | メトリクス | Grafanaでの可視化 |
| Amazon OpenSearch Service | ログ・トレース | 高度な全文検索・分析 |
X-RayとOpenTelemetryの関係
従来のX-Ray SDKとADOTは 共存できます 。既存システムにX-Ray SDKを組み込んでいる場合、段階的にADOTへ移行することが可能です。
ADOTでトレースを収集してX-Rayに送信することで、X-Rayのサービスマップ・分析コンソールをそのまま活用できます。X-Rayについては「AWS X-Rayとは?分散トレーシングの仕組みと設定手順」でも詳しく解説しています。

OpenTelemetryをCloudWatchと連携する手順
ADOTコレクターを使って、アプリのメトリクスをCloudWatchに送信する手順を解説します。
全体構成の概要
graph TD A["アプリケーション (OTel SDK組み込み済み)"] B["ADOTコレクター (EC2/ECS/EKSで動作)"] C["CloudWatch (EMFメトリクス)"] D["AWS X-Ray (トレース)"] E["IAMロール (認証)"] A -->|"OTLP (4317)"| B B -->|"EMF形式"| C B -->|"X-Ray形式"| D E -.->|"認証"| B
ADOTコレクターは OTLP(OpenTelemetry Protocol) でアプリからデータを受け取り、CloudWatchにはEMF(Embedded Metric Format)形式で、X-Rayにはトレースデータとして転送します。
Step 1: IAMロールの設定
ADOTコレクターがCloudWatchとX-Rayにデータを送信するために、以下のIAMポリシーをアタッチします。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:PutMetricData",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:GetSamplingRules",
"xray:GetSamplingTargets",
"xray:GetSamplingStatisticSummaries"
],
"Resource": "*"
}
]
}
EC2の場合はインスタンスプロファイル、ECSの場合はタスクロール、EKSの場合はIRSA(IAM Roles for Service Accounts)に上記ポリシーをアタッチしてください。
Step 2: ADOTコレクターの設定(EMFエクスポーター)
ADOTコレクターの設定ファイル(otel-config.yaml)を作成します。ここではCloudWatch EMFエクスポーターとX-Rayエクスポーターを同時に設定します。
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 30s
send_batch_size: 8192
exporters:
# CloudWatchメトリクス(EMF形式)
awsemf:
region: ap-northeast-1
log_group_name: /otel/metrics
log_stream_name: app-metrics
namespace: MyApp/Metrics
dimension_rollup_option: "NoDimensionRollup"
# AWS X-Rayトレース
awsxray:
region: ap-northeast-1
local_mode: false
service:
pipelines:
# メトリクスパイプライン
metrics:
receivers: [otlp]
processors: [batch]
exporters: [awsemf]
# トレースパイプライン
traces:
receivers: [otlp]
processors: [batch]
exporters: [awsxray]
namespace はCloudWatchのカスタムメトリクス名前空間に対応します。チームやサービス名で整理すると運用しやすくなります。
Step 3: アプリケーションのSDK設定(Python例)
Pythonアプリにて、OTel SDKを使ってメトリクスとトレースを計装する例です。
from opentelemetry import trace, metrics
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
# トレース設定
tracer_provider = TracerProvider()
tracer_provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(endpoint="http://localhost:4317")
)
)
trace.set_tracer_provider(tracer_provider)
# メトリクス設定
metric_reader = PeriodicExportingMetricReader(
OTLPMetricExporter(endpoint="http://localhost:4317"),
export_interval_millis=30000 # 30秒ごとにエクスポート
)
meter_provider = MeterProvider(metric_readers=[metric_reader])
metrics.set_meter_provider(meter_provider)
# 計装例
tracer = trace.get_tracer(__name__)
meter = metrics.get_meter(__name__)
# カスタムメトリクスの定義
request_counter = meter.create_counter(
"http.requests.total",
description="HTTPリクエストの総数",
unit="1"
)
def handle_request(path: str):
with tracer.start_as_current_span("handle_request") as span:
span.set_attribute("http.path", path)
request_counter.add(1, {"path": path})
# 処理...
エンドポイント http://localhost:4317 がADOTコレクターを指しています。アプリはOTLPでコレクターに送り、コレクターがCloudWatchとX-Rayに振り分けます。
Step 4: ADOTコレクターをDockerで起動する(EC2の場合)
# ADOTコレクターのDockerイメージを起動
docker run \
--rm \
-p 4317:4317 \
-p 4318:4318 \
-v $(pwd)/otel-config.yaml:/etc/otel-agent-config.yaml \
--name adot-collector \
amazon/aws-otel-collector:latest \
--config=/etc/otel-agent-config.yaml
EKSの場合はAdd-Onとして以下のコマンドでインストールできます。
# EKS Add-OnとしてADOTをインストール
aws eks create-addon \
--cluster-name <クラスター名> \
--addon-name adot \
--region ap-northeast-1
本番運用でのベストプラクティス
サンプリングレートの設計
トレースのサンプリング(どの割合のリクエストをトレースするか)は、コストと可観測性のトレードオフです。
| 環境 | 推奨サンプリングレート | 理由 |
|---|---|---|
| 開発・ステージング | 100% | すべて記録してデバッグしやすく |
| 本番(低トラフィック) | 100%〜50% | トレースの見落としを防ぐ |
| 本番(高トラフィック) | 5%〜10% | X-Ray料金を抑えつつ異常を検知 |
OTelコレクターの tail_sampling プロセッサーを使うと、エラーが発生したリクエストは100%サンプリングし、正常リクエストは間引くという テールサンプリング が実現できます。
processors:
tail_sampling:
decision_wait: 10s
policies:
- name: error-policy
type: status_code
status_code: {status_codes: [ERROR]}
- name: probabilistic-policy
type: probabilistic
probabilistic: {sampling_percentage: 10}
CloudWatchのカスタムメトリクス料金については、「CloudWatch入門|SREが最初に設定すべき5つの機能」で詳しく解説しています。
Prometheusとのハイブリッド構成
EKS環境では、OTelコレクターでPrometheusメトリクスをスクレイプし、 Amazon Managed Service for Prometheus(AMP) に送ることができます。GrafanaダッシュボードとCloudWatchを並用するハイブリッド構成も現実的です。
receivers:
prometheus:
config:
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
exporters:
prometheusremotewrite:
endpoint: "https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/<ID>/api/v1/remote_write"
auth:
authenticator: sigv4auth
ベンダーロックイン回避の考え方
OTelを導入するとき、送り先(バックエンド)はいつでも変えられる という設計にしておくことが重要です。
具体的には以下の点を意識します。
- アプリコードには OTel APIのみ を参照させ、SDK実装を直接呼び出さない
- コレクターの設定ファイルで送り先を管理し、アプリ側の変更なしに切り替えられるようにする
- SLIの算出には、特定ツールのクエリ言語ではなくOTel標準のメトリクス名を使う
SLI・SLOの設計については「CloudWatch SLI/SLO設計入門|Application Signalsでエラーバジェットを管理する方法」も参考にしてください。

よくあるエラーとトラブルシューティング
テレメトリデータがCloudWatchに届かない
症状: コレクターを起動したが、CloudWatchのカスタムメトリクスに何も表示されない。
確認手順:
- コレクターのログを確認する
docker logs adot-collector 2>&1 | grep -E "error|warn|exported"
- ネットワーク疎通を確認する
# CloudWatchへの接続確認
curl -I https://monitoring.ap-northeast-1.amazonaws.com
- メトリクスの反映には最大2〜3分かかる場合があります。CloudWatchコンソールで カスタム名前空間 を確認してください。
IAM権限エラー
症状: AccessDeniedException または UnauthorizedException がコレクターログに出力される。
確認ポイント:
# EC2インスタンスプロファイルの確認
aws sts get-caller-identity
# 必要なポリシーがアタッチされているか確認
aws iam list-attached-role-policies --role-name <ロール名>
ECSの場合はタスク定義の executionRoleArn と taskRoleArn の両方を確認してください。テレメトリの送信には taskRoleArn に権限が必要です。
EMFメトリクスが表示されない場合
症状: コレクターのログにエラーはないが、CloudWatch Metricsにカスタムメトリクスが現れない。
主な原因:
namespaceの設定ミス → CloudWatchコンソールで正しい名前空間を確認- ディメンションの不一致 → EMF設定の
dimension_rollup_optionを"NoDimensionRollup"から変更してみる - ログが
log_group_nameに書き込まれているか → CloudWatch Logsで生のEMFログを確認
# EMFログの確認
aws logs filter-log-events \
--log-group-name /otel/metrics \
--start-time $(date -d "10 minutes ago" +%s000) \
--query "events[*].message" \
--output text | head -5
EMF形式のログが届いていれば、数分後にCloudWatch Metricsに反映されます。
まとめ
OpenTelemetryとADOTを活用したCloudWatch連携のポイントをまとめます。
- OpenTelemetry はベンダーに依存しないオブザーバビリティの業界標準。API/SDK/Collectorの3層構成でデータを収集・転送する
- ADOT はAWSがOpenTelemetryをAWS向けに最適化したディストリビューション。CloudWatch・X-Ray・Prometheusへの送信に対応
- 連携手順 は「IAMロール設定 → コレクター設定(EMF/X-Rayエクスポーター) → アプリSDK組み込み」の3ステップ
- 本番運用 では テールサンプリングでコストを最適化し、コレクター設定でバックエンドを切り替えられる設計にする
CloudWatchとOpenTelemetryを組み合わせることで、既存のCloudWatch資産を活かしながら、将来的にPrometheusやDatadogへ移行しやすい 構成が作れます。
OTelの概念理解から実務でのAWS監視設計まで、体系的に学びたい方には Udemyのコース「AWS×SRE入門」 も参考にしてみてください。ハンズオン形式でCloudWatch・X-Ray・ADOTの設定を実際に手を動かして学べます。

コメント