Plotting the moving average of Elasticsearch’s time-series data in Grafana.
相模原市で IoT 設計を受託しているファームロジックスです。
Elasticsearch と Grafana
今日は小ネタです。Elasticsearch という時系列に強いデータベースと、Grafana というデータ可視化ツールの話題です。
今までに書いた Elasticsearch ネタの拙記事は、こちらを御参考ください。
先日の記事で、家庭用のエアコンの消費電力をリアルタイムにグラフ化する話を書かせて頂きました。例えばスマホから、こんなグラフを見ることができます。
見て頂くとお分かりになると思いますが、インバータ制御のエアコンでも、温度設定が高いなど最小電力の運転時には、送風運転に切り替わる頻度が多くなります。また、最小電力運転でなくても、インバータ制御は不連続な段階制御になっているようで(最新の高級機種は分かりませんが)、グラフをぱっと見ただけでは、平均的な電力消費は分かりにくいです。
移動平均を表示してみたい
こんなときに有効な手段の一つは、データの移動平均(moving average)を計算して表示する方法です。Grafana で可能なのでしょうか?
ネットで調べても、Grafana で移動平均を表示する方法については、あまり検索がヒットしません。「grafana elasticsearch moving average」とか検索すると、Elasticsearch: Moving Average is no longer available in 7.x なんていう結果が出てきたりして、移動平均は無理なのかな、なんて思ったりしてしまいます。
マニュアルにこっそり書かれていた!
しかし、Grafana のマニュアルを注意深く見ていたら、実は実現できることが分かりました。もともと、Grafana のマニュアルは、開発者向けのような難解な書き方になっていて、初心者向けの内容が少ないと思われるのですが…。)
マニュアルのこちらを御覧ください。
これは、現状最新の v10.0 での内容ですが、私が利用している古い Grafana でも利用できることが分かりました。
グラフの設定画面を御覧ください。
もともと Metric で Average: power という項目を用意していたのですが、それに加えて、新しい Metric として「Moving Average: Average power」というものを手動で入力してやると、移動平均が追加されます。(Average とタイプし始めると、自動的に補完されるようです。)
以下のように、オレンジ色の線で移動平均が表示されました。やった〜!
ちなみに、私としては、絶対的な時間として例えば 15分間の移動平均を求めるように指定したかったのですが、上記の設定で Elasticsearch の raw query を見ていると、date histogram aggregation の「後」に moving average(移動平均)を計算しているので、移動平均のウィンドウサイズが「時間」ではなくて「bucket」単位の指定になってしまいます。そのため、グラフの時間幅を短くすると、移動平均の線がガタガタになってしまう、という問題があります。(aggregation の前に moving average を適用しようとすると、時間範囲が広い場合、処理量が膨大になってしまうだろうとは思いますが。)
参考までに、query の中の aggregation の部分を抜粋してみます。
"aggs": {
"2": {
"date_histogram": {
"interval": "30s",
"field": "datetime",
"min_doc_count": 0,
"extended_bounds": {
"min": "1690527306804",
"max": "1690567235309"
},
"format": "epoch_millis"
},
"aggs": {
"1": {
"avg": {
"field": "power"
}
},
"3": {
"moving_avg": {
"buckets_path": "1",
"minimize": false,
"model": "linear",
"window": 400
}
}
}
}
}
これを解決するには、Elasticsearch の query を raw(生)で指定できるようにすればいいのでしょうけど、ま、だいたいの目的は達しているので、これで良いことにします。
今日はここまで。