メインコンテンツまでスキップ

AWS Distro for OpenTelemetryを使ってSpring PetClinicサンプルアプリのテレメトリーをAWSに送信する方法

· 約8分
moritalous

AWS Distro for OpenTelemetryというものがあることを知りました。これを使うとメトリクスとトレース情報が簡単に収集できるようです。Javaのアプリケーションのメトリクスやトレースをどのように収集するのか興味がありましたので、実際に試してみました。 今回試したソースコードはGitHubに格納しています。

概要
  • OpenTelemetryのAWS版としてAWS Distro for OpenTelemetryがある
  • AWS Distro for OpenTelemetryを使うと簡単にメトリクスとトレースをAWSに送信ができる
  • Spring BootのサンプルとしてPetClinicが用意されている
  • Javaアプリケーションにエージェントを追加するだけでメトリクスとトレースの収集ができる

AWS Distro for OpenTelemetryとは​

  • AWS Distro for OpenTelemetryとは

AWS Distro for OpenTelemetryは、OpenTelemetryプロジェクトのAWSサポートによるセキュアでプロダクションレディなディストリビューションです。

出典:AWS Distro for OpenTelemetry (翻訳:DeepL)

  • OpenTelemetryとは

OpenTelemetry は、ツール、API、SDK の集合体です。テレメトリーデータ(メトリクス、ログ、トレース)の計測、生成、収集、エクスポートに使用し、ソフトウェアのパフォーマンスと動作の分析に役立てることができます。

出典:OpenTelemetry (翻訳:DeepL)

OpenTelemetryのAWS版(CloudWatchやX-Rayに送信することができる版)というイメージです。

注記

ベンダーロックインを避ける意味で、オープンであるというところがポイントです。

Spring PetClinicサンプルアプリの準備​

まずはSpring PetClinicサンプルアプリを起動させます。

  1. Dockerfileを作成 Mavenでビルドするだけですが、Docker内で実行します。

    FROM bitnami/git:latest as git
    WORKDIR /work
    RUN git clone --depth 1 https://github.com/spring-projects/spring-petclinic.git

    FROM amazoncorretto:11-alpine
    RUN adduser -D amazoncorretto
    USER amazoncorretto
    COPY --from=git --chown=amazoncorretto /work/spring-petclinic /app/spring-petclinic
    WORKDIR /app/spring-petclinic
    RUN ./mvnw package
    EXPOSE 8080
    CMD ["./mvnw", "spring-boot:run"]
  2. docker-compose.yamlを作成 データベースにPostgreSQLを使用するように設定します。

    version: '3'

    services:
    petclinic:
    build:
    context: .
    dockerfile: Dockerfile
    environment:
    - POSTGRES_URL=jdbc:postgresql://postgres/petclinic
    ports:
    - "8080:8080"
    command: [ "./mvnw", "spring-boot:run", "-Dspring-boot.run.profiles=postgres"]
    depends_on:
    - postgres

    postgres:
    image: postgres
    environment:
    - POSTGRES_PASSWORD=petclinic
    - POSTGRES_USER=petclinic
    - POSTGRES_DB=petclinic
    ports:
    - "5432:5432"
    注意

    petclinicの設定でpostgresの初期ユーザーとパスワードが設定されているのでそのまま使用しました。 変更する場合は、POSTGRES_URLのようにPOSTGRES_USERとPOSTGRES_PASSで上書きができます。
    参考:https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/application-postgres.properties

  3. 起動

    docker compose up

    ブラウザでhttp://localhost:8080にアクセスします。

    • HOME画面

    image.png

    • FIND OWNERS画面

    image.png

    • VETERINARIANS画面

    image.png

    • ERROR画面

    image.png

    わざとExceptionを発生させる画面のようで、以下のExceptionが発生します。

    Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: Expected: controller used to showcase what happens when an exception is thrown] with root cause
ヒント

Spring PetClinicサンプルアプリが起動しました。

AWS Distro for OpenTelemetryでテレメトリーを取得する​

それではいよいよAWS Distro for OpenTelemetryを追加していきます。 大きく以下の手順を実行します。

  1. Spring PetClinicサンプルアプリにOpenTelemetry Agent for Javaを追加する
  2. AWS Distro for OpenTelemetry Collectorコンテナを追加する

1. Spring PetClinicサンプルアプリにOpenTelemetry Agent for Javaを追加する​

  1. Dockerfileに以下の記述を追加する。

    ADD --chown=amazoncorretto https://github.com/aws-observability/aws-otel-java-instrumentation/releases/download/v1.17.0/aws-opentelemetry-agent.jar /app/aws-opentelemetry-agent.jar
    ENV JAVA_TOOL_OPTIONS ""
    ENV OTEL_TRACES_SAMPLER ""
    ENV OTEL_PROPAGATORS ""
    ENV OTEL_RESOURCE_ATTRIBUTES ""
    ENV OTEL_IMR_EXPORT_INTERVAL ""
    ENV OTEL_EXPORTER_OTLP_ENDPOINT ""
    Dockerfile全体
    FROM bitnami/git:latest as git
    WORKDIR /work
    RUN git clone --depth 1 https://github.com/spring-projects/spring-petclinic.git

    FROM amazoncorretto:11-alpine
    RUN adduser -D amazoncorretto
    USER amazoncorretto
    COPY --from=git --chown=amazoncorretto /work/spring-petclinic /app/spring-petclinic
    WORKDIR /app/spring-petclinic
    RUN ./mvnw package
    ADD --chown=amazoncorretto https://github.com/aws-observability/aws-otel-java-instrumentation/releases/download/v1.17.0/aws-opentelemetry-agent.jar /app/aws-opentelemetry-agent.jar
    ENV JAVA_TOOL_OPTIONS ""
    ENV OTEL_TRACES_SAMPLER ""
    ENV OTEL_PROPAGATORS ""
    ENV OTEL_RESOURCE_ATTRIBUTES ""
    ENV OTEL_IMR_EXPORT_INTERVAL ""
    ENV OTEL_EXPORTER_OTLP_ENDPOINT ""
    EXPOSE 8080
    CMD ["./mvnw", "spring-boot:run"]
  2. docker-compose.yamlのenvironmentに以下を追加する。

          - JAVA_TOOL_OPTIONS=-javaagent:/app/aws-opentelemetry-agent.jar
    - OTEL_TRACES_SAMPLER=always_on
    - OTEL_PROPAGATORS=tracecontext,baggage,xray
    - OTEL_RESOURCE_ATTRIBUTES=service.name=petclinic
    - OTEL_IMR_EXPORT_INTERVAL=10000
    - OTEL_EXPORTER_OTLP_ENDPOINT=http://aws-otel-collector:4317
    - OTEL_EXPORTER_OTLP_INSECURE=true
    docker-compose.yaml全体
    version: '3'

    services:
    petclinic:
    build:
    context: .
    dockerfile: Dockerfile
    environment:
    - POSTGRES_URL=jdbc:postgresql://postgres/petclinic
    - JAVA_TOOL_OPTIONS=-javaagent:/app/aws-opentelemetry-agent.jar
    - OTEL_TRACES_SAMPLER=always_on
    - OTEL_PROPAGATORS=tracecontext,baggage,xray
    - OTEL_RESOURCE_ATTRIBUTES=service.name=petclinic
    - OTEL_IMR_EXPORT_INTERVAL=10000
    - OTEL_EXPORTER_OTLP_ENDPOINT=http://aws-otel-collector:4317
    - OTEL_EXPORTER_OTLP_INSECURE=true
    ports:
    - "8080:8080"
    command: [ "./mvnw", "spring-boot:run", "-Dspring-boot.run.profiles=postgres"]
    depends_on:
    - postgres

    postgres:
    image: postgres
    environment:
    - POSTGRES_PASSWORD=petclinic
    - POSTGRES_USER=petclinic
    - POSTGRES_DB=petclinic
    ports:
    - "5432:5432"

2. AWS Distro for OpenTelemetry Collectorコンテナを追加する​

  1. AWS認証情報(.aws/config、.aws/credentials)を作成する

    ポリシーはCloudWatchFullAccessとAWSXrayFullAccessをアタッチします。

  2. config.yamlを作成する

    AWS Distro for OpenTelemetry Collectorの設定ファイルです。 受け取ったtracesをawsxray(X-Ray)に、metricsをawsemf(CloudWatch Metrics)に送信するようになっています。

    extensions:
    health_check:

    receivers:
    otlp:
    protocols:
    grpc:
    endpoint: 0.0.0.0:4317
    http:
    endpoint: 0.0.0.0:4318
    awsxray:
    endpoint: 0.0.0.0:2000
    transport: udp

    processors:
    batch/traces:
    timeout: 1s
    send_batch_size: 50
    batch/metrics:
    timeout: 60s

    exporters:
    awsxray:
    awsemf:

    service:
    pipelines:
    traces:
    receivers: [otlp,awsxray]
    processors: [batch/traces]
    exporters: [awsxray]
    metrics:
    receivers: [otlp]
    processors: [batch/metrics]
    exporters: [awsemf]

    extensions: [health_check]
  3. docker-compose.yamlのservices配下に追加

      aws-otel-collector:
    image: public.ecr.aws/aws-observability/aws-otel-collector:latest
    environment:
    - AWS_REGION=ap-northeast-1
    - AWS_PROFILE=default
    volumes:
    - ./aws-otel-collector/config.yaml:/etc/otel-agent-config.yaml
    - ./.aws:/root/.aws
    command: ["--config=/etc/otel-agent-config.yaml"]
    docker-compose.yaml全体
    version: '3'

    services:
    petclinic:
    build:
    context: .
    dockerfile: Dockerfile
    environment:
    - POSTGRES_URL=jdbc:postgresql://postgres/petclinic
    - JAVA_TOOL_OPTIONS=-javaagent:/app/aws-opentelemetry-agent.jar
    - OTEL_TRACES_SAMPLER=always_on
    - OTEL_PROPAGATORS=tracecontext,baggage,xray
    - OTEL_RESOURCE_ATTRIBUTES=service.name=petclinic
    - OTEL_IMR_EXPORT_INTERVAL=10000
    - OTEL_EXPORTER_OTLP_ENDPOINT=http://aws-otel-collector:4317
    - OTEL_EXPORTER_OTLP_INSECURE=true
    ports:
    - "8080:8080"
    command: [ "./mvnw", "spring-boot:run", "-Dspring-boot.run.profiles=postgres"]
    depends_on:
    - postgres
    - aws-otel-collector

    postgres:
    image: postgres
    environment:
    - POSTGRES_PASSWORD=petclinic
    - POSTGRES_USER=petclinic
    - POSTGRES_DB=petclinic
    ports:
    - "5432:5432"

    aws-otel-collector:
    image: public.ecr.aws/aws-observability/aws-otel-collector:latest
    environment:
    - AWS_REGION=ap-northeast-1
    - AWS_PROFILE=default
    volumes:
    - ./aws-otel-collector/config.yaml:/etc/otel-agent-config.yaml
    - ./.aws:/root/.aws
    command: ["--config=/etc/otel-agent-config.yaml"]
    注記

    .aws/configにリージョンの設定を書いていても反映されないようで、AWS_REGIONの指定が必要です。

実行する​

docker compose upで実行し、Spring PetClinicサンプルアプリを操作しましょう。 うまく設定できていると、CloudWatchとX-Rayにデータが表示されます。

  • CloudWatch

カスタムメトリクスが色々登録されています。

image.png

ステータスコードやメソッドやURLなどが確認できます。

image.png

  • X-Ray

トレース情報はX-Rayに登録されます。

image.png

Trace Mapが表示されます。

image.png

データベースへのアクセスがある部分も表示されます。(どういう仕組みだろう。。)

image.png

SQLを実行していることがわかります。

image.png

なんと、どんなクエリを発行したかもわかります。

image.png

エラーになったリクエストは赤色で表示されます。

image.png

Exceptionの内容も確認できます。

image.png

ヒント

AWS Distro for OpenTelemetryによるメトリクスとトレース情報の取得を試してみました。 Javaのアプリケーションには一切手を入れずに収集できました!すごいですね。

参考サイト​

今回試したソースコードはGitHubに格納しています。