Spring Batch + Prometheus + Pushgateway + Grafana + Dockerでアプリケーション監視

Spring BatchにPushgateway、Prometheus、Grafanaを連携する

Spring Batch + Prometheus + Pushgateway + Grafana + Docker

概要

Prometheusは基本的に、メトリクス指標を提供するサーバーへ周期的にリクエスト(pull)してメトリクスを収集する。

しかし、Spring BatchのようにCLI形式で周期的に実行されるだけの場合がある。このような場合は個別のIPがないため、周期的なPolling方式ではなく、Prometheusへメトリクスを逆にPushできるようにする必要がある。メトリクスのPushを支援するのがPushgatewayである。

Pushgateway

Prometheusが提供するPushgatewayは、メトリクスをPushできるようにし、PushされたメトリクスをPrometheusがPullingして取得できるようにする仲介者の役割を果たす。この構造により、PushgatewayへPushされたメトリクスをPrometheusが取得できる。

Pushgateway

Spring Batchプロジェクト作成

新規プロジェクト作成コマンド

次のようにcurlコマンドを使用してSpring Bootの新規プロジェクトを作成する。

curl https://start.spring.io/starter.tgz \
-d bootVersion=2.7.6 \
-d dependencies=batch,h2 \
-d baseDir=spring-batch-prometheus \
-d groupId=com.devkuma \
-d artifactId=spring-batch-prometheus \
-d packageName=com.devkuma.batch.prometheus \
-d applicationName=BatchPrometheusApplication \
-d javaVersion=11 \
-d packaging=jar \
-d type=gradle-project | tar -xzvf -

上記コマンドを実行するとSpring Batch、H2 Databaseが追加される。

Spring Batch設定

/src/main/java/com/devkuma/batch/prometheus/BatchPrometheusApplication.java

package com.devkuma.batch.prometheus;

import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
@EnableBatchProcessing
public class BatchPrometheusApplication {

	public static void main(String[] args) {
		SpringApplication.run(BatchPrometheusApplication.class, args);
	}
}

@EnableBatchProcessingアノテーションを追加してバッチ機能を有効化し、@EnableSchedulingアノテーションも追加してスケジューラ機能を有効化した。

Prometheus関連ライブラリ追加

/build.gradle

// ... 省略 ...

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-batch'
	runtimeOnly 'com.h2database:h2'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.batch:spring-batch-test'

    // Prometheus関連ライブラリ追加
	implementation 'io.micrometer:micrometer-registry-prometheus'
	implementation 'io.prometheus:simpleclient_pushgateway'
}

// ... 省略 ...

ファイル内の依存ライブラリを見ると、Spring Batch関連ライブラリとPrometheusおよびPushgatewayライブラリが追加されていることが分かる。

Tasklet処理方式のJob構成を実装

簡単なTasklet処理方式のJob構成ファイルを追加する。

/src/main/java/com/devkuma/batch/prometheus/batch/TaskletStepJobConfiguration.java

package com.devkuma.batch.prometheus.batch;

import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TaskletStepJobConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(TaskletStepJobConfiguration.class);

    private Random random;

    public TaskletStepJobConfiguration() {
        this.random = new Random();
    }

    @Bean
    public Job taskletStepJob(JobBuilderFactory jobBuilderFactory, Step taskletStep1, Step taskletStep2) {
        return jobBuilderFactory.get("taskletStepJob")
                                .start(taskletStep1)
                                .next(taskletStep2)
                                .build();
    }
}

itemReader、itemWriter処理方式のJob構成を実装

簡単なitemReader、itemWriter処理方式のJob構成ファイルを作成する。

/src/main/java/com/devkuma/batch/prometheus/batch/ItemStepJobConfiguration.java

package com.devkuma.batch.prometheus.batch;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ItemStepJobConfiguration {
    // itemReader and itemWriter configuration
}

Jobスケジューラ作成

ここでは必ずしもスケジューラは必要ないが、グラフをより見やすくするため、周期的にデータを送るJobスケジューラを作成する。

/src/main/java/com/devkuma/batch/prometheus/batch/JobScheduler.java

package com.devkuma.batch.prometheus.batch;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class JobScheduler {
    // Run taskletStepJob every 10 seconds and itemStepJob every 15 seconds
}

続いて、thread.pool.sizeも設定ファイルへ入れる。
/src/main/resources/application.properties

thread.pool.size=3

前で入れたthread.pool.sizeを使用してThreadPoolTaskScheduler設定ファイルを作成する。

Prometheus設定

次にPrometheus設定を行う。
/src/main/resources/application.properties

prometheus.push.rate=5000
prometheus.job.name=springbatch
prometheus.grouping.key=appname
prometheus.pushgateway.url=localhost:9091

Prometheusのpush周期、Job名、グループキーを入れる。そしてPushgateway URLを設定する。

設定したPrometheus設定値を設定オブジェクトへ反映する。
/src/main/java/com/devkuma/batch/prometheus/config/PrometheusConfiguration.java

package com.devkuma.batch.prometheus.config;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;

import io.micrometer.core.instrument.Metrics;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.PushGateway;

@Configuration
public class PrometheusConfiguration {
    // Configure PushGateway and periodically push metrics
}

Prometheus + Pushgateway + GrafanaサーバーをDockerで起動

次にDockerでPrometheus + Pushgateway + Grafanaサーバーを起動するため、docker-compose.ymlを作成し、Prometheus設定を行う。

docker-compose.yml設定ファイル

/src/prometheus/docker-compose.yml

version: '3.7'
services:

  prometheus:
    image: prom/prometheus
    container_name: 'prometheus'
    ports:
      - '9090:9090'
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml

  pushgateway:
    image: prom/pushgateway
    container_name: 'pushgateway'
    ports:
      - '9091:9091'

  grafana:
    image: grafana/grafana
    container_name: 'grafana'
    ports:
      - '3000:3000'

prometheus.yml設定ファイル

/src/docker/prometheus/prometheus.yml

global:
  scrape_interval:     5s
  evaluation_interval: 5s

scrape_configs:
  - job_name: 'springbatch'
    honor_labels: true
    static_configs:
      - targets: ['host.docker.internal:9091'] # pushgateway

テスト環境がmacOSのためPushgatewayのURLをhost.docker.internal:9091としているが、Linuxなどでは異なる場合がある。テスト環境に合わせてURLを入力する。

Docker起動

% cd src/prometheus
% docker-compose up -d

接続実行

  • Pushgateway

    • http://localhost:9091
  • Prometheus

    • http://localhost:9090
  • Grafana

    • http://localhost:3000
      • 基本アカウントID/PW: admin/admin

Pushgateway収集情報確認

Pushgateway(http://localhost:9091)にアクセスすると、spring-batchで収集された情報を確認できる。
Pushgateway収集情報

Prometheus収集情報確認

Prometheus(http://localhost:9090)にアクセスすると、Pushgatewayを通じて受け取ったspring-batchで収集された情報を確認できる。
Prometheus収集情報

Grafana設定

では、spring-batchで収集された情報をGrafanaを通じてより視覚的に表示してみる。

Grafanaデータソース設定

まずデータソースを追加する。
Grafana設定

データソースとしてPrometheusを選択する。
Grafana設定

PrometheusのData Source追加画面が表示されたら、NameURLを入力する。
ここでは実装環境がmacOSなのでURLにはhttp://host.docker.internal:9090を入力したが、Linux環境などでは異なる場合があるので注意してほしい。
Grafana設定

Grafana設定

Grafanaダッシュボード設定および確認

続いてダッシュボード設定をImportで追加する。
Grafanaダッシュボード設定

用意されたImport JSONファイル(spring-batch-dashboard.json)を選択する。
Grafanaダッシュボード設定

内容を確認し、Importをクリックする。
Grafanaダッシュボード設定

ダッシュボード画面へ移動すると、spring-batchメトリクス情報がグラフで見えることを確認できる。
Grafanaダッシュボード確認

参考


上記のサンプルコードはGitHubで確認できる。