Spring Boot 2.0 でモニタリング 〜Micrometer〜

Spring Boot 2.0が今月頭2018/3/1にリリースされましたね！
https://spring.io/blog/2018/03/01/spring-boot-2-0-goes-ga

[前々回](https://qiita.com/AHA_oretama/items/984f8f63ac95a7192174)、[前回](https://qiita.com/AHA_oretama/items/533970a9d462d0971e5f)に引き続き、今回もアプリケーションモニタリングの話、Spring Boot 2.0でモニタリングがどうなったかをお話します。

# リリースノート

モニタリング部分は、Spring Boot 2.0 の[リリースノート](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes)の[Micrometerのチャプター](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes#micrometer)にあたります。
Spring Boot 2.0からMicrometerというものがメトリックスのベース部分として採用されました。
では、まずMicrometerがどういったものか見ていきたいと思います。


# Micrometer

正直、私自身は[Micrometer](https://micrometer.io/)は初耳でした。
トップページの説明文を見ると、

> Micrometer provides a simple facade over the instrumentation clients for the most popular monitoring systems, allowing you to instrument your JVM-based application code without vendor lock-in. Think SLF4J, but for metrics.

とあります。

いろいろなモニタリングツールがあるので、Micrometerはそれを意識せずに使える共通的なインタフェースを提供してくれるものというのが私の理解です。

いま現在サポートしているモニタリングツールは以下で、メジャーなものはサポートされているようです。
これらのものは統一的なインタフェースと簡単な設定でモニタリングが開始できるようです。

* [Atlas](https://github.com/Netflix/atlas)
* [Datadog](https://www.datadoghq.com/)
* [Ganglia](http://ganglia.sourceforge.net/)
* [Graphite](https://graphiteapp.org/)
* [Influx](https://www.influxdata.com/)
* JMX
* [New Relic](https://newrelic.com/)
* [Prometheus](https://prometheus.io/)
* [SignalFx](https://signalfx.com/)
* [StatsD](https://github.com/etsy/statsd)
* [Wavefront](https://www.wavefront.com/)

# モニタリングの実装

さて、それでは実際にモニタリングの実装をしていきたいと思います。
Spring Boot 2.0からMicrometerがデフォルトで追加されるようになったため、実装自体は簡単にできそうです。

いろいろ確認しながら、今回はPrometheusでのモニタリングを実装していきます。進めていく手順は以下を参考にですね。

* https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready-metrics
* https://micrometer.io/docs/registry/prometheus

まずSpring Boot Actuatorを`dependency`に追加します。
Spring Boot 2.0から`spring-boot-actuator-starter`にメトリックスのベース部分となる[Micrometer](https://micrometer.io/)が追加されているためです。

**↓1.5.10.RELEASE**
<img width="724" alt="スクリーンショット 2018-03-02 18.08.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/110216/c8793876-1fb5-d926-f60e-440bacd5ab18.png">


**↓2.0.0.RELEASE**
<img width="726" alt="スクリーンショット 2018-03-02 18.08.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/110216/c093bc03-ace1-0d77-feae-0c06d5340817.png">

たしかにMicrometerが追加されていますね。

それに加えて、pom.xmlに対象のモニタリングツール(今回は`micrometer-registry-prometheus`)の`dependency`を追加します。
（今回はWEBアプリケーションを想定して、`spring-boot-starter-web`も追加しています。）

```xml:pom.xml
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>io.micrometer</groupId>
			<artifactId>micrometer-registry-prometheus</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
```



バージョンの記載は`spring-boot-starter-parent`で管理されているので不要なはず。
　　↓
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-dependencies/pom.xml#L123


`dependency`の追加により、Prometheus用にAuto-configuratedされます。
`PrometheusMetricsExportAutoConfiguration `クラスの`@ConditionalOnClass({PrometheusMeterRegistry.class})`の条件が満たされるためです。

```java:PrometheusMetricsExportAutoConfiguration.java
@Configuration
@AutoConfigureBefore({CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class})
@AutoConfigureAfter({MetricsAutoConfiguration.class})
@ConditionalOnBean({Clock.class})
@ConditionalOnClass({PrometheusMeterRegistry.class})
@ConditionalOnProperty(
    prefix = "management.metrics.export.prometheus",
    name = {"enabled"},
    havingValue = "true",
    matchIfMissing = true
)
@EnableConfigurationProperties({PrometheusProperties.class})
public class PrometheusMetricsExportAutoConfiguration {
    ...

    @ManagementContextConfiguration
    public static class PrometheusScrapeEndpointConfiguration {
        ...
    }    
}
```

PrometheusはPull側なので、エンドポイント`/actuator/prometheus`が追加されます。
エンドポイントの追加は、`PrometheusMetricsExportAutoConfiguration`の内部クラスである、`PrometheusScrapeEndpointConfiguration`が設定を行っています。

セキュリティの観点からデフォルトではActuator関連のエンドポイントは一部しか公開されていないので、propertyファイルに設定を追加して、エンドポイントを公開します。

```properties:application.properties
management.endpoints.web.exposure.include=prometheus
```

これだけで、Prometheus用のモニタリング設定は完了です。
Spring BootアプリケーションをRunして、`http://localhost:8080/prometheus`にアクセスすると、モニタリング情報が表示されます。

# Prometheusで可視化

PrometheusにはDockerを使ってしまいます。
以下のようにprometheus.ymlを用意して、`docker run`してしまいます。

```yml:prometheus.yml
# A scrape configuration containing exactly one endpoint to scrape:
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'spring-boot-2.0'

    # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s

    # List of labeled statically configured targets for this job.
    static_configs:
      - targets: ['your_ip:8080'] # 1

    # The HTTP resource path on which to fetch metrics from targets.
    metrics_path: /actuator/prometheus # 2
```

```bash
$ docker run -p 9090:9090 -v path_prometheus_yml:/etc/prometheus/prometheus.yml prom/prometheus
```

少し補足しておきます。

1. DockerからホストのSpring Bootアプリケーションにアクセスするため、localhostではなく、IP指定でのアクセスが必要になります。
2. メトリックスのエンドポイントを指定しています。


これで、`http://localhost:9090/`にアクセスすればPrometheusが起動できています。

あとはGUI上で、取りたいメトリックスを指定すればOKです。これは`jvm_classes_loaded`を指定した例になります。

<img width="1225" alt="スクリーンショット 2018-03-07 20.39.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/110216/412e48c3-894b-b02a-f341-eafb96aaf5a8.png">

# 補足

今回は触れませんでしたが、特定のアプリケーションのメトリックス（例えば、来店人数を数えるようなCounterメトリックス）を、モニタリングツールに依らない形式で実装方法は以下を参照してください。

https://micrometer.io/docs/concepts

またSpring Boot 1.5でもMircrometerへの対応方法が書いてあるので、まだ2.0に上げていない場合は参考にしてください。

https://micrometer.io/docs/ref/spring/1.5

# GitHub

いつものようにサンプルをGitHub上にアップしてあるので参考にしてください。

https://github.com/aha-oretama/spring-boot-2.0-prometheus-metrics


# 最後に

Spring Boot 2.0がリリースされて本当に嬉しいし、早く全貌をキャッチアップ＆使いたおしたいところです。
アプリケーションのモニタリングについては、今までは実装するのが少し大変でアプリケーションごとに工夫していた気がします（例えば、[前々回](https://qiita.com/AHA_oretama/items/984f8f63ac95a7192174)、[前回](https://qiita.com/AHA_oretama/items/533970a9d462d0971e5f)）。
しかし、今後はMicrometerがSpring Bootでのモニタリングのデファクトスタンダードになっていくので、簡単に使えるようになって嬉しい限りです。