Golangで簡単にPrometheusのExporterを作れる。
GolangによるPrometheusのExporterの作成
やること
今回は、自作のExpoterの作り方の情報がすごい少ないなと感じたので とても簡単に作れるよというのをお見せできたらと思います。
事前準備
まず、prometheusのライブラリを取ってきましょう。
$ go get github.com/prometheus/client_golang/prometheus
インストルメンテーション
promethusはプル型のモニタリングシステムであり、監視対象にHTTPでアクセスしメトリクスを収集します。
すなわち、監視される側でprometheus形式のメトリクスを投げるHTTPのエンドポイントが必要となります。
それを提供するのがExporterでなんですが、自分好みの値を格納したいと思ってた時に、 それに適したExporterがないなんてことはざらにあります。
その際に、自分でExporterを作ることになるのですが、そこで使うのがインストルメンテーションです。
◯主要インストルメンテーション
- カウンター: イベントの数およびサイズ等を追跡する。
- ゲージ: あらゆる数値を格納
この他に、サマリ・ヒストグラムがある。
Code
以下がコードの全体像です。
// 初期定義 package main import ( "flag" "log" "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) // Metricsの定義 const ( namespace = "SampleMetric" ) type myCollector struct{} // 今回働いてくれるインスタンス // metricsの記述子 「metricsの中に埋め込む情報の1つ(名前、#HELP に乗せる情報)であり、後にグラフで表示させるための数値以外のもの」 var ( exampleCount = prometheus.NewCounter(prometheus.CounterOpts{ Namespace: namespace, Name: "example_count", Help: "example counter help", }) exampleGauge = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "example_gauge", Help: "example gauge help", }) ) // Describe と Collect func (c myCollector) Describe(ch chan<- *prometheus.Desc) { ch <- exampleCount.Desc() ch <- exampleGauge.Desc() } func (c myCollector) Collect(ch chan<- prometheus.Metric) { exampleValue := float64(12345) ch <- prometheus.MustNewConstMetric( exampleCount.Desc(), //ここと prometheus.CounterValue, //ここは固定 float64(exampleValue), //ここが、グラフに表示させたい数値 ) ch <- prometheus.MustNewConstMetric( exampleGauge.Desc(), prometheus.GaugeValue, float64(exampleValue), ) } var addr = flag.String("listen-address", "127.0.0.1:5000", "The address to listen on for HTTP requests.") func main() { flag.Parse() var c myCollector prometheus.MustRegister(c) http.Handle("/metrics", promhttp.Handler()) log.Fatal(http.ListenAndServe(*addr, nil)) }
では細かく見ていきます。
初期定義(prometheus用moduleのimport)
ここでは、package定義やmoduleのimportを記述します。
package main import ( "flag" "log" "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" )
基本、このライブラリはデフォルトでimportすることになると思います。
Metricsの定義
初めの1歩
const ( namespace = "SampleMetric" ) type myCollector struct{}
ここでは、Namespace(metricに与える名前の一部)をSampleMetricとして固定します。
そして、今回働いてくれるインスタンスをstructで作っておきます。
Metricの中身を決定
今回は上で紹介した、カウントとゲージを定義します。
var ( exampleCount = prometheus.NewCounter(prometheus.CounterOpts{ Namespace: namespace, Name: "example_count", Help: "example counter help", }) exampleGauge = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "example_gauge", Help: "example gauge help", }) )
ここで定義したものは、後にmetricを取得した際に以下のように表示されます。
# HELP SampleMetric_example_count example counter help # TYPE SampleMetric_example_count counter SampleMetric_example_count 12345 # HELP SampleMetric_example_gauge example gauge help # TYPE SampleMetric_example_gauge gauge SampleMetric_example_gauge 12345
metric名は、NameSpace + Nameをしたものが表示されています。
値
CollectorとDescriber
自作Exporterではこの2つを定義しなければなりません。
Describer
func (c myCollector) Describe(ch chan<- *prometheus.Desc) { ch <- exampleCount.Desc() ch <- exampleGauge.Desc() }
ここは、ほぼテンプレです。
metricの中身を定義した際に決定した変数名(今回はexampleCountとexampleGauge).Desc()をchに入れます。
Collector
func (c myCollector) Collect(ch chan<- prometheus.Metric) { exampleValue := float64(12345) ch <- prometheus.MustNewConstMetric( exampleCount.Desc(), //ここと prometheus.CounterValue, //ここは固定 float64(exampleValue), //ここが、グラフに表示させたい数値 ) ch <- prometheus.MustNewConstMetric( exampleGauge.Desc(), prometheus.GaugeValue, float64(exampleValue), ) }
ここで、変える必要があるのは、exampleValueのみです。
ここの数値に、サーバから取得した数値等様々な値を入れて下さい。
ここで定義した数値が、先ほどの取得したmetricの12345の箇所に入り、prometheusに格納されます。 この際、単調増加でないものはCounterに入れないようにして下さい。
それ以外は、コピペで大丈夫です。
最後のもう一押し
今回、addressを標準入力で取得できるように、flagを用意しています。
var addr = flag.String("address", "127.0.0.1:5000", "The address to get the metrics on the HTTP requests.") func main() { flag.Parse() var c myCollector prometheus.MustRegister(c) http.Handle("/metrics", promhttp.Handler()) log.Fatal(http.ListenAndServe(*addr, nil)) }
main関数では、値をparseして、インスタンスを生成させてMustRegisterに渡します。
最後、port番号の後に続くものを
Exporterの起動
今回は、flagに定義したdefaultのIPにて起動をしたいと思います。
$ go run exporter.go
後は以下にアクセスしてみて下さい。
prometheus metric URL (http://localhost:5000/metrics)
するとこのようなものが表示されれば、完成です。
最後に
前回の記事で書いたGrafana+Prometheusに今回のExporterを組み合わせることで、Prometheusがより一層力を増すのでぜひ使ってみて下さい