Micrometer + Promregator で Spring Boot アプリのヒストグラム形式のメトリクスを収集する際の注意点
備忘録。
CloudFoundry で動かしている Spring Boot アプリケーションのメトリクスを Promregator 経由で Prometheus に蓄積しようとした時に詰まったところ & その解決策について。
環境
- Spring Boot アプリケーションを CloudFoundry 上で動かしている
- HTTP で処理を受け付けて MQ に流す API と、MQ からリクエストを取り出して処理をするワーカーがある
- API のレスポンスタイムとワーカーの処理時間のNパーセンタイルを Micrometer でメトリクス化する
- メトリクスは Prometheus で収集する
- インスタンス毎のメトリクスが欲しいので Prometheus server とアプリケーションの間に Promregator を挟む
- 環境
- Spring Boot 2.0.6
- micrometer-registry-prometheus 1.1.1
- Promregator 0.5.0
API とワーカーそれぞれのプロパティで percentilesHistogram
にパーセンタイルを計算したいメトリクスを指定する。API は http.server.requests
, ワーカーは spring.integration.send
が共通の prefix なので、以下のようになる。
API:
management: metrics: distribution: percentiles-histogram: http.server.requests: true
ワーカー:
management: metrics: distribution: percentiles-histogram: spring.integration.send: true
起きたこと
上記の設定をした上で、Promregator のエンドポイントにリクエストして双方のメトリクスを取得すると、http_server_requests_seconds_buckets
, spring_integration_send_seconds_buckets
という名前のメトリクスが export されるはず。
が、spring_integration_send_seconds_buckets
が取れない。
ちなみに http_server_requests_seconds_count
や spring_integration_seconds_count
はもれなく取れる。また、API とワーカー自身が公開しているエンドポイントにリクエストするととれるべきメトリクスは全て取れる。
原因
API とワーカーで management.metrics.distribution.percentiles-histogram
に指定したメトリクスがずれていたのが原因だった。
- micrometer は
percentiles-histogram
が指定されたメトリクスを histogram 型として、それ以外のメトリクスを summary 型として export する - Promregator では対象アプリケーションのエンドポイントをリクエストした際、
# TYPE
コメントを元にメトリクスの型(counter, gauge, histogram, summary)をパースする - Promregator は複数のエンドポイント間で同じメトリクスに異なる型が混在していた場合、後から収集したメトリクスについては WARN メッセージを出力してスキップする
今回のケースだと、API は MQ への publish をするため、自動的に spring_integration_send
から始まるメトリクスを export するが、percentiles-histogram
の指定はされていないので summary 型として export する。
# TYPE spring_integration_send_seconds summary ...
一方、ワーカーでは spring_integration_send
が percentiles-histogram
に含まれているので、histogram 型として出力する。
# TYPE spring_integration_send_seconds histogram ...
この型の不一致によって、ワーカーの spring_integration_send_seconds_buckets
が Promregator のエンドポイントにリクエストした際に含まれていなかった。ログを見るとその旨が出ている。
Attempt to merge metric spring_integration_send_seconds, but types are deviating: ...
解決策
解決するためには2つのアプリケーション間で percentiles-histogram
に含めるメトリクスを共通にすればいい。
management: metrics: distribution: percentiles-histogram: http.server.requests: true spring.integration.send: true
これによってどちらのアプリケーションでもメトリクスが histogram 型となり、上記の問題を回避できる。
ただしこれだと興味のないメトリクスもエクスポートされることになる……
(アプリケーション間でメトリクス名に共通の prefix or suffix を付けられるといいのだけど、そこはまだ未調査)