Norikraのクエリをテキストファイルで管理する

Norikra に登録されているクエリが大量にある場合、WebUIで登録、編集をしていると複数人での共同作業で管理しきれなくなるため、クエリをファイルにしておいてリポジトリで管理したくなります。

norikra-clientには query add, remove, suspend, resume などの機能が従来からありますが、add, removeは冪等でないため登録されているクエリに対して再度実行するとエラーになるので状態管理は難しい。

ということで、norikra-client に query dump query sync という機能を追加して 1.3.1 で取り込んでもらいました。これで JSON によってクエリを管理し、Norikraと同期することができます。

$ norikra-client query dump > dump.json
[
  {
    "name": "test",
    "group": "STDOUT()",
    "expression": "SELECT count(*)\nFROM test.win:time_batch(5 sec)",
    "targets": [
      "test"
    ],
    "suspended": false
  },
  {
    "name": "test2",
    "group": "STDOUT()",
    "expression": "SELECT count(*) FROM test.win:time_batch(10 sec)",
    "targets": [
      "test"
    ],
    "suspended": false
  }
]

JSONを編集後、query sync に食わせると Norikra に登録されているクエリとの差分を見つけて、変更があったものだけ削除、追加を行います。変更がないクエリは触らないので、1時間とか1日などのロングスパンなクエリがあっても(変更しなければ) 大丈夫です。

$ norikra-client query sync < dump.json
remove query {"name"=>"test2", "group"=>"STDOUT()", "expression"=>"SELECT count(*) FROM test.win:time_batch(10 sec)", "targets"=>["test"], "suspended"=>false}
add query {"name"=>"test2", "group"=>nil, "expression"=>"SELECT count(*) FROM test.win:time_batch(60 sec)", "targets"=>["test"], "suspended"=>false}

しかし、SQLのクエリは見やすくするために改行を入れたりインデントしたりしたいので、JSON手書きして管理するのは辛いですね。

ということで norikra-querydump-format という簡単なフィルタを書きました。query dumpJSONSQL のテキストファイルの相互変換ができます。

$ norikra-client query dump | norikra-querydump-format -i json > dump.txt
$ norikra-querydump-format -i text < dump.txt | norikra-client query sync
-- QUERY:{"name":"test","group":"STDOUT()","targets":["test"],"suspended":false}
SELECT count(*)
FROM test.win:time_batch(5 sec)

-- QUERY:{"name":"test2","group":"STDOUT()","targets":["test"],"suspended":false}
SELECT count(*) FROM test.win:time_batch(10 sec)

--QUERY: の部分が後続のクエリについてのメタデータ、それ以外の部分がクエリ本文になります。行頭が -- で始まっている行と空行は無視されるので、クエリについてのコメントなども記述できます。

ただし、一度 Norikra に sync したあと dump すると、Norikra側にはコメントなどを保存することができないので失われてしまいます。なので運用の際には、

  1. 現在 Norikra に登録されているクエリを dump, format してテキストファイルにする
  2. リポジトリでファイルを管理
  3. クエリの変更はファイルで行い、JSON にして sync する一方通行

という手順で管理するのがよいでしょう。