kubell Advent Calendar 2024 の投稿です。 1
この投稿では、AWS Distro for OpenTelemetry (ADOT) 2 を用いた Next.js の計測について書きます。
TL;DR
- ADOT を使用することで、Next.js アプリケーションにレーシングを実装。特に AWS のサービスを使用している環境では、X-Ray との連携も容易で、運用面でも優れる
- AWS Amplify Gen 2 (Amplify) でホスティングしている Next.js アプリケーションに AWS Distro for OpenTelemetry (ADOT) を導入
- Amazon ECS (ECS) にデプロイした ADOT Collector で X-Ray 3 トレーシングを実現
- バックエンドの計測では Collector を Sidecar として起動可能
- ⚠️ Amplify Managed の制約により、フロントエンドの Tracing とログの紐付けには制限あり
はじめに
本記事では、Amplify でホスティングされている Next.js アプリケーションに、AWS Distro for OpenTelemetry(ADOT)を使用してトレーシング機能を実装する方法について説明します。ADOT は、AWS が提供する OpenTelemetry ディストリビューションで、ECS にデプロイできます。
前提条件と制約事項
- フロントエンドは Amplify Managed で運用されています。
- Amplify の CDN と Render (Lambda) は管理された状態で提供されています。
- Amplify の Lambda の設定は 2024 年 12 月 1 日時点では変更できません。
- この制約により、Tracing とログを紐づけて観察することが困難です。
これらの制約は、特にフロントエンドのパフォーマンス監視やデバッグの際に考慮が必要です。
アーキテクチャ概要
- フロントエンド: Amplify ホスティング
- Server-side Rendering: Lambda
- トレーシング: ADOT
- バックエンド デプロイ環境: ECS
ADOT Collector の設定
ECS でのヘルスチェック設定
ECS でヘルスチェックを行うために、以下のような config.yaml
の設定が必要です。
extensions: health_check: endpoint: 0.0.0.0:13133 pprof: endpoint: 0.0.0.0:1777 receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 processors: batch: exporters: debug: verbosity: detailed awsxray: region: 'ap-northeast-1' awsemf: region: 'ap-northeast-1' service: pipelines: traces: receivers: [otlp] exporters: [awsxray] metrics: receivers: [otlp] exporters: [awsemf] extensions: [pprof, health_check] telemetry: logs: level: debug
ローカル開発環境での設定
ローカルで ADOT を起動する場合、AWS の認証情報が必要です。以下の Docker コマンドで実行できます:
docker run --rm -p 13133:13133 -p 4317:4317 -p 4318:4318 -p 55680:55680 -p 8889:8888 \ -e "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" \ -e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \ -e "AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}" \ -e AWS_REGION=ap-northeast-1 \ --name awscollector public.ecr.aws/aws-observability/aws-otel-collector:latest
必要な IAM Policy
以下の IAM Policy は、ECS タスク定義のタスク実行ロールに必要です。この Policy により、ADOT Collector が X-Ray や CloudWatch と連携できるようになります:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:PutLogEvents", "logs:CreateLogGroup", "logs:CreateLogStream", "logs:DescribeLogStreams", "logs:DescribeLogGroups", "ssm:GetParameters", "xray:PutTraceSegments", "xray:PutTelemetryRecords", "xray:GetSamplingRules", "xray:GetSamplingTargets", "xray:GetSamplingStatisticSummaries" ], "Resource": "*" } ] }
- ECS タスク定義でこの Policy をタスク実行ロールにアタッチすることで、ADOT Collector は必要な権限を持って AWS サービスと連携できるようになります。
Next.js アプリケーションでのトレーシング実装
基本実装
Next.js の公式ドキュメント 4 をベースに、実装できます:
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http' import { Resource } from '@opentelemetry/resources' import { NodeSDK } from '@opentelemetry/sdk-node' import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node' import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions' const sdk = new NodeSDK({ resource: new Resource({ [ATTR_SERVICE_NAME]: 'next-app', }), spanProcessor: new SimpleSpanProcessor(new OTLPTraceExporter()), }) sdk.start()
このコードは以下のことを行います:
- OTLP TraceExporter を使用してトレースデータを HTTP で送信。
- リソース名(サービス名)を
next-app
として設定。 - SimpleSpanProcessor を使用してトレースの処理を行う。
カスタマイズのポイント
- Vercel 以外でホスティングする場合は、環境に応じたカスタマイズが必要です。
- Full-Stack TypeScript プロジェクトの場合、トレーシングの実装からテストまでを一貫して行うことが容易です。
ECS での運用について
- バックエンドの場合、OpenTelemetry Collector を Sidecar として起動できます。
- ECS では、ポートマッピングは 1 つで十分です(
localhost
でヘルスチェックが可能なため)
記事は以上です。
この投稿をみていただい方はいいねをお願いします。
それでは次回のアドカレでお会いしましょう👋
- 2024年7月1日、Chatwork株式会社は株式会社kubellへと社名変更しました。↩
- https://aws-otel.github.io/↩
- https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html↩
- https://nextjs.org/docs/pages/building-your-application/optimizing/open-telemetry↩