AWS上にObservability検証環境を構築してみた(Grafana + Tempo + Loki + AMP)

AWS上にObservability検証環境を構築してみた(Grafana + Tempo + Loki + AMP)

2026.02.06

こんにちは、ゲームソリューション部のsoraです。
今回は、AWS上にObservability検証環境を構築してみたことについて書いていきます。

構成

今回構築したのは以下の構成です。
Fargateで動くサンプルアプリでADOT Collector + FluentBitを使って、トレース・ログ・メトリクスを収集し、EC2上のGrafanaで可視化する構成です。

サンプルアプリがあるECSへはHTTPで接続します。
プライベートサブネットのEC2へはSSMポートフォワーディングで接続します。

sr-grafana-ec2-01

主なコンポーネント 役割
ECS(Fargate) サンプルアプリ + ADOT Collector + FluentBit
EC2 Grafana / Tempo / Loki(docker-compose)
ALB サンプルアプリへのHTTPアクセス
Amazon Managed Service for Prometheus (AMP) メトリクスの保存

データのフローについては以下です。

  • トレース:アプリ → ADOT Collector → Tempo(EC2)
  • ログ:アプリ → FluentBit(FireLens)→ Loki(EC2)
  • メトリクス:アプリ → ADOT Collector → AMP

構築

今回はTerraformで構築しました。
基本的なリソースが多いのでコードは割愛しますが、ポイントだけ解説します。

Amazon Managed Service for Prometheus(AMP)

AMPはフルマネージドなPrometheus互換のモニタリングサービスです。
AWSコンソールからワークスペースを作成すると、以下のような画面が表示されます。

sr-grafana-ec2-02

ワークスペースには以下の情報が含まれています。

  • エンドポイント - リモート書き込みURL:メトリクスを送信する際に使用
  • エンドポイント - クエリURL:Grafanaなどからクエリを実行する際に使用

ちなみに、AMP自体にはメトリクスを閲覧するUIがありません。
そのため、Grafanaなどの外部ツールからクエリして可視化する必要があります。
また、ルール管理やアラートマネージャーの設定はコンソールから行うことができます。

OpenTelemetry(OTel)の設定

サンプルアプリにOpenTelemetry SDKを組み込み、トレースとメトリクスを出力します。

from opentelemetry import trace, metrics
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter

# トレース設定
provider = TracerProvider(resource=resource)
otlp_exporter = OTLPSpanExporter(
    endpoint=os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://localhost:4317"),
    insecure=True
)
provider.add_span_processor(BatchSpanProcessor(otlp_exporter))
trace.set_tracer_provider(provider)

# メトリクス設定
metric_exporter = OTLPMetricExporter(
    endpoint=os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://localhost:4317"),
    insecure=True
)
metric_reader = PeriodicExportingMetricReader(metric_exporter)
meter_provider = MeterProvider(resource=resource, metric_readers=[metric_reader])
metrics.set_meter_provider(meter_provider)

FlaskとRequestsの自動計装も有効にしています。

FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()

これにより、HTTPリクエストのトレースとメトリクスが自動的に収集されます。

ADOT Collectorの設定

ECSタスク内でサイドカーとして動作するADOT Collectorが、アプリからのテレメトリを受信して各ツールやサービスへ転送します。
AMPへの書き込みにはSigV4認証が必要なため、sigv4authを設定しています。

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

exporters:
  otlphttp/tempo:
    endpoint: http://${TEMPO_ENDPOINT}:4318

  prometheusremotewrite:
    endpoint: ${AMP_REMOTE_WRITE_URL}
    auth:
      authenticator: sigv4auth

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlphttp/tempo]
    metrics:
      receivers: [otlp]
      exporters: [prometheusremotewrite]

Tempoの設定

Tempoはトレースデータを保存・検索するためのツールです。

server:
  http_listen_port: 3200

distributor:
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317
        http:
          endpoint: 0.0.0.0:4318

ingester:
  max_block_duration: 5m
  lifecycler:
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1

storage:
  trace:
    backend: local
    local:
      path: /var/tempo/traces
    wal:
      path: /var/tempo/wal

Lokiの設定

Lokiはログデータを保存・検索するためのツールです。
ECSタスクからはFluentBit(FireLens)経由でログを受信します。

auth_enabled: false

server:
  http_listen_port: 3100

common:
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

schema_config:
  configs:
    - from: 2020-10-24
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

Grafanaの設定

Grafanaでは、Tempo・Loki・AMPの3つをデータソースとして設定します。
AMPへの接続にはSigV4認証を使用するため、EC2のIAMロールに適切な権限を付与しています。

datasources:
  - name: Tempo
    type: tempo
    url: http://localhost:3200

  - name: Loki
    type: loki
    url: http://localhost:3100

  - name: Prometheus (AMP)
    type: prometheus
    url: https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/xxx/
    jsonData:
      sigV4Auth: true
      sigV4Region: ap-northeast-1

動作確認

サンプルアプリ

ALBのDNS名にブラウザでアクセスして、サンプルのアプリにアクセスします。

sr-grafana-ec2-03

各ボタンで異なる特性のAPIを呼び出せます。

ボタン 動作
Hello API 即時レスポンス
Slow API 2〜5秒遅延
Error API 500エラー
Chain API 複数API呼び出し

sr-grafana-ec2-04

sr-grafana-ec2-05

sr-grafana-ec2-06

sr-grafana-ec2-07

Grafana

SSMポートフォワーディングでEC2に接続し、ブラウザで http://localhost:3000 にアクセスします。

aws ssm start-session \
  --target <EC2_INSTANCE_ID> \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["3000"],"localPortNumber":["3000"]}'

Starting session with SessionId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Port 3000 opened for sessionId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Waiting for connections...

Connection accepted for session [xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx]

ログイン後、Exploreからデータソースを確認できます。

sr-grafana-ec2-08

sr-grafana-ec2-09

Tempoでトレース確認

Tempoを選択し、Service Nameにsample-appを入力してみると、トレースが確認できました。

sr-grafana-ec2-10

Lokiでログ確認

Lokiを選択し、job = ecs-sample-appでフィルタしてみると、ログが確認できました。

sr-grafana-ec2-11

AMPでメトリクス確認

Prometheus (AMP)を選択し、PromQLクエリを実行してみると、メトリクスが確認できました。

sr-grafana-ec2-12

最後に

今回は、AWS上にObservability検証環境を構築してみたことを記事にしました。
この記事がどなたかの参考になれば幸いです。

この記事をシェアする

FacebookHatena blogX

関連記事