🍣

ADOT Collector をとりあえずローカルのコンテナ環境で動かすまでのデモ

2024/06/04に公開

目的

  • AWS Distro for OpenTelemetry(ADOT)の動作検証をしていきたいのですが、何ができるのか?どう動くのかがよくわかっていない。
  • ECS, EKS で検証を行う前に、とりあえずローカル環境でDocker使って動かしてみて、動作確認してみたいと思います。

サンプルアプリ

メトリクス、トレースを出力するように計装されたアプリケーションが必要となります。
今回は公式githubにあるサンプルアプリをそのまま使用します。いずれは自分でサンプルアプリを作ってみたいところです。

https://github.com/aws-observability/aws-otel-community/tree/master/sample-apps/go-sample-app

README には以下のように使い方が書かれています。

Description
This Go sample app will emit Traces and Metrics with Logs as experimental. There are two types of metrics emitted; Request Based and Random Based. Metrics are generated as soon as the application is ran or deployed without any additional effort.
...
Additionally, you can generate Traces and request based Metrics by making requests to the following exposed endpoints. Due to the upstream Go SDK being unstable for metrics, we do not support metrics further than for generating values for demo purposes.

  1. /
    Ensures the application is running
  2. /outgoing-http-call
    Makes a HTTP request to aws.amazon.com (http://aws.amazon.com/)
  3. /aws-sdk-call
    Makes a call to AWS S3 to list buckets for the account corresponding to the provided AWS credentials
  4. /outgoing-sampleapp
    Makes a call to all other sample app ports configured at <host>:<port>/outgoing-sampleapp. If none available, makes a HTTP request to www.amazon.com (http://www.amazon.com/)

アップストリームの Go SDK でメトリクスについては不安定なためとありますが、OpenTelemetry をみてみるとすでに Stable となっていました。
この辺は最新情報をしっかりとみる必要がありますね。今回は動かすことを第一目標としたいため、一旦無視して進めます。

https://opentelemetry.io/docs/languages/go/

ディレクトリ構成

% tree
.
├── docker-compose.yml
├── go-sample-app
│   ├── Dockerfile
│   ├── README.md
│   ├── collection
│   │   ├── client.go
│   │   ├── config.go
│   │   ├── http_traces.go
│   │   ├── random_metrics.go
│   │   └── request_metrics.go
│   ├── config.yaml
│   ├── go.mod
│   ├── go.sum
│   └── main.go
└── otel-agent-config.yaml

docker-compose でコンテナ設定

docker-compose.yml
version: "2"
services:
  aws-ot-collector:
    image: public.ecr.aws/aws-observability/aws-otel-collector:latest
    command: ["--config=/etc/otel-agent-config.yaml"]
    environment:
      - AWS_REGION=ap-northeast-1
    volumes:
      - ./otel-agent-config.yaml:/etc/otel-agent-config.yaml
      - ~/.aws:/home/aoc/.aws
    ports:
      - "1777:1777"   # pprof extension
      - "55679:55679" # zpages extension
      - "13133"       # health_check

  go-app:
    build: ./go-sample-app
    environment:
      - OTEL_EXPORTER_OTLP_ENDPOINT=http://aws-ot-collector:4317
      - OTEL_RESOURCE_ATTRIBUTES=service.namespace=GoOtelDemo,service.name=GoOtelDemoService
      - AWS_REGION=ap-northeast-1
      - OTEL_METRICS_EXPORTER=otlp
      - LISTEN_ADDRESS=0.0.0.0:8080 # web server endpoint
    volumes:
      - ~/.aws:/root/.aws # test auto generated trace on S3 access
    ports:
      - "8080:8080"   # http sample requests
    depends_on:
      - aws-ot-collector

細かくみていきます。

ADOT Collector コンテナについて

  aws-ot-collector:
    ...
    command: ["--config=/etc/otel-agent-config.yaml"]
    ...
    volumes:
      - ./otel-agent-config.yaml:/etc/otel-agent-config.yaml
      - ~/.aws:/home/aoc/.aws

設定ファイルをバインドマウントして渡しています。
また、ローカルの AWS 認証情報を渡しています。
ADOT コレクターから CloudWatch, X-Ray へデータ出力するために権限が必要となります。
https://aws-otel.github.io/docs/setup/ecs/create-iam-policy

推奨はされませんが、IAMユーザーのアクセスキー・シークレットアクセスキーを直接指定してあげることも可能です。

  aws-ot-collector:
    image: public.ecr.aws/aws-observability/aws-otel-collector:latest
    command: ["--config=/etc/otel-agent-config.yaml"]
    environment:
      - AWS_REGION=ap-northeast-1
      - AWS_ACCESS_KEY_ID=xxxxxx
      - AWS_SECRET_ACCESS_KEY=xxxxxxxx

今回は OTLP レシーバーからメトリクスを EMF 形式で CloudWatch に、トレースデータを X-Ray に出力してみます。

設定ファイルは以下です。

otel-agent-config.yaml
extensions:
  health_check:
  pprof:
    endpoint: 0.0.0.0:1777

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

processors:
  batch:

exporters:
  logging:
    loglevel: debug
  awsxray:
    region: 'ap-northeast-1'
  awsemf:
    region: 'ap-northeast-1'

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [awsxray]
    metrics:
      receivers: [otlp]
      exporters: [awsemf]

  extensions: [pprof]
  telemetry:
    logs:
      level: debug

全体イメージはこうなります。

アプリケーションコンテナについて

...
  go-app:
    build: ./go-sample-app
    environment:
      - OTEL_EXPORTER_OTLP_ENDPOINT=http://aws-ot-collector:4317
      - OTEL_RESOURCE_ATTRIBUTES=service.namespace=GoOtelDemo,service.name=GoOtelDemoService
      - AWS_REGION=ap-northeast-1
      - OTEL_METRICS_EXPORTER=otlp
      - LISTEN_ADDRESS=0.0.0.0:8080 # web server endpoint
    volumes:
      - ~/.aws:/root/.aws # test auto generated trace on S3 access
    ports:
      - "8080:8080"   # http sample requests
    depends_on:

SDK の設定として、OTEL_EXPORTER_OTLP_ENDPOINTOTEL_RESOURCE_ATTRIBUTES などの環境変数を設定できます。
特に OTEL_RESOURCE_ATTRIBUTES で設定した値が CloudWatch メトリクスのディメンションになります。

https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/

https://opentelemetry.io/docs/languages/sdk-configuration/general/

実行

コンテナを起動してみます。

$ docker-compose up -d

アプリケーションが起動します。
ポート8080 で起動しているアプリにリクエスを送ってみると、トレースIDが出力されるよう設定されています。

$ curl localhost:8080/outgoing-http-call
{"traceId":"1-665d55ee-47f6a8d1e952ac690cf2d1f3"}

メトリクス/トレースの確認

メトリクス

CloudWatch を確認してみます。

まず awsemf エクスポーターを設定しているため、EMF形式で出力されています。
CloudWatch Logs の /metrics/GoOtelDemo/GoOtelDemoService に出力されていることがわかります。

ではメトリクスを見ていきましょう。
カスタムメトリクス名前空間に GoOtelDemo/GoOtelDemoService が作成されており、そこにメトリクスが出力されています。
OTEL_RESOURCE_ATTRIBUTES で設定した値がここに反映されていることがわかりますね。

CloudWatch EMF Exporter (awsemf)について

こちらにまとまっています。

https://aws-otel.github.io/docs/getting-started/cloudwatch-metrics#cloudwatch-emf-exporter-awsemf

より細かいオプションは github repository にあります。

https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/awsemfexporter

ロググループ、ストリーム、名前空間や保持期間などをカスタマイズできます。
ディメンションを細かく設定することもできそうです。

トレース

X-Ray を確認してみると、トレースが作成されていることがわかります。

X-ray Exporter について

X-ray Exporter の設定などはこちらにまとまっています。
X-ray と OTEL のデータモデルで対応する Attribute などがまとまっています。

https://aws-otel.github.io/docs/getting-started/x-ray#configuring-the-aws-x-ray-exporter

細かい設定をやろうとすればできますが、単に X-Ray へ送るだけであれば特段設定は必要なさそうですね。
OTEL SDK でトレースを出力するようにアプリ側が実装されていれば、簡単に X-Ray へトレースを出力できそうです。

最後に

  • 今回は ADOT の動作を確認するため、docker-compose を使ってまず動かすことを目的にしたデモを行いました。
  • アプリ側でどのようにメトリクスやトレース情報を出力するか実装に依存するところも多いです。今回はアプリケーションはサンプルを使用したため、ここの理解が進みませんでした。
  • ローカルでの動作確認はできたため、ECS/EKS での動作も見ていきたいと思います。

Discussion