Grafana + InfluxDB による時系列データの表示2018年2月3日 | |
はじめに物理シミュレーションの計算状況を可視化できないかと思い、Grafana + InfluxDB で計算データの表示を試みた。 環境
InfluxDBInfluxDB は時系列データを扱うデータベース管理サーバーである。Grafana は InfluxDB のデータの表示機能を持つ。 こちら から Windows 用パッケージ (influxdb-1.4.2_windows_amd64.zip) をダウンロードする。パッケージを展開して適当なところに置いて、パスを通す。 ユーザーのディレクトリパス HOME を手動で設定したほうがよいらしい。環境変数 HOMEPATH と同様の設定にする (参考: CLI History Error on ARM (GitHub))。 コマンドラインでサーバーの起動。 >influxd クエリは http://localhost:8086 で受け付ける。 InfluxDB のデータベースは以下の項目からなる。
別のコマンドラインで influx (クライアント) を実行。コマンドは以下の通りである。 データベースの一覧の表示> show databases データベースの作成> create database <name> データベースの削除> drop database <name> 使用するデータベースの設定> use <name> データの追加> insert <measurement>,<tag>=<label>,... <field>=<value>,... データの一覧の表示> show measurements データの削除> drop measurement <measurement> データの中身の表示> select * from <measurement> 終了> quit たとえば、データベース "case1" を作って温度データを追加するには、次のようにする。 > create database case1 > use case1 > insert temperature value=1000 Python からの操作InfluxDB-Python というもので Python から InfluxDB サーバーにアクセスできる。 pip でインストール。 >pip install influxdb JSON 形式でデータを登録する。
from influxdb import InfluxDBClient
c = InfluxDBClient(host="localhost", port=8086)
c.create_database("case1")
c.switch_database("case1")
for i in range(10):
json_body = [
{
"measurement": "temperature",
"fields" : {
"iteration" : i,
"value" : 1000. + i
}
}
]
c.write_points(json_body)
result = c.query("select iteration,value from temperature")
print("Result: {0}".format(result))
データベースがすでに作成されているかどうかを確認するには、次のような関数を作ればよい。
def created_database(c, name):
db_list = c.get_list_database()
found = False
for db_name in db_list:
if db_name['name'] == name:
found = True
break
return found
GrafanaGrafana は時系列データベース表示用のダッシュボードを作るための仕組みである。 こちら から Windows 用パッケージ (grafana-4.6.3.windows-x64.zip) をダウンロードして展開し、適当な場所に置く。 conf/sample.ini をコピーして conf/custom.ini を作る。custom.ini を編集する。 # The http port to use ;http_port = 3000 http_port = 8080 コマンドラインで bin フォルダに移動して、サーバー grafana-server.exe を実行する。 ブラウザで http://localhost:8080/login にアクセスする。ログイン画面が出てきたら、User: admin, Password: admin でログインできる。 左上のアイコン [Admin]-[Global Users] ユーザー名、パスワードを設定できる。ユーザーの作成もできる。 データソースの追加左上のアイコン [Data Sources] の "Add data source" でデータソースを追加する。
ダッシュボードの追加左上のアイコン [Dashboards]-[New] を選択、"Graph" を選ぶ。"Panel Title" をクリックして "Edit" を選ぶ。下のクエリの設定の右にメニューのアイコンがあるので、"Toggle Edit Mode" を選ぶ。InfluxDB のコマンドを直接編集できるので、たとえば、次のようにする。
SELECT "value" FROM "temperature" WHERE $timeFilter グラフの自動更新右上の時刻をクリック、"Time range" のところの "Refreshing every" から更新間隔を選択する。 シミュレーション計算状況の可視化シミュレーション計算状況を Grafana で可視化することを試みる。 熱流体計算の状況表示を考える。計算は定常計算である。データは平均流速と平均温度で、繰り返し計算回数 (iteration) ごとに出力される。ファイルのタイムスタンプを監視して、更新があったら最後のデータを InfluxDB に送るようにしてみた。 watch-timestamp.py
import os
from stat import *
import time
from influxdb import InfluxDBClient
def created_database(c, name):
db_list = c.get_list_database()
found = False
for db_name in db_list:
if db_name['name'] == name:
found = True
break
return found
db = "case1"
files = {
"plot-vel.txt" : "velocity",
"plot-temp.txt" : "temperature",
}
def main():
c = InfluxDBClient(host="localhost", port=8086)
if not created_database(c, db):
c.create_database(db)
c.switch_database(db)
timestamp0 = {}
for file in files.keys():
if not os.path.exists(file):
with open(file, "w"):
pass
timestamp0[file] = os.stat(file)[ST_MTIME]
print("Waiting...")
try:
while True:
for file in files.keys():
timestamp = os.stat(file)[ST_MTIME]
if timestamp > timestamp0[file]:
print("update: %s" % file)
item = []
with open(file, "r") as f:
line = f.readlines()
item = line[-1].split()
json_body = [
{
"measurement": files[file],
"fields" : {
"iteration" : item[0],
"value" : item[1]
}
}
]
c.write_points(json_body)
timestamp0[file] = timestamp
time.sleep(1)
except KeyboardInterrupt:
pass
if __name__ == "__main__":
main()
これではたまにしかデータを送れなかった。Windows の問題かもしれない。そこで、ある時間間隔でデータを送るようにしてみた。 watch-interval.py
import os
from stat import *
import time
from influxdb import InfluxDBClient
def created_database(c, name):
db_list = c.get_list_database()
found = False
for db_name in db_list:
if db_name['name'] == name:
found = True
break
return found
db = "case1"
files = {
"plot-vel.txt" : "velocity",
"plot-temp.txt" : "temperature",
}
interval = 10
def main():
c = InfluxDBClient(host="localhost", port=8086)
if not created_database(c, db):
c.create_database(db)
c.switch_database(db)
print("Waiting...")
try:
while True:
for file in files.keys():
print("update: %s" % file)
item = []
with open(file, "r") as f:
line = f.readlines()
item = line[-1].split()
json_body = [
{
"measurement": files[file],
"fields" : {
"iteration" : item[0],
"value" : item[1]
}
}
]
c.write_points(json_body)
time.sleep(interval)
except KeyboardInterrupt:
pass
if __name__ == "__main__":
main()
頻繁にデータが更新されるなら、時間間隔で送った方がよいかもしれない。 感想Grafana は (今のところ) 実時間に対するグラフしか表示できないので、時間が実時間とは異なるシミュレーションでは少し使いにくい。長時間の計算に対する状況の監視には使えないこともないが。 | |
| PENGUINITIS | |