datadogでタグを使って1モニターから複数の通知先を出し分け設定する


結論: is_matchでがんばる

datadogを使用していると、「このホストからのアラートはroom-aに、このホストからのアラートはroom-bに、でroom-bのときは @channelつけて」などの出し分けをしたくなります。
これまではシステムグループや役割に応じてタグを付与して、モニターを複数作成するという運用を続けていましたが、同じ監視をおこなうモニターが複数できあがり、SaaSを使用しているにもかかわらず運用コストが非常に大きくなってしまったので、 どうにかして1つのモニターで通知先を分けられないかを調べていたところ、 is_match を使うことで対応できたので覚書として投稿します。

タグを設定してis_matchで拾う

datadog-agentを起動している・これから起動するホストのdatadog.confを編集します。
tagsの項目に以下のようにタグを追加します。

datadog.conf
tags: alert_to:slack-room-a

tagsはコロン区切りで複数設定できます。
tags: alert_to:slack-room-a,role:api

このファイルでagentを起動した場合、datadog monitorのtemplateで以下のように記述すると条件分岐することが可能です。

{{#is_match "host.alert_to" "slack-room-a"}}
@slack-a
{{/is_match}}

先程datadog.confで設定した alert_to というタグキーは、 host.alert_to という形でとれます。
なお、どういうタグを指定できるかはmonitorの編集画面にある Use message template variables をクリックすると使用可能なタグを確認することが出来ます。
(これは独自に追加したtagについても表示されるので、とても役立ちます


※ 画像元: http://docs.datadoghq.com/ja/monitoring/

詰まりポイント: {{#is_match "alert_to" "slack-room-a"}} だと引っかかりません。気をつけましょう

タグがない場合の対応方法

既に起動中のインスタンス等のケアやあえてタグを付与しない運用を行うといった対応で、 タグがない場合は特定の通知先に通知するといったことが必要になると思います。
その場合、以下の記述をすることでタグが設定されていない条件分岐をすることが可能です。

{{^is_match "host.alert_to" ""}}
this host is no alert_to tag
{{/is_match}}

ただし、この方法だと「タグだけは設定されている」という場合を拾うことができません。
設定漏れに気をつけましょう。

記述例

以上を振り返り、各モニターで以下の例のように状態やタグを踏まえた通知出し分けの記述することができます。
(見やすいようにスペースを入れています。)

{{#is_warning}}
{{#is_match "host.alert_to" "slack-room-a"}} @slack-a {{/is_match}} 
{{#is_match "host.alert_to" "slack-room-b"}} @slack-b {{/is_match}} 
{{^is_match "host.alert_to" ""            }} @slack-c {{/is_match}} 
{{/is_warning}} 

{{#is_alert}}
<!channel> 障害発生。対応してください
{{#is_match "host.alert_to" "slack-room-a"}} @slack-a @pagerduty-a {{/is_match}} 
{{#is_match "host.alert_to" "slack-room-b"}} @slack-b @pagerduty-b {{/is_match}} 
{{^is_match "host.alert_to" ""            }} @slack-c @pagerduty-c {{/is_match}}
{{/is_alert}}

{{#is_recovery}}
{{#is_match "host.alert_to" "slack-room-a"}} @slack-a {{/is_match}} 
{{#is_match "host.alert_to" "slack-room-b"}} @slack-b {{/is_match}} 
{{^is_match "host.alert_to" ""            }} @slack-c {{/is_match}} 
{{/is_recovery}}

おまけ

試してみてダメだったパターン集

{{^alert_to}} {{/alert_to}}                 #=> syntaxは問題ないが、機能せず常に(いわゆる)else句に入った

{{^host.alert_to}} {{^host.alert_to}}       #=> syntax error

{{^"host.alert_to"}} {{^"host.alert_to"}}   #=> syntax error