Prometheus PushgatewayにGolangからメトリクスを登録する

PrometheusではExporterに対してメトリクスを取得するため、HTTPリクエストを行いますが、これではバッチ処理などの一時的に起動するものなどのメトリクスを収集することができません。

そのため、PrometheusではPushgatewayというものが用意されています。これはバッチ処理などのメトリクスを保存し、PrometheusからPushgatewayに対して保存されているメトリクスを取得する仕組みになっています。

Pushgatewayにメトリクスを追加するためのライブラリがGolangにあったので、今回はこれを使ってメトリクスを収集したいと思います。

目次

  1. 動作環境
  2. PrometheusとPushgatewayの起動
  3. バッチ処理の作成
  4. 終わりに

1. 動作環境

  • Golang: 1.13.1
  • Prometheus: 2.15.1

2. PrometheusとPushgatewayの起動

まずは、PrometheusとPushgatewayを起動させます。PushgatewayはDocker Imageが用意されているようなので、それを使って起動させます。

$ docker pull prom/pushgateway
$ docker run -d -p 9091:9091 prom/pushgateway

これだけで完了です。 PushgatewayもExporterと同様にHTTPリクエストを受けれる口が用意されています。下記が確認用としてcurlでリクエストした結果になります。

$ curl http://localhost:9091/metrics
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 9.943e-06
go_gc_duration_seconds{quantile="0.25"} 3.0521e-05
go_gc_duration_seconds{quantile="0.5"} 4.2184e-05
go_gc_duration_seconds{quantile="0.75"} 0.000109096
go_gc_duration_seconds{quantile="1"} 0.000429447
go_gc_duration_seconds_sum 0.003177886
go_gc_duration_seconds_count 38
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 12
・・・

また、curlからメトリクスの追加もできます。

$ echo "some_metric 3.14" | curl --data-binary @- http://192.168.33.141:9091/metrics/job/some_job

$ curl http://localhost:9091/metrics

・・・
pushgateway_http_requests_total{code="200",handler="push",method="post"} 3
pushgateway_http_requests_total{code="200",handler="push",method="put"} 2
pushgateway_http_requests_total{code="200",handler="status",method="get"} 1
# TYPE some_metric untyped
some_metric{instance="",job="some_job"} 3.14

無事に追加できるところまで確認できましたね。

では次にPrometheusの設定をしていきます。 Prometheusでは通常の設定と同様、scrapeに設定を追加していきます。

  - job_name: 'push gateway'
    metrics_path: /metrics
    static_configs:
      - targets: ['192.168.33.141:9091']

192.168.33.141 はPushgatewayが起動してるサーバのIPになります。 これだけで準備完了となります。

3. バッチ処理の作成

次にバッチ処理Golangで書いていきたいと思います。 まずはサンプルとして Counter のメトリクスを作成し、Pushgatewayに送信したいと思います。

package main

import (
    "fmt"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/push"
)

func main() {
    sample := prometheus.NewCounter(prometheus.CounterOpts{
            Name: "myapp_sample_counter",
            Help: "myapp sample counter",
    })
        // 値をインクリメント
    sample.Inc()
    if err := push.New("http://192.168.33.141:9091", "my_job").
        Collector(sample).
        Push(); err != nil {
            fmt.Printf(err.Error())
        }
}

では、これを実行し、Pushgatewayでメトリクスを確認したいと思います。

$ curl http://localhost:9091/metrics
・・・
# HELP myapp_sample_counter myapp sample counter
# TYPE myapp_sample_counter counter
myapp_sample_counter{instance="",job="my_job"} 1

無事に登録されていますね。 バッチ処理のメトリクスっぽく起動時間を登録したいと思います。

サンプルなので途中で10秒停止して時間を計測したいと思います。

   execute := prometheus.NewSummary(prometheus.SummaryOpts{
            Name: "my_batch_job_execution_time",
            Help: "execution time",
    })
        // 時間の計測
    start := time.Now()
    time.Sleep(time.Second * 10)
    end := time.Now()

        // 実行時間を登録
    execute.Observe((end.Sub(start)).Seconds())
    if err := push.New("http://192.168.33.141:9091", "my_job").
        Collector(execute).
        Push(); err != nil {
            fmt.Printf(err.Error())
        }
$ curl http://localhost:9091/metrics

・・・
# HELP my_batch_job_execution_time execution time
# TYPE my_batch_job_execution_time summary
my_batch_job_execution_time_sum{instance="",job="my_job"} 10.000940275
my_batch_job_execution_time_count{instance="",job="my_job"} 1

登録できましたね。めでたし。

4. 終わりに

簡単ではありますが、Pushgatewayでバッチ処理のメトリクス収集までやってみました。

カスタムメトリクスの収集方法を覚えれば、Exporterでも役立つのでもっと使い方を調べていきたいと思います。