かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その14 )( Docker コンテナの image をバージョンアップする、Spring Boot Statistics のデータが表示されていない Panel を修正する+Dashboard に JVM (Micrometer) を追加する )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その13 )( Docker コンテナの image をバージョンアップする、Grafana の RabbitMQ 用の Dashboard を RabbitMQ Monitoring → RabbitMQ-Overview に切り替える ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Grafana の Dashboard の Spring Boot Statistics にデータが表示されていない Panel があるので表示されるように修正します。
    • Grafana の DashboardJVM (Micrometer) を追加します。

参照したサイト・書籍

  1. Actuator metrics do not include http.server.requests
    https://stackoverflow.com/questions/60345738/actuator-metrics-do-not-include-http-server-requests

  2. micrometer-metrics / micrometer
    https://github.com/micrometer-metrics/micrometer

  3. Spring Boot default metrics
    https://tomgregory.com/spring-boot-default-metrics/

目次

  1. Spring Boot Statistics のデータが表示されていない Panel を修正する
    1. Process Open Files
    2. $memory_pool_nonheap (non-heap)
    3. Classes Loaded、Classes Unloaded
    4. Threads
    5. 「HikariCP Statistics」の下の全ての Panel
    6. 「HTTP Statistics」の下の全ての Panel
    7. 「Tomcat Statistics」の下の全ての Panel
  2. Dashboard に JVM (Micrometer) を追加する

手順

Spring Boot Statistics のデータが表示されていない Panel を修正する

docker-compose up -d コマンドでコンテナを起動+IntelliJ IDEA から Web アプリを起動して作業します。

Process Open Files

Edit 画面で参照している metrics を確認すると process_files_openprocess_files_max の2つでした。

f:id:ksby:20201220164659p:plain

http://localhost:8080/actuator/prometheus にアクセスして出力されている metrics を確認してみましたが、どちらもありません。。。

調べていた時に Actuator metrics do not include http.server.requests を見つけました。/acutator/metrics という endpoint があるらしく、この endpoint にアクセスすると取得可能な metrics 一覧が出力されますが process_files_open ではなく process.files.open と表示されるようです。

micrometer-metrics / micrometerprocess.files.open で検索してみると micrometer/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/system/FileDescriptorMetrics.java がヒットしましたが、この中に this.osBeanClass = getFirstClassFound(UNIX_OPERATING_SYSTEM_BEAN_CLASS_NAMES); というコードがありました。おそらく Web アプリを Unix 系の OS で動作させた時しか process_files_openprocess_files_max は取れないのでしょう。

試してみます。まず /acutator/metrics の endpoint を使用できるようにするために src/main/resources/application.properties の management.endpoints.web.exposure.include に metrics を追加します。

..........

management.endpoints.web.exposure.include=health,info,loggers,prometheus,metrics
management.metrics.tags.application=lending
..........

コンテナで Web アプリを起動する時の JDK を AdoptOpenJDK 11.0.9.1+1 にします。docker/app/Dockerfile の以下の点を変更します。

FROM adoptopenjdk/openjdk11:jdk-11.0.9.1_1-alpine-slim
RUN apk add --no-cache tzdata
ENV TZ="Asia/Tokyo"
ENV LANG="ja_JP.UTF-8"
VOLUME /tmp
EXPOSE 8080
ENTRYPOINT ["docker-entrypoint.sh"]
  • FROM adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine-slimFROM adoptopenjdk/openjdk11:jdk-11.0.9.1_1-alpine-slim に変更します。

app コンテナを起動する時の jar ファイルを ksbysample-webapp-lending-2.3.7-RELEASE.jar にします。docker-compose.app.yml の以下の点を変更します。

  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    image: ksbysample-webapp-lending
    volumes:
      - ./build/libs/ksbysample-webapp-lending-2.3.7-RELEASE.jar:/app.jar
      - ./docker/app/docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh
    environment:
      - SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://postgresql/ksbylending
      - SPRING_MAIL_HOST=mail-server
      - SPRING_RABBITMQ_HOST=haproxy
    deploy:
      mode: replicated
      replicas: 3
    # entrypoint: /bin/sh
    # stdin_open: true
    # tty: true

  haproxy-app:
    image: haproxy:2.3.2-alpine
    container_name: haproxy-app
    volumes:
      - ./docker/app/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
    ports:
      - "8080:8080"
    depends_on:
      - app
  ..........
  • app コンテナの volumes の設定で - ./build/libs/ksbysample-webapp-lending-2.2.2-RELEASE.jar:/app.jar- ./build/libs/ksbysample-webapp-lending-2.3.7-RELEASE.jar:/app.jar に変更します。
  • haproxy-app コンテナの image の設定で haproxy:2.1.2-alpinehaproxy:2.3.2-alpine に変更します。

以下の手順で Alpine Linux 上で Web アプリを起動します。

  1. Gradle の build コマンドで ksbysample-webapp-lending-2.3.7-RELEASE.jar を生成する。
  2. docker-compose -f docker-compose.app.yml --compatibility build --no-cache コマンドを実行して app コンテナ起動用の Docker image を作成する。
  3. docker-compose -f docker-compose.mail.yml up -d コマンドを実行してメールサーバのコンテナを起動する。
  4. docker-compose -f docker-compose.app.yml --compatibility up -d コマンドを実行して app コンテナを起動する。

http://localhost:8080/actuator/metrics にアクセスすると以下の JSON が出力され、process.files.openprocess.files.max が入っていました。

{
  "names": [
    "hikaricp.connections",
    "hikaricp.connections.acquire",
    "hikaricp.connections.active",
    "hikaricp.connections.creation",
    "hikaricp.connections.idle",
    "hikaricp.connections.max",
    "hikaricp.connections.min",
    "hikaricp.connections.pending",
    "hikaricp.connections.timeout",
    "hikaricp.connections.usage",
    "http.server.requests",
    "jdbc.connections.active",
    "jdbc.connections.idle",
    "jdbc.connections.max",
    "jdbc.connections.min",
    "jvm.buffer.count",
    "jvm.buffer.memory.used",
    "jvm.buffer.total.capacity",
    "jvm.classes.loaded",
    "jvm.classes.unloaded",
    "jvm.gc.live.data.size",
    "jvm.gc.max.data.size",
    "jvm.gc.memory.allocated",
    "jvm.gc.memory.promoted",
    "jvm.gc.pause",
    "jvm.memory.committed",
    "jvm.memory.max",
    "jvm.memory.used",
    "jvm.threads.daemon",
    "jvm.threads.live",
    "jvm.threads.peak",
    "jvm.threads.states",
    "logback.events",
    "process.cpu.usage",
    "process.files.max",
    "process.files.open",
    "process.start.time",
    "process.uptime",
    "rabbitmq.acknowledged",
    "rabbitmq.acknowledged_published",
    "rabbitmq.channels",
    "rabbitmq.connections",
    "rabbitmq.consumed",
    "rabbitmq.failed_to_publish",
    "rabbitmq.not_acknowledged_published",
    "rabbitmq.published",
    "rabbitmq.rejected",
    "rabbitmq.unrouted_published",
    "system.cpu.count",
    "system.cpu.usage",
    "system.load.average.1m",
    "tomcat.sessions.active.current",
    "tomcat.sessions.active.max",
    "tomcat.sessions.alive.max",
    "tomcat.sessions.created",
    "tomcat.sessions.expired",
    "tomcat.sessions.rejected"
  ]
}

ただし Prometheus の画面で検索すると process_files_open はなく process_files_open_files になっていました。process_files_maxprocess_files_max_files でした。

f:id:ksby:20201220192823p:plain f:id:ksby:20201220192920p:plain

Edit 画面で参照する metrics を process_files_open_filesprocess_files_max_files に変更すると「Process Open Files」に metrics が表示されるようになりました。

f:id:ksby:20201220193344p:plain f:id:ksby:20201220193643p:plain

$memory_pool_nonheap (non-heap)

Edit 画面で参照している metrics を確認すると以下の Query が記述されていました。

  • jvm_memory_used_bytes{instance="$instance", application="$application", id="$memory_pool_nonheap"}
  • jvm_memory_committed_bytes{instance="$instance", application="$application", id="$memory_pool_nonheap"}
  • jvm_memory_max_bytes{instance="$instance", application="$application", id="$memory_pool_nonheap"}

f:id:ksby:20201220200956p:plain

Query で使用されている Variable $memory_pool_nonheap の定義を見ると以下のようになっていました。「Preview of values」に値が複数表示されています。

f:id:ksby:20201220201212p:plain

Query で参照している Variable $memory_pool_nonheap が復数の値を返すのに、Query で単一の値が返る想定の記述がされているのが原因でした。 id="$memory_pool_nonheap"id=~"$memory_pool_nonheap" のように変更することにします。

f:id:ksby:20201220202727p:plain f:id:ksby:20201220202822p:plain

Classes Loaded、Classes Unloaded

Edit 画面で参照している metrics を確認すると以下の Query が記述されていました。

  • irate(jvm_classes_unloaded_total{instance="$instance", application="$application"}[5m])
  • jvm_classes_loaded{instance="$instance", application="$application"}

f:id:ksby:20201220212717p:plain f:id:ksby:20201220212821p:plain

Prometheus の画面で確認すると jvm_classes_unloaded_totaljvm_classes_unloaded_classes_totaljvm_classes_loadedjvm_classes_loaded_classes に変更されていました。

f:id:ksby:20201220213304p:plain f:id:ksby:20201220213412p:plain

Edit 画面で参照している metrics を修正します。

f:id:ksby:20201220213838p:plain f:id:ksby:20201220214455p:plain

f:id:ksby:20201220214234p:plain f:id:ksby:20201220214600p:plain

Threads

Edit 画面で参照している metrics を確認すると以下の Query が記述されていました。

  • jvm_threads_daemon{instance="$instance", application="$application"}
  • jvm_threads_live{instance="$instance", application="$application"}
  • jvm_threads_peak{instance="$instance", application="$application"}

f:id:ksby:20201220215532p:plain

Prometheus の画面で確認すると jvm_threads_daemonjvm_threads_daemon_threadsjvm_threads_livejvm_threads_live_threadsjvm_threads_peakjvm_threads_peak_threads に変更されていました。

f:id:ksby:20201220215928p:plain f:id:ksby:20201220220042p:plain f:id:ksby:20201220220139p:plain

Edit 画面で参照している metrics を修正します。

f:id:ksby:20201220220421p:plain f:id:ksby:20201220220539p:plain

「HikariCP Statistics」の下の全ての Panel

今見たら表示されていました。IntelliJ IDEA から Web アプリを起動している時は表示されず、jar ファイルから起動している時は表示される metrics でした(Windows でも Linux でも表示されました)。

「HTTP Statistics」の下の全ての Panel

こちらも今見たら表示されていました。IntelliJ IDEA から Web アプリを起動している時は表示されず、jar ファイルから起動している時は表示される metrics でした(Windows でも Linux でも表示されました)。

Tomcat Statistics」の下の全ての Panel

Edit 画面で参照している metrics を確認すると以下の Query が記述されていました。

f:id:ksby:20201220224040p:plain

  • Total Error Count
    • tomcat_global_error_total{instance="$instance", application="$application"}
  • Thread Config Max
    • tomcat_threads_config_max{instance="$instance", application="$application"}
  • Active Sessions
    • tomcat_sessions_active_current{instance="$instance", application="$application"}
  • Sent & Recieved Bytes
    • irate(tomcat_global_sent_bytes_total{instance="$instance", application="$application"}[5m])
    • irate(tomcat_global_received_bytes_total{instance="$instance", application="$application"}[5m])
  • Threads
    • tomcat_threads_current{instance="$instance", application="$application"}
    • tomcat_threads_busy{instance="$instance", application="$application"}

Prometheus の画面で確認すると tomcat_sessions_active_currenttomcat_sessions_active_current_sessions に変更すれば良いのですが、それ以外の metrics はそもそも出力されていませんでした。

Web で検索すると Disable Tomcat's MBean Registry by default and provide a property to enable it の Issue が見つかり、Spring Boot の Manual の Common Application properties の 11. Server Propertiesserver.tomcat.mbeanregistry.enabled が見つかりました。default は false なので true にすれば良いようです。

src/main/resources/application.properties に server.tomcat.mbeanregistry.enabled=true を追加します。

..........

management.endpoints.web.exposure.include=health,info,loggers,prometheus,metrics
management.metrics.tags.application=lending
management.endpoint.health.show-details=always
management.endpoint.health.probes.enabled=true
management.endpoint.health.group.liveness.include=livenessStateProbeIndicator,cacheCheck
management.endpoint.health.group.readiness.include=readinessStateProbeIndicator,cacheCheck
server.tomcat.mbeanregistry.enabled=true

..........

Gradle の build タスクを実行して jar ファイルを作成し直した後、docker-compose -f docker-compose.app.yml --compatibility downdocker-compose -f docker-compose.app.yml --compatibility up -d コマンドを実行して app コンテナを再起動します。

最後に Grafana の Edit 画面で参照する metrics を以下のように変更すると表示されるようになりました。

  • Total Error Count
    • tomcat_global_error_total{instance="$instance", application="$application"}
  • Thread Config Max
    • tomcat_threads_config_max_threads{instance="$instance", application="$application"}
  • Active Sessions
    • tomcat_sessions_active_current_sessions{instance="$instance", application="$application"}
  • Sent & Recieved Bytes
    • irate(tomcat_global_sent_bytes_total{instance="$instance", application="$application"}[5m])
    • irate(tomcat_global_received_bytes_total{instance="$instance", application="$application"}[5m])
  • Threads
    • tomcat_threads_current_threads{instance="$instance", application="$application"}
    • tomcat_threads_busy_threads{instance="$instance", application="$application"}

f:id:ksby:20201220232236p:plain

DashboardJVM (Micrometer) を追加する

「Import」画面で「Import via grafana.com」に 4701 を入力して import します。

f:id:ksby:20201220235011p:plain f:id:ksby:20201220235102p:plain

JVM (Micrometer) の画面が表示されます(面倒なので画面キャプチャは1画面目のみ)。

f:id:ksby:20201220235253p:plain

履歴

2020/12/20
初版発行。