AWS Distro for OpenTelemetry Lambda を使いHoneycombにトレースを送信する
こんにちは。
エンジニアの古野です。
この記事では、AWS Distro for OpenTelemetry Lambda(以降ADOT Lambda) を使って、Observabilityプラットフォームの Honeycomb にトレースを送信するまでの流れをご紹介します。
ADOT Lambda とは、Lambda 関数上で OpenTelemetry エージェント(Collector)を実行できる AWS のディストリビューションです。
背景
- 近年、サービスの可観測性(Observability)がより重視されるようになり、その一環として OpenTelemetry を採用するプロジェクトが増えています。
- Honeycomb は、高次元の高カーディナリティデータ分析により、イベントや分散トレースなどを可視化できる Observability プラットフォームです。
- ADOT LambdaはLambdaレイヤーとしてサポートされています。Lambdaレイヤーは.zipファイルアーカイブであり、zip形式でデプロイされた関数にレイヤー適用し、追加のライブラリやバイナリを /opt ディレクトリに展開して利用する仕組みです。そのため、コンテナイメージ (ECR) でのデプロイでは、このレイヤーをそのまま利用できません。
- この問題を回避するため、レイヤーの中身をコンテナビルドの工程に取り込み、Collector を稼働させる方法をまとめました。
Honeycomb で API キーを取得する
まずは Honeycomb 側で API Key の作成が必要です。
- honeycomb.io にログインします
- 初回ログインで表示されている
API key
は設定用のキー(Configuration Key)となっています。
テレメトリ送信を行うには権限が強いため、専用のIngest Key
を用いることが推奨されています。
-
Ingest Key
を新規で作成し、そのキーを控えておきます。
このキーを、後ほど Collector に渡すことで Honeycomb へトレースを送信します。
Lambda(コンテナイメージ)への導入
前提
- 例として、私が関わっているプロダクト「オクタゴン セールススイート」では、Python のバックエンド API を Docker イメージとしてビルドし、ECR にプッシュ → Lambda にデプロイしています。
- ADOT Lambda はレイヤーで提供されていますが、コンテナイメージにはレイヤーが使えません。そのため、レイヤーの中身をコンテナビルドに含める必要があります。
- 参考情報:
GitHub ActionsのCD例
以下は、GitHub Actions を利用したコンテナビルド&デプロイの例です。
- adot-layerディレクトリを作成し、そこへADOT Lambdaレイヤーを展開します。
-
aws lambda get-layer-version-by-arn
でARNからURLが取得できます。 - curlでダウンロード後にunzipで展開します。
-
- ADOT Lambda を有効にするための設定は、以下の箇所となります。
- AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument
- OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/otel-collector-config.yaml
- HONEYCOMB_API_KEY
build-backend:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
defaults:
run:
working-directory: python
steps:
- name: checkout
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.role-to-assume }}
aws-region: ap-northeast-1
- name: Download ADOT Lambda Layer
# @see
# https://aws-otel.github.io/docs/getting-started/lambda/lambda-python#add-the-arn-of-the-lambda-layer
run: |
mkdir -p adot-layer
LOCATION=$(aws lambda get-layer-version-by-arn \
--arn "arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-python-arm64-ver-1-29-0:1" \
--query 'Content.Location' --output text)
curl -sSL "$LOCATION" -o adot-layer/layer.zip
unzip -q adot-layer/layer.zip -d adot-layer
rm adot-layer/layer.zip
- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and Push
uses: docker/build-push-action@v5
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: sales-suite-backend-${{ inputs.env }}
IMAGE_TAG: ${{ inputs.tag }}
with:
push: true
tags: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
context: ./python
platforms: linux/arm64
provenance: false
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument
OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/otel-collector-config.yaml
HONEYCOMB_API_KEY=${{ secrets.honeycomb-api-key }}
otel-collector-config.yaml の設定
上記の Actions では OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/otel-collector-config.yaml
を指定しています。
このファイルをコンテナイメージ内に含めることで、Collector の起動設定を読み込ませます。
receivers:
otlp:
protocols:
grpc:
endpoint: "localhost:4317"
http:
endpoint: "localhost:4318"
exporters:
debug: {}
otlp/traces:
endpoint: api.honeycomb.io:443
headers:
"x-honeycomb-team": ${env:HONEYCOMB_API_KEY}
service:
pipelines:
traces:
receivers: [otlp]
processors: []
exporters: [debug, otlp/traces]
- receivers
- デフォルト設定です。
- exporters.otlp/traces.endpoint
- Honeycomb の OTLP 受信エンドポイント (443) を指定しています。
- headers.x-honeycomb-team
- ここで API key を設定することで、Honeycomb 側にトレースを送信できるようになります。
${env:HONEYCOMB_API_KEY}
は Confmap Providers のEnv providerにより、環境変数を参照しています。
- ここで API key を設定することで、Honeycomb 側にトレースを送信できるようになります。
- 標準出力に出力するためdebug exporterも指定しています。
Dockerfileの設定
展開したADOT Lambdaレイヤーを/optへ含めるようにします。
FROM python:3.11.9-slim-bookworm AS build-env
WORKDIR /app
RUN pip install poetry \
&& poetry config --local virtualenvs.in-project true
COPY pyproject.toml poetry.lock /app/
RUN poetry install --only main --no-root
FROM public.ecr.aws/lambda/python:3.11
# 追加した環境変数定義
ARG AWS_LAMBDA_EXEC_WRAPPER
ARG OPENTELEMETRY_COLLECTOR_CONFIG_URI
ARG HONEYCOMB_API_KEY
ENV AWS_LAMBDA_EXEC_WRAPPER=$AWS_LAMBDA_EXEC_WRAPPER
ENV OPENTELEMETRY_COLLECTOR_CONFIG_URI=$OPENTELEMETRY_COLLECTOR_CONFIG_URI
ENV HONEYCOMB_API_KEY=$HONEYCOMB_API_KEY
COPY /app/.venv ${LAMBDA_TASK_ROOT}/.venv
# /optへコピーしておく
COPY adot-layer /opt
COPY src/ ${LAMBDA_TASK_ROOT}/src/
CMD [ "src.app.handler.handler" ]
テレメトリ送信の確認
これでHoneycombへトレースが送信されます。📈
もし送信されていない場合は、CloudWatch Logsなどにログが残っているはずです。
次項の構築時の確認方法も参考に、問題解決しましょう。
構築時の確認方法
正常に送信できない場合に、問題切り分けのための方法をいくつかご紹介します。
ECR からイメージを pull して中身を確認する
- 事前にECRからイメージを取得します。
docker run -it --entrypoint /bin/sh <イメージID or タグ>
- adot-layer ディレクトリや、otel-collector-config.yaml 、環境変数が正しく含まれているかを確認します。
otel-collector-config.yamlを検証する
ADOT CollectorのDocker imageが配布されています。
otel-collector-config.yamlの検証に利用できます。
docker pull amazon/aws-otel-collector:latest
docker run --rm -it \
-v $(pwd)/otel-collector-config.yaml:/config/config.yaml \
-e HONEYCOMB_API_KEY=xxxxx \
amazon/aws-otel-collector:latest \
--config /config/config.yaml
未解決: batch processor 利用時のエラーについて
- ADOT Lambdaからトレースを送信する際に、batch processor を追加するとCollectorの起動に失敗してしまいました。
- ドキュメントではbatch processor に対応していそうですが、原因を掴むことができず利用をやめました。
- Python, arm64のLambdaレイヤーのバージョン。
- arn:aws:lambda:ap-northeast-1:901920570463:layer:aws-otel-python-arm64-ver-1-29-0:1
{"level":"warn","ts":1742456138.0101013,"logger":"lifecycle.manager","msg":"Failed to start the extension","error":"failed to get config: cannot unmarshal the configuration: decoding failed due to the following error(s):\n\nerror decoding 'processors': unknown type: \"batch\" for id: \"batch\" (valid values: [])"}
{"level":"info","ts":1742456138.0106115,"msg":"done","error":"failed to get config: cannot unmarshal the configuration: decoding failed due to the following error(s):\n\nerror decoding 'processors': unknown type: \"batch\" for id: \"batch\" (valid values: [])";}
まとめ
- ADOT Lambda をコンテナイメージで利用する場合は、Lambdaレイヤーの中身をビルド時に取り込み、
AWS_LAMBDA_EXEC_WRAPPER
やOPENTELEMETRY_COLLECTOR_CONFIG_URI
を指定します。 - Honeycomb 側では Ingest Key を作成し、
otel-collector-config.yaml
でx-honeycomb-team
ヘッダとして設定します。 - Collector の設定ファイルをローカルで検証しておくと、Lambda 上でのトラブルシューティングが容易になります。
これで、ADOT Lambda (Collector) を使って Honeycomb にトレースを送信する仕組みが整います。
🚀🚀🚀 Observability環境の構築にぜひ活用してみてください 🚀🚀🚀
参考リンク
Discussion