これは、なにをしたくて書いたもの?
- メトリクスやモニタリングまわりにあまり勘所がないので、少しずつ試してみようと
- Spring Bootを使っていると、Micrometerというものが便利らしいので、まずはこれを
- メトリクスの収集にはPrometheusを、可視化にはGrafanaを試してみようと
全部に言えますが、「初めてやってみました」エントリです。
Spring BootにMicrometerを入れ、Prometheusでメトリクスを収集し、Grafanaで可視化するまでの最低限のことを
やっていきます。
Micrometer?
Micrometerとは、Javaでメトリクスを取得できるようにするベンダー非依存のライブラリです。
Micrometer Application Monitoring
Prometheus、AWS CloudWatch、Datadog、New Relicなど、いろいろなメトリクス収集・モニタリング・監視ソフトウェア、サービスに
取得したメトリクスを送信したりできるようになります。
Spring Bootで使うと、これが非常に簡単に使えるようになるらしいです。
Spring Boot 2.0 でモニタリング 〜Micrometer〜 - Qiita
Spring Boot で micrometer を使ってメトリクスを計測・送信する - k11i.biz
Spring BootアプリのメトリクスをMicrometerで収集する #micrometer · matsumanaの技術メモ
Spring Boot Actuator 2.0 & Micrometer
Prometheus?
Prometheusは、メトリクス収集や監視を行うソフトウェアです。
Prometheus - Monitoring system & time series database
メトリクスの収集は、Prometheusから対象へPullする(取得しに行く)方向になります。
可視化や、アラート通知も可能なようです。
Grafana?
Grafanaは、メトリクスなどを可視化し、アラート通知なども行えるソフトウェアです。
Grafana - The open platform for analytics and monitoring
可視化などの元なるデータの取得先となるソフトウェアは、いろいろと対応しているようです。
Prometheus、AWS CloudWatch、Elasticsearch、Datadog、MySQL、PostgreSQLなどなど…。
オープンソースの運用管理・運用自動化 / Grafanaとは
ダッシュボードを作ることができ、そこでグラフなどの表示ができます。
合わせて
で、このあたりを組み合わせて運用していくわけですね。
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
PrometheusとGrafanaを組み合わせて監視用ダッシュボードを作る | さくらのナレッジ
prometheusとgrafanaを入れたみたが、どうグラフとか出すといいのか? - Qiita
prometheus のデータを grafana でグラフ表示してみた - Qiita
Prometheus+Grafanaでパフォーマンス監視をしています - Keepdata Blog
ここからは、最初に書いたとおり、Micrometer、Prometheus、Grafanaを使って、あまり難しいこと(カスタマイズ、拡張とか)を
考えずに、最低限これらをつなげて可視化できるまでを目標にしていきます。
環境
稼働させるアプリケーション、サーバーは、いずれもDocker上で行うものとします。
IPアドレスとしては、
- Spring Boot+Micrometer … 172.17.0.2
- Prometheus … 172.17.0.3
- Grafana … 172.17.0.4
としたいと思います。
Java側の環境は、こちら。
$ java -version openjdk version "1.8.0_191" OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-0ubuntu0.18.04.1-b12) OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode) $ mvn -version Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-25T03:41:47+09:00) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 1.8.0_191, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-8-openjdk-amd64/jre Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "4.15.0-39-generic", arch: "amd64", family: "unix"
PrometheusとGrafanaは、Dockerを使って立ち上げることにしましょう。
Prometheusのバージョンは2.5.0、Grafanaのバージョンは5.3.4を使用します。
Spring Boot+Micrometerのアプリケーションを用意する
では、まずはメトリクス収集対象となる、Spring Boot+Micrometerを使ったアプリケーションを書いていきましょう。
Maven依存関係などは、こちら。
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.1.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.1.1.RELEASE</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
アプリケーションは、Spring Web MVCで書くことにします。
Spring BootでMicrometerを使うには、「spring-boot-starter-actuator」とメトリクスを収集するソフトウェアに応じた
「micrometer-registry-〜」が必要です。今回は、Prometheusを使うので「micrometer-registry-prometheus」を加えます。
Spring Boot Actuator: Production-ready features
https://github.com/micrometer-metrics/micrometer-samples-spring-boot/blob/master/build.gradle
Micrometerを依存関係に加えた時に、追加される情報はこのあたりを見るのではないでしょうか。
Spring Web MVCを使った場合に取得できるメトリクスも、追加されます。
では、起動クラスとControllerを作成。
src/main/java/org/littlewings/spring/micrometer/App.java
package org.littlewings.spring.micrometer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String... args) { SpringApplication.run(App.class, args); } }
とりあえず、動くコードがあれば良いくらいの感じなので、単純なもので。
src/main/java/org/littlewings/spring/micrometer/HelloController.java
package org.littlewings.spring.micrometer; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("hello") public class HelloController { @GetMapping public String message() { return "Hello World!!"; } }
また、Spring Boot Actuatorのエンドポイントで、Prometheus向けのものを有効にしておく必要があります。
src/main/resources/application.properties
management.endpoints.web.exposure.include=prometheus
あとは、パッケージングして起動。
$ mvn package
実行は、Dockerコンテナ内で。
$ java -jar target/micrometer-prometheus-0.0.1-SNAPSHOT.jar
これで、監視対象のアプリケーション側の準備は完了です。
確認。
$ curl 172.17.0.2:8080/hello Hello World!!
また、Prometheus向けのエンドポイントにアクセスすると、いろいろとメトリクスを取得することができます。
$ curl 172.17.0.2:8080/actuator/prometheus # HELP tomcat_servlet_error_total # TYPE tomcat_servlet_error_total counter tomcat_servlet_error_total{name="default",} 0.0 tomcat_servlet_error_total{name="dispatcherServlet",} 0.0 # HELP tomcat_threads_config_max_threads # TYPE tomcat_threads_config_max_threads gauge tomcat_threads_config_max_threads{name="http-nio-8080",} 200.0 # HELP jvm_threads_states_threads The current number of threads having NEW state # TYPE jvm_threads_states_threads gauge jvm_threads_states_threads{state="runnable",} 7.0 jvm_threads_states_threads{state="blocked",} 0.0 jvm_threads_states_threads{state="waiting",} 12.0 jvm_threads_states_threads{state="timed-waiting",} 4.0 jvm_threads_states_threads{state="new",} 0.0 jvm_threads_states_threads{state="terminated",} 0.0 # HELP tomcat_sessions_rejected_sessions_total # TYPE tomcat_sessions_rejected_sessions_total counter tomcat_sessions_rejected_sessions_total 0.0 # HELP system_cpu_count The number of processors available to the Java virtual machine # TYPE system_cpu_count gauge system_cpu_count 8.0 # HELP jvm_gc_memory_promoted_bytes_total Count of positive increases in the size of the old generation memory pool before GC to after GC # TYPE jvm_gc_memory_promoted_bytes_total counter ... 省略
Spring Web MVC関連の情報は、「http_server_requests_〜」に入っています。
$ curl -s 172.17.0.2:8080/actuator/prometheus | grep http_server_requests # HELP http_server_requests_seconds # TYPE http_server_requests_seconds summary http_server_requests_seconds_count{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/hello",} 1.0 http_server_requests_seconds_sum{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/hello",} 0.096711315 http_server_requests_seconds_count{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 5.0 http_server_requests_seconds_sum{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 0.109337835 # HELP http_server_requests_seconds_max # TYPE http_server_requests_seconds_max gauge http_server_requests_seconds_max{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/hello",} 0.096711315 http_server_requests_seconds_max{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 0.083914304
各エンドポイントに関する、アクセス回数などがわかりますね。
Prometheusを起動して、アプリケーションのメトリクスを収集する
続いて、Prometheusを準備します。
Prometheusがメトリクスの情報をPullしてくる先を、設定として定義します。先ほど作成した、Spring Bootアプリケーションの
Prometheus向けのエンドポイントを定義しています。
prometheus.yml
scrape_configs: - job_name: 'spring-boot-app' metrics_path: '/actuator/prometheus' static_configs: - targets: ['172.17.0.2:8080']
このあたりは、こちらを参考に作成しました。
https://github.com/prometheus/prometheus/blob/v2.5.0/documentation/examples/prometheus.yml
これで、PrometheusのDockerコンテナを起動。
$ docker container run -it --rm --name prometheus -v `pwd`/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus:v2.5.0
「http://[Prometheusが動作しているホスト]:9090」にアクセスすると、UIを見ることができます。
テキストフィールドにPrometheusのクエリを入力すると補完が効き、「Execute」ボタンを押すと「Console」に表示されます。
「Graph」タブを押すことで、グラフも見ることができます。
PrometheusでAlertも設定できるようですが、今回はここまでで。
Prometheusの準備は、これでおしまいです。
Grafanaを起動して、可視化する
最後は、Grafana。
ドキュメントを参考にして、Dockerコンテナで起動します。
Installing using Docker | Grafana Documentation
$ docker container run -it --rm --name grafana grafana/grafana:5.3.4
起動したら、「http://[Grafanaが動作しているホスト]:3000」にアクセスすると、ログイン画面が表示されます。
初期のアカウント / パスワードは、「admin / admin」なようなので、それでログイン。この時、パスワードの変更を求めらるので、
適宜変更。
このデフォルトの情報がどこに書かれているかというと、こちら。「admin_user」、「admin_password」というやつですね。
Home Dashboardという画面に移るので
緑色で表示されている「Add data source」ボタンを押して、データソースを追加しましょう。
ここでは、「Type」に「Prometheus」を選択して、「Name」を適当に設定。「HTTP」の「URL」は、Prometheusにアクセス
するためのURLを設定してください。
今回、Prometheusは「172.17.0.3」で稼働しているので、「http://172.17.0.3:9090」で設定。
その他の設定は、ここではそのままにしてページの下の方にある「Save & Test」ボタンを押します。
これで、データソースが追加されます。
続いて、左側にある「+」ボタンを押すと、ダッシュボードが追加されます。
ここで表示されている、「Graph」を押してダッシュボードにグラフを追加します。
空のグラフが表示されるので、タイトルをクリックするとメニューが展開されます。「Edit」を選択。
グラフの編集画面に移るので、「Data Source」に「prometheus」を選択して、フィールドにPrometheusのクエリを
入力します。
とはいえ、ここでは取得したメトリクスの名前そのままですが。
ここまでの操作は「Metrics」タブでしたが、今度は「General」タブに移ってグラフの名前を変更しておきましょう。
あとは、ダッシュボードを保存します。名前は、適当に。
ダッシュボードに、グラフが追加されました!
グラフをもうひとつ追加してみましょう。
また空のグラフが表示されるので、同じ要領で「Edit」して、Prometheusから情報を取得するように編集します。
今度は、HTTPの呼び出し回数でも。
これだと、Prometheusがメトリクスを収集するためのアクセスも見えてしまって、ジャマなように思います。
Prometheusのクエリでフィルタリングしてみましょう。
こうしました。
http_server_requests_seconds_count{uri!="/actuator/prometheus"}
スッキリですね。
ダッシュボードを保存して、おしまい。
とりあえず、全部つながったようです…。
まとめ
特に応用的なことはなにも考えずに、とにかくSpring Boot+Micrometer、Prometheus、Grafanaをつなげることを目標に、
いろいろ頑張ってみました。
最初はPrometheusやGrafanaがとっかかりが全然わからなかったのですが、試したり調べたりしていたら、だんだんドキュメントも
読めそうな感じになってきたので、少しずつ習熟したいなぁと思います。