influxDBとGrafanaで手の届かないところ

influxDBとGrafanaで様々なメトリクスグラフを作っていて、基本的には気に入ってはいるのですが、ちょいちょい痒いところに手が届かないのでまとめておきます。

influxDBとGrafanaの基本については [こっち](http://qiita.com/chroju/items/355f3c6da9f8c4867ba5) 参照で。なお用途としてはAPI叩いた結果を格納したり、サーバーからメトリクスを上げさせて格納したりということをしています。

## RP, CQによるダウンサイズとGrafanaの付き合い方

* [InfluxData | Documentation | Downsampling and Data Retention](https://docs.influxdata.com/influxdb/v1.2/guides/downsampling_and_retention/)

influxDBにはContinuous QueriesとRetention Policiesという機能があり、これを利用したデータの定期的なダウンサンプリングが公式でも推奨されている。

### Continuous Queries (CQ)

CQは名前の通り、一定間隔で継続的にクエリを実行する機能。これを利用することで、1分刻みでデータが補完されたmeasurementから、10分平均値を定期的に抜き出し、別のmeasurementにinsertすることができる。

### Retention Policies (RP)

RPは、各measurementのデータ保存期間を設定する機能。先の1分刻みデータを保存した`week.data`measurementは1週間しか保存しない設定にし、10分平均のデータは`year.data`measurementに1年間保存する設定にすれば、ダウンサンプリングされたデータだけを長期保存して、ディスク容量を空けることができる。

1分刻みのデータをずっと持っておくのもツライので、基本的にはこの機能を使うことになる。

が、Grafanaにおいて。GrafanaのグラフはinfluxDBに対するクエリを設定して、その結果を表示してくれるものである。従って1分刻みデータから`SELECT .... FROM week.data ...`というクエリをかけたグラフを作成した場合、表示する時間範囲を1か月に引き伸ばしても、1週間より前のデータは`year.data`にあるので、データがきちんと表示できない。

Grafanaは表示するグラフの時間範囲を自由に指定できるので、心情としては勝手にダウンサンプリング先のデータを読むようにできたらよいのだが、今のところこの回避策は見つかっていない。というかissue挙がっているので基本的には現状ムリっぽい。

* [grafana can support influxdb continuous queries some way · Issue #420 · grafana/grafana · GitHub](https://github.com/grafana/grafana/issues/420)


## Continuous Queriesでワイルドカード指定するとfield keyが変化する

これはinfluxDBの仕様なのだけど、select文でAggregationを行なったとき、出力のカラムタイトルはAggregationの機能名になる。

```
> SELECT mean(value) FROM default.loadaverage WHERE time < now() - 10m GROUP BY time(5m) LIMIT 5
name: loadaverage
time                mean
----                ----
1491868800000000000 1.24320000000000003
1491869100000000000 1.28506666666666663
1491869400000000000 1.2694666666666667
1491869700000000000 1.21906666666666666
1491870000000000000 1.21386666666666665
```

これが嫌な場合には回避策があって、`mean`句の後ろに`AS`句を使えば、その名前をカラムタイトルにできる。

しかしContinuous Queryをかけるとき、あるmeasurementのfieldsを一括して集計するためにワイルドカード指定を使うと、この`AS`がprefixの指定になってしまう。

```
> SELECT mean(*) AS hoge FROM default.loadaverage WHERE time < now() - 10m GROUP BY time(5m) LIMIT 5
name: loadaverage
time                hoge_value
----                ----
1491868800000000000 1.24320000000000003
1491869100000000000 1.28506666666666663
1491869400000000000 1.2694666666666667
1491869700000000000 1.21906666666666666
1491870000000000000 1.21386666666666665
```

どうも今のところこういう仕様っぽいのでどうしようもない。回避するには、ワイルドカードを使わずに1つずつCQを作り、それぞれで`AS`指定を行なっていくしかない。

* [Support wildcards in aggregate functions by jsternberg · Pull Request #7009 · influxdata/influxdb · GitHub](https://github.com/influxdata/influxdb/pull/7009)

## Templatingで有効なtag valuesだけを拾いたい

Grafanaの [Templating](http://docs.grafana.org/reference/templating/) は、influxDBへの特定クエリ結果を変数として扱える機能。例えば`show tag values with key = "hostname"`でホスト名の一覧をピックアップし、そこから任意のホスト名を選択して、そのサーバーのグラフを表示させる、といった使い方ができる。

クラウド環境のサーバーメトリクスを収集していると、当然サーバーが頻繁に削除されたりするわけだが、今のところTemplatingには「現在activeなサーバー」だけをピックアップする方法が無さそうで、influxDBに保持された全サーバー名がピックアップされてしまう。手段として考えられるのは、

* `value >= 0`のような指定で、現在fieldに値を持ったサーバー名だけピックアップさせる。
* 時間範囲を直近1日等で区切って、その間に出力されているサーバー名だけをピックアップさせる。

といったところだが、今のところいずれも`show tag values`では構文として書くことができない。GitHub issuesで挙げられてはいるので、取りあえず対応待ち。

* [\[feature request\] SHOW TAG KEYS/VALUES should accept a WHERE time clause · Issue #5668 · influxdata/influxdb · GitHub](https://github.com/influxdata/influxdb/issues/5668)

なお、先のissueでワークアラウンドとして挙げられているのが、Continuous Queryで最新のサーバーリストを別のmeasurementに作ってしまうこと。これは確かに有効な手法ではある。

```
CREATE CONTINUOUS QUERY "lookupquery" ON "prod" BEGIN SELECT mean(value) as value INTO "lookup"."host_info" FROM "cpuload" where time > now() - 1h GROUP BY time(1h), host, team, status, location END;
```

以上、ちょこちょこツライポイントに遭遇してはいるが、全体的には程よく使えている状況である。