🪐

Spring Boot + Prometheus + Grafanaでデータ可視化(概要とローカル環境構築編)

2024/02/24に公開

この記事は

Spring Boot + Prometheus + Grafanaの環境を構築します

全体概要

  • Spring Bootで作成したアプリケーションがメトリックスを(適当なパスに)公開する
  • Prometheusがそのパスを定期的に呼び出す。取得したデータはPrometheus内に保存される
  • Garafanaでデータを可視化する

Spring Bootの設定

以下の2つの依存を追加します。

build.gradle
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-actuator'
  runtimeOnly 'io.micrometer:micrometer-registry-prometheus'
  // ...
}

Spring Initializrを使用する場合は、
Spring Boot ActuatorとPrometheus選択するとよいでしょう。

applicatoin.yamlにactuatorの設定をします。(参考: Spring Boot 本番機能対応)
今回はすべてのactuatorのエンドポイントを公開します。

application.yaml
management:
  endpoints:
    web:
      exposure:
        include: "*"

Springを起動します。

http://localhost:8080/actuator/prometheus
を開きます。

以下のような画面が出てきます。

以下のように表示されている部分を見てみましょう。

# HELP jvm_memory_used_bytes The amount of used memory
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="G1 Survivor Space",} 3742384.0
jvm_memory_used_bytes{area="heap",id="G1 Old Gen",} 1.7818168E7
jvm_memory_used_bytes{area="nonheap",id="Metaspace",} 3.6499712E7
jvm_memory_used_bytes{area="nonheap",id="CodeCache",} 1.0933248E7
jvm_memory_used_bytes{area="heap",id="G1 Eden Space",} 1.048576E7
jvm_memory_used_bytes{area="nonheap",id="Compressed Class Space",} 5205712.0

# HELPの部分はメトリクスの説明、#TYPEの部分はメトリクスの種類(counter, gauge, histogram, summary)を表します。
jvm_memory_used_bytesの部分はメトリクス名、{area="heap",id="G1 Survivor Space",}の部分はラベルと呼ばれます。最後の数値(3742384.0)は現時点での値です。

参考:
https://prometheus.io/docs/concepts/data_model/
https://prometheus.io/docs/concepts/metric_types/

http://localhost:8080/actuator/metrics
も確認しておきましょう。
こちらは、/actuator/prometheusで表示されるメトリクスの一覧が表示されます。

{
  "names": [
    "application.ready.time",
    "application.started.time",
    "disk.free",
    "disk.total",
    "executor.active",
    "executor.completed",
    "executor.pool.core",
    "executor.pool.max",
    "executor.pool.size",
    "executor.queue.remaining",
    // 中略
  ]
}

こちらでSpring Bootの設定が完了です。

もう少し動作を確認してみましょう。前述の

# HELP jvm_memory_used_bytes The amount of used memory
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="G1 Survivor Space",} 3742384.0
jvm_memory_used_bytes{area="heap",id="G1 Old Gen",} 1.7818168E7
jvm_memory_used_bytes{area="nonheap",id="Metaspace",} 3.6499712E7
jvm_memory_used_bytes{area="nonheap",id="CodeCache",} 1.0933248E7
jvm_memory_used_bytes{area="heap",id="G1 Eden Space",} 1.048576E7
jvm_memory_used_bytes{area="nonheap",id="Compressed Class Space",} 5205712.0

こちらの部分はjvmの現在のメモリの使用量を表しています。リロードすると値が変化しますので、確認してみましょう。

次に、適当なjavaのコントローラを作成します。

DemoController.java
@RestController
public class DemoController {
  @GetMapping("/greeting")
  public String greeting() {
    return "Hello";
  }
}

http://localhost:8080/greetingが動作することを確認してください。

http://localhost:8080/actuator/prometheusを開き、以下の行が追加されていることを確認してみましょう。

http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/greeting",} 1.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/greeting",} 0.0118966

もう一度
http://localhost:8080/greetingにリクエストを送ると、

http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/greeting",} 2.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/greeting",} 0.0158103

のように変わります。お気づきの通り、1行目は/greetingが呼ばれるたびに1カウントアップします。2行目は累積時間です。

PrometheusとGrafanaの設定と起動

Dockerを使用してPrometheusとGrafanaのセットアップを行います。

ディレクトリ構成はこのようになっています。

prometheus.yml

prometheusに、アプリの情報を登録します。

scrape_configs:
  - job_name: 'SampleJob'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['host.docker.internal:8080']
        labels:
          application: 'prometheus-demo'

以下が簡単な説明です。

名前 説明
job_name このjobの名前です
metrics_path メトリクスを公開しているパスです
scrape_interval メトリクスを取得する間隔です。上記であれば5秒に1回メトリクスを取得します
targets メトリクス取得対象のサーバのホスト名です
labels 上記であれば、application:"prometheus-demo" というラベルをすべてのメトリクスに追加します

datasources.yml

Grafanaに、prometheusの情報を登録します。

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true

docker-compose.yml

docker-compose.ymlを作成します。

docker-compose.yml
version: '3.8'

services:
  prometheus:
    image: prom/prometheus:v2.45.3
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana-oss:10.3.3
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources

起動してください。

docker compose up

Prometheus

Prometheusの動作確認をします。

http://localhost:9090/graphを開きます。以下のような画面が表示されます。Open metrics exploerをクリックしてみましょう。

メトリクス一覧が表示されます。

jvm_memory_used_bytesを選択して、Executeを押してみましょう。
Graphにメモリの使用量が表示されます。

次に、
http://localhost:8080/greeting
に何度かアクセスしておきます。

http_server_requests_seconds_count
を選択します。

*_countは、アプリが起動してからの累計なので、このようなグラフになっています。
単位時間(以下の例では30秒)あたりの、1秒あたりの平均値を表示するには、rate関数を使います。メトリクスを以下のように変更します。

rate(http_server_requests_seconds_count[30s])

Grafana

Grafanaでグラフを表示します。Prometheusでもグラフは表示できますが、Grafanaのほうが柔軟な設定が可能です。

http://localhost:3000/
を開きます。ユーザ名とパスワードは両方"admin"です。

ダッシュボードを作成します。
右上の"+"をクリックし"New Dashboardを選択します"

"Add visualization"をクリックします。

データソースは、"Prometheus"を選択します。(先ほどdatasource.ymlにて設定した内容が表示されています)

先ほどPrometheusで表示した内容を、Grafanaで表示してみます。
Metricで"jvm_memory_used_bytes"を選択します。

"Run Queries"でどのように表示されるか確認できます。

Titleを設定しておくとよいでしょう。

Y軸の単位を設定すると見やすくなります。

Applyを押すと、ダッシュボードに戻ります。
"Add > Visualization" をクリックし、グラフを追加します。

同様に、

http_server_requests_seconds_count
を選択します。
Operationで"rate"を選択します。

(Codeモードでrate(http_server_requests_seconds_count[$__rate_interval])と入力してもよいです)

$__rate_intervalは、Grafanaの変数で、適当な時間を選択してくれます。

以上で基本的なGrafanaの設定は終了です。
内容が消えてほしくない場合はSaveボタンを押しておきましょう。

参考

環境

Spring Boot: 3.2.2
Java: 17
Prometheus: v2.45.3
Grafana: 10.3.3

Discussion