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

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_USERPOSTGRES_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.yamlenvironmentに以下を追加する。

          - 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)を作成する

    ポリシーはCloudWatchFullAccessAWSXrayFullAccessをアタッチします。

  2. config.yamlを作成する

    AWS Distro for OpenTelemetry Collectorの設定ファイルです。 受け取ったtracesawsxray(X-Ray)に、metricsawsemf(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.yamlservices配下に追加

      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に格納しています。