Stackdriver Monitoringの機能拡張

インフラの反田です。AWSやGCPのモニタリングまわりを担当しています。

GREEでは、大部分のサービスをAWSで運用していますが、一部の新しいサービスではGCPも利用しています。
AWSで運用しているサービスについては、PrometheusとCloudWatchを組み合わせてモニタリングしています。サービスごとにAWSアカウントが分けられていることもあり、AWSのマネジメントコンソールにログインしなくてもすむように、GrafanaでCloudWatchのメトリクスを確認できるようにしています。

GCPを利用するにあたって、Stackdriver Monitoringの機能を評価したところ、そのまま利用することには課題があったので、モニタリング環境の整備をしました。

やったこと

  • GrafanaにStackdriver datasourceを作成し、Stackdriverのメトリクスを表示できるようにした
  • PrometheusにStackdriver read adapterを作成し、Stackdriverのメトリクスに対してPromQLを使えるようにした

StackdriverとCloudWatchの比較

CloudWatchと比較してStackdriverの優れていると思う点としては、フィルタにより柔軟に処理対象のtime seriesをマッチングできる点です。
CloudWatchでDimensionを指定する場合、曖昧なマッチングはできず、EC2のインスタンスIDなどを完全一致で指定する必要があります。全てのインスタンスのCPUUtilizationを取得したいという場合は、CloudWatchのクエリに全インスタンスIDを指定する必要があります。

StackdriverのフィルタはPrometheusのlabel matcherに近い感覚でマッチングでき、フィルタで絞り込まない場合は全てのtime seriesにマッチしてくれます。

Stackdriverに追加してほしい機能

ダッシュボード作成など十分な機能を提供してくれていると思いますが、GrafanaやPrometheusで普段利用しているいくつかの重要な機能が提供されていませんでした。
全ての機能が必要というわけではないのですが、今後本格的に利用していくにあたって課題があると感じました。
これらの機能を使えるように、GrafanaとPrometheusを利用して機能拡張しました。

  • Templating
    • 1つのdashboard内で問題のしぼりこみを行うために必要
  • 積み上げグラフ
    • CPUやメモリのリソース使用内訳を表示するために必要
  • 共有可能なdashboard link
    • チャットなどでdashboardを共有するために必要
  • 数式サポート
    • エラーレートなど割合の計算のために必要

Stackdriver datasource

Grafanaのdatasourceはpluginとして追加できるようになっており、Stackdriver datasourceを作成することで、GrafanaでStackdriverのメトリクスを表示できるようになります。
これにより、GrafanaのTemplating、積み上げグラフやdashboard linkといった機能をStackdriverに対しても使えるようにできます。
Grafana 5.xからは、ブラウザではなくGrafanaが起動しているインスタンス内でpluginが動作するbackend pluginがサポートされています。Stackdriver datasourceでは、これを利用することでサービスアカウントなどを作成せず、インスタンスのIAMを利用してStackdriverのAPIを呼び出しています。

https://github.com/mtanda/grafana-google-stackdriver-datasource

GCPのプロジェクトごとにGrafanaを起動することで、各プロジェクトのdashboardを確認できるようにしています。

なお、Grafana公式のStackdriver datasourceの開発が進んでいるため、おそらく近日中にbeta releaseがあると思われます。
新規に導入される場合は、公式のplugin利用がおすすめです。

https://github.com/grafana/grafana/pull/13289

Stackdriver read adapter

Prometheusにはlong term storageの問題を解決するために、remote write / remote readという機能があります。

https://prometheus.io/docs/operating/integrations/#remote-endpoints-and-storage

本来の用途とは異なるのですが、これを利用して既存のTSDBに対してもPromQLの数式や関数を使えるようにできます。

https://github.com/mtanda/stackdriver_read_adapter

Prometheusではメトリクスデータの取得元として、local storageもremote readで読み取るremote storageも同じように扱えるようになっています。

https://github.com/prometheus/prometheus/blob/master/documentation/internal_architecture.md

StackdriverのフィルタはPrometheusのlabel matcherと同程度の機能があるので、remote readが必要な処理は、label matcherをフィルタに変換し、Stackdriverからメトリクスを取得し、Prometheusに返すだけです。
PromQLはPrometheus内で評価されます。

以下のようなPromQLのクエリを発行すると、

以下のようなStackdriverのクエリに変換されます。

PromQLではmetric nameやlabel nameに"."を含められないため、metric nameは"__name__"でlabel matchさせ、label nameは"."を"_"に置き換えて指定します。

注意点としては、Stackdriverからクエリ対象期間に記録されている全てのtime seriesを返すことは仕様面でも負荷面でも難しいので、PromQLのrate()やavg_over_time()といったrange vectorを扱うクエリは正しい結果とならない場合があります。
rate()であれば、期間内にカウンタのリセットがなければ問題ないので、短い期間を対象とした場合はおそらく問題ないですが、長い期間を対象とした場合は注意が必要です。

まとめ

StackdriverとGrafanaを組み合わせることで、Stackdriverではサポートされていない多くの機能を使えるようになりました。
またPrometheusと組み合わせることで、数式もサポートすることができました。

Stackdriver Traceなど、Stackdriverにはとても有用な機能がそろっています。
StackdriverのPrometheusサポート、OpenCensusやOpenMetricsは、Prometheusのエコシステムを活用しつつ、Stackdriverをより強力なモニタリングツールに変えていくと思います。
このあたりの動向を追いかけつつ、便利な機能は積極的に使っていこうと思っています。

参考資料