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サンプルアプリを起動させます。
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"]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起動
docker compose up
ブラウザで
http://localhost:8080
にアクセスします。- HOME画面
- FIND OWNERS画面
- VETERINARIANS画面
- ERROR画面
わざと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を追加していきます。 大きく以下の手順を実行します。
- Spring PetClinicサンプルアプリに
OpenTelemetry Agent for Java
を追加する AWS Distro for OpenTelemetry Collector
コンテナを追加する
1. Spring PetClinicサンプルアプリにOpenTelemetry Agent for Javaを追加する
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"]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=truedocker-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コンテナを追加する
AWS認証情報(
.aws/config
、.aws/credentials
)を作成するポリシーは
CloudWatchFullAccess
とAWSXrayFullAccess
をアタッチします。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]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
カスタムメトリクスが色々登録されています。
ステータスコードやメソッドやURLなどが確認できます。
- X-Ray
トレース情報はX-Rayに登録されます。
Trace Mapが表示されます。
データベースへのアクセスがある部分も表示されます。(どういう仕組みだろう。。)
SQLを実行していることがわかります。
なんと、どんなクエリを発行したかもわかります。
エラーになったリクエストは赤色で表示されます。
Exceptionの内容も確認できます。
AWS Distro for OpenTelemetryによるメトリクスとトレース情報の取得を試してみました。 Javaのアプリケーションには一切手を入れずに収集できました!すごいですね。
参考サイト
- AWS Distro for OpenTelemetry
- AWS Distro for OpenTelemetry Collector
- Spring PetClinic Sample Application
- Containerizing a Legendary PetClinic App Built with Spring Boot
今回試したソースコードはGitHubに格納しています。