OpenTelemetryとは?AWS CloudWatchとの連携方法をSRE視点で解説

AWS監視・オブザーバビリティ

監視ツールを入れるたびに、ベンダー固有の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 logo with AWS cloud icons, observability pipeline diagram, data flowing from applicati

OpenTelemetryとは何か

OpenTelemetry(OTel)は、アプリケーションの テレメトリデータ(メトリクス・ログ・トレース) を収集・処理・エクスポートするためのオープンソースのフレームワークです。Cloud Native Computing Foundation(CNCF)のプロジェクトとして、Google・Microsoft・Datadogなど主要企業が共同開発しています。

なぜOpenTelemetryが生まれたのか

OTelが生まれる以前、オブザーバビリティ領域にはOpenTracingとOpenCensusという2つの競合標準が存在していました。両者は設計思想が異なり、開発者はどちらを選ぶか迷う状況が続いていました。

2019年、この2プロジェクトが統合して誕生したのがOpenTelemetryです。現在は CNCFのGraduatedプロジェクト(2024年2月に卒業認定)として、事実上の業界標準になっています。

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へ移行することが可能です。

補足: AWS X-Ray SDKは2026年2月25日にmaintenance modeへ移行しました(公式アナウンス済み)。新規実装にはADOTの使用が推奨されています。

ADOTでトレースを収集してX-Rayに送信することで、X-Rayのサービスマップ・分析コンソールをそのまま活用できます。X-Rayについては「AWS X-Rayとは?分散トレーシングの仕組みと設定手順」でも詳しく解説しています。


ADOT collector architecture with multiple receivers and exporters, showing AWS cloud services as exp

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",
        "logs:DescribeLogGroups"
      ],
      "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: 1s          # AWS公式ブログ推奨値(2025年7月)。5s以上にすると送信遅延が発生するため注意
    send_batch_size: 1024 # 1回に送るスパン数。大きすぎるとメモリ圧迫につながる

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アプリの計装には、自動計装(ADOT推奨)手動計装(細かい制御が必要な場合) の2パターンがあります。

① 自動計装(ADOT推奨)

コードを一切変更せずに計装できます。aws-opentelemetry-distro パッケージをインストールし、起動コマンドを opentelemetry-instrument で包むだけです。

pip install aws-opentelemetry-distro
opentelemetry-bootstrap --action=install

# 環境変数でCollectorエンドポイントを指定して起動
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
export OTEL_RESOURCE_ATTRIBUTES="service.name=my-app"
export OTEL_PYTHON_DISTRO=aws_distro
export OTEL_PYTHON_CONFIGURATOR=aws_configurator

opentelemetry-instrument python app.py

Django・Flask・FastAPI・boto3など主要フレームワークのスパンが自動で生成されます。まずはこちらから試すことを推奨します。

② 手動計装(カスタムスパンが必要な場合)

ビジネスロジック独自のスパンやメトリクスを追加したい場合は、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
)
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の場合、デプロイ方式によってcert-managerの要否が変わります

EKS構成 推奨デプロイ方式 Fargate対応 cert-manager 用途
EC2ノード DaemonSet 不要 ノードごとにコレクター配置
EC2ノード(Operator利用) ADOT Operator Add-On 必要(admission webhook) Operatorによる自動サイドカーインジェクション
Fargate 中央集権型(StatefulSet/Deployment) 推奨 不要 1台のコレクターで全Podのテレメトリを集約
EC2 / Fargate(シンプル構成) Collector-less 不要 コレクター不要・SDKから直接OTLPエンドポイントへ送信

補足: Fargate環境ではDaemonSetが使えません。コレクターが必要な場合は 中央集権型(Deployment/StatefulSet 1台) でコレクターPodを立て、全アプリPodからOTLPで集約する方式が推奨です(AWS公式ブログ 2025年7月でも採用されている構成)。コレクター不要の場合は Collector-less方式 でSDKからOTLPエンドポイントへ直送できます。どちらもSigV4認証はIRSAで処理され、cert-managerは不要です。

ADOT Operator Add-Onを使う場合(EC2ノード):

# ① cert-manager Add-Onを先にインストール(Operator Add-On利用時のみ必要)
aws eks create-addon \
  --cluster-name <クラスター名> \
  --addon-name cert-manager \
  --region ap-northeast-1

# ② ADOT Add-Onをインストール
aws eks create-addon \
  --cluster-name <クラスター名> \
  --addon-name adot \
  --region ap-northeast-1

IAM OIDC プロバイダーの有効化も事前に必要です(eksctl utils associate-iam-oidc-provider)。

(補足)Collector-lessアプローチ:ADOTコレクター不要の新しい方式

2024年以降、ADOTコレクターを立てずに SDKから直接CloudWatch OTLPエンドポイントへ送信する 方式がサポートされました。

# Python(Collector-less)
pip install aws-opentelemetry-distro
opentelemetry-bootstrap --action=install

export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://xray.ap-northeast-1.amazonaws.com/v1/traces"
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="https://logs.ap-northeast-1.amazonaws.com/v1/logs"
export OTEL_AWS_LOG_GROUP_NAME="/myapp/logs"
export OTEL_RESOURCE_ATTRIBUTES="service.name=my-app"
export OTEL_PYTHON_DISTRO=aws_distro
export OTEL_PYTHON_CONFIGURATOR=aws_configurator

opentelemetry-instrument python app.py

前提条件: トレースにCloudWatch OTLPエンドポイントを使う場合、Transaction Search を事前に有効化する必要があります(CloudWatchコンソール → Application Signals → Transaction Search)。有効化しないとトレースデータが届きません。

方式 Collectorの要否 適したケース
Collector経由(本記事メイン) 必要 テールサンプリング・複数バックエンド・バッファリングが必要
Collector-less 不要 シンプルに始めたい・Fargate/Lambda 等コレクター稼働が難しい環境に特に有効

本番運用でのベストプラクティス

サンプリングレートの設計

トレースのサンプリング(どの割合のリクエストをトレースするか)は、コストと可観測性のトレードオフです。

環境 推奨サンプリングレート 理由
開発・ステージング 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でエラーバジェットを管理する方法」も参考にしてください。


troubleshooting diagram for OpenTelemetry connection issues, network flow from app to collector to C

よくあるエラーとトラブルシューティング

テレメトリデータがCloudWatchに届かない

症状: コレクターを起動したが、CloudWatchのカスタムメトリクスに何も表示されない。

確認手順:

  1. コレクターのログを確認する
docker logs adot-collector 2>&1 | grep -E "error|warn|exported"
  1. ネットワーク疎通を確認する
# CloudWatchへの接続確認
curl -I https://monitoring.ap-northeast-1.amazonaws.com
  1. メトリクスの反映には最大2〜3分かかる場合があります。CloudWatchコンソールで カスタム名前空間 を確認してください。

IAM権限エラー

症状: AccessDeniedException または UnauthorizedException がコレクターログに出力される。

確認ポイント:

# EC2インスタンスプロファイルの確認
aws sts get-caller-identity

# 必要なポリシーがアタッチされているか確認
aws iam list-attached-role-policies --role-name <ロール名>

ECSの場合はタスク定義の executionRoleArntaskRoleArn の両方を確認してください。テレメトリの送信には taskRoleArn に権限が必要です。

EMFメトリクスが表示されない場合

症状: コレクターのログにエラーはないが、CloudWatch Metricsにカスタムメトリクスが現れない。

主な原因:

  1. namespace の設定ミス → CloudWatchコンソールで正しい名前空間を確認
  2. ディメンションの不一致 → EMF設定の dimension_rollup_option"NoDimensionRollup" から変更してみる
  3. ログが 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ステップ
  • Collector-less方式(ADOTコレクター不要)もサポート。トレース利用時はTransaction Searchの事前有効化が必要
  • EKS FargateではDaemonSet不可。コレクターが必要なら中央集権型(StatefulSet/Deployment 1台)、不要ならCollector-less方式(SDK→OTLPエンドポイント直送)を選択。どちらもcert-manager不要でIRSAでSigV4認証
  • 本番運用 では テールサンプリングでコストを最適化し、コレクター設定でバックエンドを切り替えられる設計にする

CloudWatchとOpenTelemetryを組み合わせることで、既存のCloudWatch資産を活かしながら、将来的にPrometheusやDatadogへ移行しやすい 構成が作れます。


OTelの概念理解から実務でのAWS監視設計まで、体系的に学びたい方には Udemyのコース「AWS×SRE入門」 も参考にしてみてください。ハンズオン形式でCloudWatch・X-Ray・ADOTの設定を実際に手を動かして学べます。

Udemyで「AWS×SRE入門」を見る →

コメント

タイトルとURLをコピーしました