📐

ADOT を使用して Next.js を計測する

2024/12/01に公開

kubell Advent Calendar 2024 の投稿です。 [1]

https://qiita.com/advent-calendar/2024/kubell

この投稿では、AWS Distro for OpenTelemetry (ADOT) [2] を用いた Next.js の計測について書きます。

TL;DR

  • ADOT を使用することで、Next.js アプリケーションにレーシングを実装。特に AWS のサービスを使用している環境では、X-Ray との連携も容易で、運用面でも優れる
  • 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 でヘルスチェックが可能なため)

記事は以上です。

この投稿をみていただい方はいいねをお願いします。

それでは次回のアドカレでお会いしましょう👋

脚注
  1. 2024年7月1日、Chatwork株式会社は株式会社kubellへと社名変更しました。 ↩︎

  2. https://aws-otel.github.io/ ↩︎

  3. https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html ↩︎

  4. https://nextjs.org/docs/pages/building-your-application/optimizing/open-telemetry ↩︎

GitHubで編集を提案

Discussion