RedashアラートのRearm Secondsとは何をするものなのか
Redashを使っていて特に便利だと感じるのがアラート機能。うちの会社では、自社サービスの異常値検知のためにアラート機能を多用している。
しかし、アラートの設定画面にある Rearm Seconds
という項目は、公式サイトの説明が少なく、どのような動きをするのかよくわからなかった。そこで、実際にコードを見て仕様を確かめることにした。
2019/02/13現在、アラートを制御するコードは以下にまとまっている。
@celery.task(name="redash.tasks.check_alerts_for_query", time_limit=300, soft_time_limit=240) def check_alerts_for_query(query_id): logger.debug("Checking query %d for alerts", query_id) query = models.Query.query.get(query_id) for alert in query.alerts: new_state = alert.evaluate() if should_notify(alert, new_state): logger.info("Alert %d new state: %s", alert.id, new_state) old_state = alert.state alert.state = new_state alert.last_triggered_at = utils.utcnow() models.db.session.commit() if old_state == models.Alert.UNKNOWN_STATE and new_state == models.Alert.OK_STATE: logger.debug("Skipping notification (previous state was unknown and now it's ok).") continue notify_subscriptions(alert, new_state)
Redashは、アラートに登録されたクエリの実行結果をceleryが定期的に取得し、アラートを起動させるかどうかを決めている。new_state
には、アラートの状態(OK_STATE
, TRIGGERED_STATE
, UNKNOWN_STATE
)のいずれかが入る。そして、クエリの結果に応じた状態を一旦 new_state
に入れたうえで、 should_notify
関数で実際にアラートを動かすか判定している。もし True
と判定されれば、 alert.state = new_state
というように状態を更新し、 notify_subscription
関数の処理でアラートが通知される。
ここで鍵になるのが should_notify
関数の役割。このメソッドは以下のようになっている。
def should_notify(alert, new_state): passed_rearm_threshold = False if alert.rearm and alert.last_triggered_at: passed_rearm_threshold = alert.last_triggered_at + datetime.timedelta(seconds=alert.rearm) < utils.utcnow() return new_state != alert.state or (alert.state == models.Alert.TRIGGERED_STATE and passed_rearm_threshold)
Rearm Seconds
の欄に値を入れると、その値は alert.rearm
に入る。そして、 passed_rearm_threshold
には、アラートが前回起動した時刻から alert.rearm
で指定した秒数が経過しているかどうかが True
または False
で入る。
これをふまえて最終行を見ると、以下のいずれかの時にアラートが起動することがわかる。
- クエリの実行結果が、元々のアラートの状態とは異なるとき
- 元々のアラートの状態が
TRIGGERED_STATE
で、かつ前回起動時刻からRearm Seconds
以上が経過しているときRearm Seconds
を指定していないときは、上記は無条件でFalse
となる(passed_rearm_threshold
のデフォルト値がFalse
であるため)
つまり、例えば Rearm Seconds
に 3600
と入れておけば、異常な状態が1時間経っても継続しているときは再度通知してくれる。アラートがTRIGGERED
になっていなければ、Rearm Seconds
が指定されていても再度通知されることはない。
フラグを駆使することで、状態管理のコードが思った以上に短くまとまっていて驚いた。変数名はもっと改良しても良さそうだが、これもスマートな書き方で良い。