SlowDash を使ってみる

Contents

SlowDash とは

スローコントロールのモニタを Grafana で作らされた経験に基づいて開発が開始されました.おおまかには,

ための Web ベースのソフトウェアです.ブラウザ側の JavaScript と,サーバー側の Python で構成されています.

もともとはスローコントロール用でしたが,現在では物理実験に関わる全てのデータのビジュアライズと,DAQ を含むシステムコントロールの UI を目指して開発をしています.現時点で,Grafana で行うようなビジュアライゼーションの部分はほぼ実装済みで,解析およびコントロールの部分が開発中です.

データベースアクセス以外は外部ライブラリを使っておらず,ソフトウェアの寿命が外のライブラリの変更等に影響されることはないようになっています.特に,流行り廃れが激しい JavaScript の部分はフレームワークなどは使わず,完全に自己完結です(使っていたけど排除しました).データベース側および解析モジュールは,全て独立なプラグインとなっており,いつでも切り捨てられます.依存性がないので,インストールがとても楽です.

名前がまだ決まっておらず,SlowDash というのは最初にスローコントロール用のダッシュボードを作ったときからの仮称です.

機能と特長(予定を含む)

Grafana と似たビジュアライゼーション(ほぼ実装済み)

Grafana と違って,物理屋に使いやすいようになっています(ほぼ実装済み):

さらに,コントロール用の機能も実装しています(8割くらい完成):

将来的には,

Grafana にあって今の SlowDash にないもの:

実験でよく使われるけど,今の SlowDash にないもの:

JSROOT や Bokeh との違い:

よくある宣伝

もはや当たり前だけど,みんな書いているので,いちおう書いておきます.

インストール

動作環境

使っているデータベースを読むライブラリが必要な以外は,基本的に Python 3 が動けばすぐ使えます.

使っているデータベースに合わせて,Python のライブラリを別にインストールする必要があります.pip ですぐに入ります.

データベース Python モジュール
PostgreSQL psycopg2
MySQL mysqlclient
SQLite 追加ライブラリは不要
InfluxDB influxdb-client
Redis redis
MongoDB pymongo
CouchDB couchdb

疑似データベースとして,CPU やメモリなどのシステムリソースをデータとして返すものもあります.便利なので入れておいていいと思います.

データソース Python モジュール
システム情報 psutil

ダウンロード

GitHub からダウンロードできます. サブモジュールを使っているので,--recurse-submodules オプションをつけてください.

$ git clone https://github.com/slowproj/slowdash.git --recurse-submodules

(git コマンドが利用できない場合,github のページ からパッケージをダウンロードすることもできます.)

これで,slowdash というディレクトリが作成されます.インストールおよび次の Quick Tour では,全てのファイルは slowdash のディレクトリ以下に作られるので,この過程でユーザのシステムが汚されることはありません.また,このディレクトリを削除すれば,全てをなかったことにできます.

ドキュメント

公式ドキュメントは,展開したディレクトリの docs 以下にあります.index.html をブラウザで開いてください.

$ firefox slowdash/docs/index.html

(macOS 等では,firefox コマンドを直接実行するのではなく,open コマンドを介するようです.)

日本語の隠しドキュメントは FirstStep-JP.html です.今読んでいるものですが,docs から読むと内部リンクが切れていません.

$ firefox slowdash/docs/FirstStep-JP.html

インストール

$ cd slowdash
$ make

make を使っているけれど,基本的にはファイルをコピーしているだけで,一瞬で終わります.

slowdash/bin の下に環境変数を設定するスクリプト slowdash-bashrc ができるので,これを source してください.これは,新しいターミナルを開くたびに必要です.

$ source PATH/TO/SLOWDASH/bin/slowdash-bashrc

SlowDash を継続的に使うなら,上記の行を .bashrc などに書いておくと毎回やる必要がなくなります.

インストールが成功したかは,slowdash コマンドを実行してチェックできます. (slowdash コマンドは slowdash/bin の下にあります)

$ slowdash
Usage: 
  Web-Server Mode:    slowdash.py [Options] --port=PORT
  Command-line Mode:  slowdash.py [Options] Command

Options:
  -h, --help            show this help message and exit
  -p PORT, --port=PORT  port number for web connection; command-line mode
                        without this option
  --project-dir=PROJECT_DIR
                        project directory (default: current dir if not
                        specified by SLOWDASH_PROJECT environmental variable)

任意のポート番号を指定して slowdash コマンドを実行し,ブラウザとの接続を確認してください.ここで,プロジェクトがないという警告が出ますが,今はこのまま先に進みます.

$ slowdash --port=18881
23-05-15 20:12:35 WARNING: unable to find Slowdash Project Dir: specify it with the --project-dir option, set the SLOWDASH_PROJECT environmental variable, or run the slowdash commands at a project directory
listening at port 18881
$ firefox http://localhost:18881

成功すれば以下のようなエラーメッセージが表示されます.

確認したら,Ctrl-cslowdash コマンドを終了してください.

ダミーデータで UI を動かしてみる

ダミーデータを使って SlowDash の UI をテストするプロジェクトがあるので,これを使ってとりあえず動かしてみます.展開した SlowDash ディレクトリの下にある ExampleProjectsDummyDataSourcecd して,そこから slowdash を走らせてください.

$ cd PATH/TO/SLOWDASH/ExampleProjects/DummyDataSource
$ slowdash --port=18881

プラウザを立ち上げて http://localhost:18881 に接続すると作成済みページの一覧が表示されます.右上の SlowPlot にある demo をクリックすると,以下のようなプロットのデモページが表示されます.データに意味はなく,更新するたびに中身が変わりますが,SlowDash の表示要素の操作を一通り試してみることができます.

もし古いバージョンの SlowDash から更新してこの段階で不具合が出る場合は,ブラウザのキャッシュに残っている古いスクリプトが影響している可能性があります.この場合は,Ctrl-F5 などにより強制リロードを試してみてください.

Quick Tour をやってみる

ここでは,公式ドキュメントの Quick Tour の前半くらい,時系列データのプロットを作るところまでやってみます.

テスト用のデータストアには,SQLite を使います.これは,追加のライブラリをインストールせずに使用でき,また,データがファイルに保存されるため,使用後のクリーンアップが簡単なためです.

最初に,プロジェクト用のディレクトリを作成してください.ディレクトリを作る場所はどこでもいいです.このプロジェクトで作成されるファイルは全てこのディレクトリ以下に格納されます.プロジェクト終了後はディレクトリをまるごと削除しても大丈夫です.途中でプロジェクトディレクトリを別の場所へ移動することも可能です.

$ mkdir QuickTour
$ cd QuickTour

準備:SlowPy ライブラリを使ってテスト用のデータストアを作る

SlowPy は,SlowDash に含まれる Python のライブラリです.上記のインストールで,source slowdash/bin/slowdash-bashrc をしていれば,SlowPy のパスが環境変数 PYTHONPATH に追加れていて,すでに使えるようになっています.

SlowPy を使って,一秒ごとに乱数の値を SQLite に書き込むスクリプトを作成します.

from slowpy.control import DummyDevice_RandomWalk, ControlSystem
from slowpy.store import DataStore_SQLite, SimpleLongFormat


class TestDataFormat(SimpleLongFormat):
    schema_numeric = '(datetime DATETIME, timestamp INTEGER, channel STRING, value REAL, PRIMARY KEY(timestamp, channel))'
    def insert_numeric_data(self, cur, timestamp, channel, value):
        cur.execute(f'INSERT INTO {self.table} VALUES(CURRENT_TIMESTAMP,%d,"%s",%f)' % (timestamp, channel, value))

datastore = DataStore_SQLite('sqlite:///QuickTourTestData.db', table="testdata", format=TestDataFormat())
device = DummyDevice_RandomWalk(n=4)


def _loop():
    for ch in range(4):
        data = device.read(ch)
        datastore.append(data, tag="ch%02d"%ch)
    ControlSystem.sleep(1)

def _finalize():
    datastore.close()
    
    
if __name__ == '__main__':
    ControlSystem.stop_by_signal()
    while not ControlSystem.is_stop_requested():
        _loop()
    _finalize()

このスクリプトの詳細は公式ドキュメントの Controls セクションに説明があります.ここでは,上記の内容をコピペして,generate-testdata.py というファイル名でプロジェクトディレクトリに保存してください.

このスクリプトを走らせると,テスト用のデータファイルが生成されます.

$ python3 generate-testdata.py

(もしコピペに失敗してエラーが出るようであれば,同じ内容のファイルが slowdash/ExampleProjects/QuickTour/config/slowtask-testdata.py にあります.)

10 秒くらい経過したら Ctrl-c で止めて,できたファイルを確認してください.

$ ls -l
-rw-r--r-- 1 sanshiro sanshiro 24576 Apr 11 16:52 QuickTourTestData.db
-rwxr-xr-x 1 sanshiro sanshiro  3562 Apr 11 16:51 generate-testdata.py

データの中身は sqlite3 コマンドで確認できます.(このコマンドがインストールされてなければ,この手順は飛ばしていいです.)

$ sqlite3 QuickTourTestData.db 
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> .table
testdata
sqlite> .schema testdata
CREATE TABLE testdata(datetime DATETIME, timestamp INTEGER, channel TEXT, value REAL, PRIMARY KEY(timestamp, channel));
sqlite> select * from testdata limit 10;
2023-04-11 23:52:13|1681257133|ch00|0.187859
2023-04-11 23:52:13|1681257133|ch01|-0.418021
2023-04-11 23:52:13|1681257133|ch02|0.482607
2023-04-11 23:52:13|1681257133|ch03|1.733749
...

sqlite3.schema コマンド出力にあるとおり,データは testdata というテーブルに保存されていて,その構造は以下のようになっています.

testdata(datetime DATETIME, timestamp INTEGER, channel TEXT, value REAL, PRIMARY KEY(timestamp, channel))

テスト目的のために,データのタイムスタンプは日付時刻型(SQLite では ISO 表記の文字列)のものと,整数の UNIX 時間の両方が入っていますが,通常はどちらか一方のことが多いと思います.SQLite では,タイムゾーンの扱いに罠が多いので,UNIX 時間の方がいいかもしれません.

データの中身はこんな感じです:

datetime (DATETIME/TEXT) timestamp (INTEGER) channel (TEXT) value (REAL)
2023-04-11 23:52:13 1681257133 ch00 0.187859
2023-04-11 23:52:13 1681257133 ch01 -0.418021
2023-04-11 23:52:13 1681257133 ch02 0.482607
2023-04-11 23:52:13 1681257133 ch03 1.733749

ここでは,面倒な例として,日付時刻型のデータにタイムゾーンを明示しないで UTC 時刻を使用しています(SQLite ではこれがデフォルトの関数が多いです).通常は,タイムゾーン付きまたは UNIX 時間を使用してください.

時系列データのテーブルは,必ずしもこの形になっている必要はありません.特に,テーブルにカラムを追加するのが簡単なタイプのデータストアを使用している場合は,各チャンネルを各カラムにするのも普通にアリだと思います.同時に読み出したデータのグルーピングが簡単になるというメリットもあります.詳しくは,公式ドキュメントの Data Binding の章を参照してください.

プロジェクト設定

SlowDash のプロジェクトでは,通常,専用のディレクトリを作って,そこに SlowdashProject.yaml という名前のプロジェクト設定ファイルを置きます.(データファイルを直接読む場合などの例外はあります.)どこのデータベースからどのようなデータを読むかなどを,このプロジェクト設定ファイルに記述します.

プロジェクトディレクトリに,以下の内容で SlowdashProject.yaml という名前のファイルを作成してください.

slowdash_project:
  name: QuickTour   (なんでも良いが,スペースや特殊文字を含まない方が人生が楽になる)
  title: SlowDash Quick Tour  (なんでも良いが,改行や極悪な文字は含まない方がいいと思う)
  
  data_source:
    type: SQLite
    parameters:
      file: QuickTourTestData.db
      time_series:
        schema: testdata[channel]@timestamp(unix)=value

schema のところで,データのテーブル名と,どの情報がどのカラムに書かれているかを記述しています.フォーマットは,テーブル名 [チャンネル情報のカラム名] @ 時刻情報のカラム名(時刻の表現形式)= データ値のカラム名 みたいな感じです.詳しくは,DataBinding の章を参照してください.

この例では,時刻情報に,UNIX タイムスタンプの方を使っています.DateTime 型の方の時刻情報を使う場合は,schema の記述を以下のようにしてください:

      time_series:
        schema: testdata[channel]@datetime(unspecified utc)=value

ここでは,UTC 時刻がタイムゾーン指定なしで使われている悪い例に対応するために,時刻表現形式を unspecified utc (「書いてないけど UTC だよ」)と伝えています.保存されているデータがちゃんとタイムゾーン付きの場合は with timezone または aware を,最悪のケースでタイムゾーンなしでローカルタイムが使われている場合は without timezone または naive と書いてください.この情報は,SlowDash がクエリを構築する際に,データと同じ時刻表現を使用するために使われます.タイムゾーンを明示しないでローカルタイムを使った場合の惨事が多数報告されているので,新しく作るデータで without timezone を選択する理由はないです.(日本国内だけなら関係ないと思ってすでにそういう形式でデータを取ってる場合は,夏時間の導入に反対しておいた方がいいです.)

slowdash config コマンドで設定情報の一部が表示されるので,設定ファイルが読めているかのチェックができます.これは,SlowdashProject.yaml ファイルを作成したプロジェクトディレクトリで実行してください.

$ slowdash config
{
    "project": {
        "name": "QuickTour",
        "title": "SlowDash Quick Tour",
        "error_message": ""
    },
    "data_source_module": [
        "datasource_SQLite.py"
    ],
    "user_module": [],
    "style": null
}

データベースに正しくアクセスできる場合,slowdash channels コマンドでチャンネルの一覧を表示できます.

$ slowdash channels
[
  {"name": "ch00"}, {"name": "ch01"}, {"name": "ch02"}, ...
]

データの中身は,slowdash data/CHANNEL コマンドで見ることができます.

$ slowdash "data/ch00?length=10"
{
  "ch00": {
    "start": 1680223465, "length": 10, 
    "t": [0.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], 
    "x": [5.180761, 5.92074, 5.515459, 4.883299, 5.650556, 4.284527, 3.884656, 3.223627, 2.06343]
  }
}

もう気づいたかもしれませんが,slowdash コマンドの第1引数は HTTP でアクセスした場合の URL で,出力はそのリプライです.

サーバーを走らせる

SlowDash にネットワークからアクセスするために,--port オプションで適当なポート番号を指定します.これで,コマンドを HTTP 経由で受け取るようになります.

$ slowdash --port=18881

SlowDash を走らせたままブラウザを立ち上げ,使ったポートに接続してください.

$ firefox http://localhost:18881

今回はプロジェクト付きで走らせているので,以下のようなスタートページが表示されるはずです.

テスト用のデータベースにデータを継続的に記録するため,別ターミナルで先程のデータ生成プログラムを走らせてください.

(別ターミナルを開く)
$ cd PATH/TO/MySlowDashProject
$ python3 ./generate-testdata.py

データサイズは一時間で 5MB 程度なので,しばらくは走らせ続けて大丈夫です.データファイル(QuickTourTestData.db)は,SlowDash が走ってなければ,いつ消しても構いません.またデータが欲しくなったら,再度 generate-testdata.py を走らせてください.(データファルを削除せずに走らせても問題ありません.複数同時に走らせたら変なことになると思います.)

プログラムの終了は,全て Ctrl-c です.それなりに上品に止まります.だめだったら,Ctrl-\ を使ってください.

ブラウザでデータを見る

ブラウザ上の青い文字のところをクリックすればいろいろとプロットを作成できます.上部の紫色は,東北大学とワシントン大学の共通テーマカラーなので我慢してください.(プロジェクト設定ファイルで変更できます.Project Setup の章に説明があります.)

右上の Slow-Plot にある Blank または Blank 2x2 では,新しい空のページを作ります.その中で,Add a New Panel を選んで,プロットを作成していきます.たぶん自明です.

左下の Channel List のチャンネル名をクリックすると,直近の時系列データのプロットを含んだページが作成されます.それを元にいろいろ追加していくこともできます.

ここまでの準備では時系列データしか生成していないので,すぐにできるのは,それを直接プロットする Time-Axis Plot (Time-Series) と,値分布のヒストグラムを作る XY Plot (Histograms and Graphs)Histogram of Time-Series Values です.ここから先は,公式ドキュメントの UI Panels の章などを参照してください.

セキュリティについて

SlowDash は,ファイアウォールの内部で使う目的で作られています. このためセキュリティ関係の機能は実装されていません.SlowDash のポートを外部からアクセスできるところに開けないようにしてください.外部からは,VPN もしくは SSH のトンネルを経由して使用するのが想定です.

もし内部の人を信用できない場合,最低限として,基本認証を使ってパスワードを設定することはできます.この場合は,リバースプロキシを使って HTTPS に乗せ換え,パスワードと通信を暗号化してください.

基本認証の設定は,SlowdashProject.yamlauthentication エントリを追加し,パスワードハッシュを指定します.

slowdash_project:
  ...

  authentication:
    type: Basic
    key: slow:$2a$12$UWLc20NG5E3drX35cfA/5eFxuDVC0U79dGg4UP/mo55cj222/vuRS

パスワードハッシュは,slowdash authkey/USER?password=PASS コマンドにより作ることがきます.

$ slowdash authkey/slow?password=dash
{
    "type": "Basic",
    "key": "slow:$2a$12$UWLc20NG5E3drX35cfA/5eFxuDVC0U79dGg4UP/mo55cj222/vuRS"
}

このパスワードハッシュは Apache でも流用できますが,Apache で今でも広く使われている古いタイプのハッシュは,SlowDash では使えません.

リバースプロキシの設定方法については,大規模言語モデル系の AI が詳しく教えてくれます.もとのポートはちゃんと塞いでおいてください.

ローカルマシン上でパケットダンプができる人からシステムを守る術はありませんが,そういう人は別の方法でもっと簡単に攻撃できるはずです.