prometheus/exporter-toolkit を使って自作exporterを簡単にTLS対応させる方法


Prometheusはpull型のメトリクス収集を特徴としており、メトリクスを公開するプログラム(Exporter)がWebサーバとして振る舞います。

ExporterはHTTPのことが多いですが、センシティブなメトリクスを収集する場合などは、その内容を盗み見されないようにTLS対応が必要ということもあります。

Expoterの前段にリバースプロキシを設置してTLS対応するという方法もありますが、Exporter自身がTLS通信できれば、そっちの方が嬉しい場合も多いです。

Prometheusの公式のExporterは多くがTLS対応しています。

READMEを見ると、どうもこれは同じライブラリを利用しているようです。

To use TLS and/or basic authentication, you need to pass a configuration file using the --web.config.file parameter. The format of the file is described in the exporter-toolkit repository.

同じ仕組みでTLS対応していると、同じ設定ファイルが使えるし、車輪の再発明を防げるので良さそうと感じ、もう少し深堀りして調べることにしました。

exporter-toolkit

言及されているライブラリはこれです。

This repository is currently WIP and experimental.

まだ作業中ということで、利用には注意が必要そうです・・・

このライブラリは今のところwebというパッケージを提供しているだけのようです。

中を見てみると・・

  • kingpinというコマンドライン引数処理のライブラリを使うための便利関数が用意されている
  • http.Server.ListenAndServe を置き換える関数が用意されており、これだけでTLS対応ができる
    • ただし引数が違う func ListenAndServe(server *http.Server, tlsConfigPath string, logger log.Logger) error

対応時のdiffを見ると簡単さが伝わると思います↓

loggerの互換性

3つ目の引数のLoggerが少し曲者です。

exporter-toolkitが利用しているのは go-kit/log のLogger。
このLoggerがすぐに用意できるならexporter-toolkitは簡単に利用できます。

※goのlogger無茶苦茶種類があるな・・ ( https://github.com/avelino/awesome-go#logging

go-kitとは?

マイクロサービスのためのツールキットと書かれている。

  • https://pkg.go.dev/github.com/go-kit/kit
    • auth, circuitbreaker, endpoint, metrics. ratelimit, sd, tracing, transport, util などのパッケージがある。
    • logもその一つだが、リポジトリが分かれています。

prometheusの公式exporterはgo-kit/logを使うポリシーのようです。
(さらに調べるとpromlogというライブラリでgo-kit/logを簡単に使えるようにしています。 https://pkg.go.dev/github.com/prometheus/common/promlog)

どうなん?

たまたま手元にあったexporterはLoggerがgo-kitのものではありませんでした。これを気にgo-kitに描き直すか、うまく共存させる必要がありそうです。

どうなん? と思って少し調べているとこのような記事を発見しました。

既存のロギングライブラリは絶対にNG
ライブラリを書く際に既存のロギングライブラリを使うのは絶対にやめましょう。 あなたのライブラリのユーザーはあなたが提供する機能を使いたいのであって、 あなたが使いたいロギングライブラリを使いたいわけではないのです。

ですね・・

わかったこと

  • 独自のexpoterをTLS対応するにはexpoter_toolkitを使うのが良さそう
  • ロギングライブラリはgo-kit/log (またはpromlog)にするのが良い
  • exporter_toolkitはExperimentalなので動向に注意