Datadog の Help でも紹介されている、Monitor の管理ツールの DogPush に触れる機会があったので、使い方をまとめます。
目次
- 前提・注意事項
— 基本的には全Monitorが対象
— 同名 Monitor は未サポート
— Message が空の Monitor は未サポート - インストール
- config.yaml ファイル
— config.yaml の作成
— デフォルトルール(default_rules)
— デフォルトルールオプション(default_rule_options)
— チーム(teams) - initコマンド
— 実行例 - diffコマンド
- pushコマンド
— delete_untracked オプション - muteコマンド
— mute_tags 定義 - まとめ
前提・注意事項
基本的には全Monitorが対象
タグ等による絞り込み機能はありません。 出力や比較には全 Monitor の定義が使用されます。
同名 Monitor は未サポート
Datadog の Monitor は 同名の物を定義できますが、dogpush では未サポートとなります。
Monitor 名称で管理しているため重複エラーとなります。 dogpush に限らず、 Datadog のツール系はこの制約に引っ掛かる事が多い気がします。
$ dogpush init Duplicate name: MonitorTest4 Traceback (most recent call last): File "/usr/bin/dogpush", line 5, indogpush.main() File "/usr/lib/python2.7/site-packages/dogpush/dogpush.py", line 397, in main args.command() File "/usr/lib/python2.7/site-packages/dogpush/dogpush.py", line 215, in command_init remote_monitors = [m['obj'] for m in get_datadog_monitors().values()] File "/usr/lib/python2.7/site-packages/dogpush/dogpush.py", line 139, in get_datadog_monitors 'Duplicate names found in remote datadog monitors.') dogpush.dogpush.DogPushException: Duplicate names found in remote datadog monitors.
Message が空の Monitor は未サポート
実運用ではあまり無いかと思いますが、 現バージョンでは本文部分が空の場合に失敗します。Web UI 上では空での作成は不可ですが、APIだと作成できてしまいます。
message 部分に以下のようなメッセージが含まれてしまい、出力内容をそのまま利用することができません。
- message: !!python/unicode ''
一見上記部分を排除すれば利用できそうですが、重複エラーに引っ掛かります。
インストール
README を参考にインストールを行います。 今回は素に近い CentOS7 で試してます。必要パッケージは環境により変わると思います。
$ cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) $ python -V Python 2.7.5 $ sudo yum install python2-pip openssl-devel python-devel libffi-devel ・・・ Complete! $ pip -V pip 8.1.2 from /usr/lib/python2.7/site-packages (python 2.7) $ sudo pip install -U pip dogpush ・・・ Successfully installed PyYAML-3.12 datadog-0.15.0 decorator-4.0.11 dogpush-0.3.3 pip-9.0.1 pytz-2017.2 requests-2.13.0 simplejson-3.10.0 $ pip -V pip 9.0.1 from /usr/lib/python2.7/site-packages (python 2.7) $ dog -v dog 0.15.0 $ dogpush -h usage: dogpush [-h] [--config CONFIG] {init,push,diff,mute} ... positional arguments: {init,push,diff,mute} sub-command help init init new alerts file push push monitors to datadog diff show diff between local monitors and datadog mute Mute alerts based on their `mute_when` key optional arguments: -h, --help show this help message and exit --config CONFIG, -c CONFIG configuration file to load (default: ./config.yaml)
datadog パッケージが依存関係として含まれるため、 dogshell(dogコマンド)もインストールされます。
尚、後述 delete_untracked オプションで記載していますが、バージョンが古いようでしたので再度 GitHub からインストールし直しています。
config.yaml ファイル
Datadog の Key 情報を定義する config.yaml が無いとエラーとなります。
$ dogpush init Traceback (most recent call last): File "/usr/bin/dogpush", line 3, infrom dogpush import dogpush File "/usr/lib/python2.7/site-packages/dogpush/dogpush.py", line 391, in CONFIG = _load_config(args.config) File "/usr/lib/python2.7/site-packages/dogpush/dogpush.py", line 29, in _load_config with open(config_file, 'r') as f: IOError: [Errno 2] No such file or directory: './config.yaml'
config.yaml の作成
Datadog の API Key、App Key を記載します。
cat <<_EOF > config.yaml datadog: api_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX app_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx _EOF
デフォルトルール(default_rules)
パラメータ未指定時の既定値となる値を指定します。 README 上は multi,message とありますが、 実際は multi,type かと思います。
ルール | 既定値 | 内容 |
---|---|---|
multi | False | Multi アラートか否か {true, false} |
type | metric alert | モニターのタイプ {metric alert, service check, event alert} |
init,diff 時は config で指定した値は未出力となり、 push 時は既定値として設定されます。 そのため、本来 metric alert である設定項目に対し、service check をデフォルト値とした場合等はAPIエラーとなります。
$ dogpush push Pushing 1 new monitors. Traceback (most recent call last): File "/usr/bin/dogpush", line 5, inpkg_resources.run_script('DogPush==0.3.3', 'dogpush') File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 540, in run_script self.require(requires)[0].run_script(script_name, ns) File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 1455, in run_script execfile(script_filename, namespace, namespace) File "/usr/lib/python2.7/site-packages/DogPush-0.3.3-py2.7.egg/EGG-INFO/scripts/dogpush", line 5, in dogpush.main() File "/usr/lib/python2.7/site-packages/DogPush-0.3.3-py2.7.egg/dogpush/dogpush.py", line 407, in main args.command(args) File "/usr/lib/python2.7/site-packages/DogPush-0.3.3-py2.7.egg/dogpush/dogpush.py", line 230, in command_push datadog.api.Monitor.create(**_prepare_monitor(local_monitors[name])) File "/usr/lib/python2.7/site-packages/datadog/api/resources.py", line 40, in create attach_host_name=attach_host_name, **params) File "/usr/lib/python2.7/site-packages/datadog/api/api_client.py", line 150, in submit raise ApiError(response_obj) datadog.api.exceptions.ApiError: {'errors': ["The value provided for parameter 'query' is invalid"]}
デフォルトルールオプション(default_rule_options)
使い方がわかりませんでした。 config.yaml へ記述するとAssertionError
となってしまい、利用できませんでした。
ルールファイル(〜.yaml) へ記述して既定値を設定するのかと思いましたが、ルールファイルへの記述は無視されました。
チーム(teams)
通知設定を記述できます。 config.yaml へ通知先の指定を行い、各ルールファイルの先頭で定義したteamを指定します。
各 monitor 設定で severity
を指定することで通知先の振分が行えます。
- config.yamlへの記載例
- シングルクォート囲み必須
- servirity は
CRITICAL
がデフォルト、その他は任意文字列可
teams: team-A: notifications: CRITICAL: '@hoge@example.com @slack-XXXXX' WARNING: '@hoge@example.com' INFO: '通知無し' FATAL: 'Fatal @all' team-B: notifications: CRITICAL: '@hoge@example.com'
- ルール yaml への記載例(team)
$ head -n 3 monitors.team* ==> monitors.team1.yaml <== team: team-A alerts: ==> monitors.team2.yaml <== team: team-B alerts:
- ルール yaml への記載例(severity)
- message: 'Test Team Alert 1-1' name: TeamAlert1-1 options: {new_host_delay: 300, require_full_window: true, thresholds: {critical: 50.0, warning: 30.0}} query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 - message: 'Test Team Alert 1-2' name: TeamAlert1-2 options: {new_host_delay: 300, require_full_window: true, thresholds: {critical: 50.0, warning: 30.0}} query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 severity: WARNING - message: 'Test Team Alert 1-3' name: TeamAlert1-3 options: {new_host_delay: 300, require_full_window: true, thresholds: {critical: 50.0, warning: 30.0}} query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 severity: INFO - message: 'Test Team Alert 1-4' name: TeamAlert1-4 options: {new_host_delay: 300, require_full_window: true, thresholds: {critical: 50.0, warning: 30.0}} query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 severity: FATAL
message 末尾に通知設定を追加することができます。
{"name":"TeamAlert1-1","message":"Test Team Alert 1-1\n@hoge@example.com @slack-XXXXX"} {"name":"TeamAlert1-2","message":"Test Team Alert 1-2\n@hoge@example.com"} {"name":"TeamAlert1-3","message":"Test Team Alert 1-3\n通知無し"} {"name":"TeamAlert1-4","message":"Test Team Alert 1-4\nFatal @all"
init コマンド
全 Monitor を対象とした YAML を出力します。
絞り込みのオプションはありません。
usage: dogpush init [-h]
実行例
そのまま実行すると標準出力となるため、リダイレクトなどでファイル出力とすることになると思います。
$ dogpush init # team: TEAMNAME alerts: - message: 'Test2: alert message to @hoge@example.com' multi: true name: MonitorTest2 options: {new_host_delay: 300, notify_no_data: false, require_full_window: true} overall_state_modified: 'yyyy-mm-ddThh:mm:ss.560069+00:00' query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 - message: 'Test3: alert message to @hoge@example.com' multi: true ・・・略 $ dogpush init > my_monitors.yaml $
diff コマンド
Datadog 上の Monitor 登録内容とローカルのYAMLとの比較を行います。
対象とする monitor 定義(ここでは my_monitors.yaml) を config.yaml へ追加した上で利用します。
cat <<_EOF >> config.yaml rule_files: - my_monitors.yaml _EOF
差分が無い場合は何も出力されません。
$ dogpush diff $
差分がある場合は diff 結果が出力されます。
$ dogpush diff --------------------------------------------------------- TO BE UPDATED. These monitors exist in datadog, but are different than the local version. Use "dogpush push" to push them to datadog. --------------------------------------------------------- --- datadog:MonitorTest2 +++ /home/vagrant/dogpush/my_monitors.yaml:MonitorTest2 @@ -1,4 +1,4 @@ -message: 'Test2: alert message to @hoge@example.com' +message: 'Test2: alert message to @hoge@example.com Update' multi: true name: MonitorTest2 options: {new_host_delay: 300, notify_no_data: false, require_full_window: true} $
差分が name の場合は更新ではなく、新規追加として扱われます。
$ dogpush diff --------------------------------------------------------- NEW MONITORS. These monitors are currently missing in datadog and can be pushed using "dogpush push" --------------------------------------------------------- - message: MonitorTest1 multi: true name: MonitorTest1 Update options: new_host_delay: 300 no_data_timeframe: 2 notify_no_data: false renotify_interval: 0 require_full_window: true thresholds: {critical: 50.0} timeout_h: 0 overall_state_modified: 'yyyy-mm-ddThh:mm:ss.560069+00:00' query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 ------------------------------------------------------------ UNTRACKED MONITORS. These monitors are only in datadog and needed to be MANUALLY added to a local file or removed from datadog. ------------------------------------------------------------ - message: MonitorTest1 multi: true name: MonitorTest1 options: new_host_delay: 300 no_data_timeframe: 2 notify_no_data: false renotify_interval: 0 require_full_window: true thresholds: {critical: 50.0} timeout_h: 0 overall_state_modified: 'yyyy-mm-ddThh:mm:ss.560069+00:00' query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 *** FAILED *** Untracked monitors found.
push コマンド
Datadog 上の Monitor へローカルのYAMLの変更点を反映します。
対象とする monitor を config.yaml へ追加した上で利用します。
usage: dogpush push [-h]
$ dogpush push Pushing 1 new monitors. Updating 1 modified alerts
削除は行われません。 その為、 nameの変更を行った場合は別途削除が必要になります。
- name を更新した場合、更新前の情報が残る
------------------------------------------------------------ UNTRACKED MONITORS. These monitors are only in datadog and needed to be MANUALLY added to a local file or removed from datadog. ------------------------------------------------------------ - message: MonitorTest1 multi: true name: MonitorTest1 options: new_host_delay: 300 no_data_timeframe: 2 notify_no_data: false renotify_interval: 0 require_full_window: true thresholds: {critical: 50.0} timeout_h: 0 overall_state_modified: 'yyyy-mm-ddThh:mm:ss.560069+00:00' query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 *** FAILED *** Untracked monitors found.
delete_untracked オプション
yaml に含まれていない monitor を削除するオプションです。
pip からインストールした物は少々バージョンが古いようで、使用できませんでした。
$ dogpush push --delete_untracked usage: dogpush [-h] [--config CONFIG] {init,push,diff,mute} ... dogpush: error: unrecognized arguments: --delete_untracked
GitHub 上では追加されているようでしたので、 git clone して再導入します。
# pip でインストールしたバージョンの削除 $ sudo pip uninstall dogpush Uninstalling DogPush-0.3.3: /usr/bin/dogpush /usr/lib/python2.7/site-packages/DogPush-0.3.3-py2.7.egg Proceed (y/n)? y Successfully uninstalled DogPush-0.3.3 # GitHub からインストール $ git clone https://github.com/trueaccord/DogPush.git $ cd DogPush $ sudo python setup.py install ・・・ Finished processing dependencies for DogPush==0.3.3 # dlete_untracked オプションが追加されていることを確認 $ dogpush push -h usage: dogpush push [-h] [-d] optional arguments: -h, --help show this help message and exit -d, --delete_untracked Delete untracked monitors.
オプションを付けた状態で実行すると monitor の削除が行われます。
$ dogpush push --delete_untracked Deleting 1 untracked monitors. $ dogpush diff $
mute コマンド
mute_tags を定義済みの Monitor へ Downtime を設定します。
usage: dogpush mute [-h]
mute_tags 定義
config.yaml へ mute 対象時間帯の定義を行い、各 monitor 設定で mute_when
を指定することで mute 対象モニターとします。
- config.yamlへの記載例
mute_tags: mute_a: timezone: Asia/Tokyo expr: now.hour
- ルール yaml への記載例(mute_when)
- message: 'Test MuteAlert' name: MuteAlert options: {new_host_delay: 300, require_full_window: true, thresholds: {critical: 50.0, warning: 30.0}} query: avg(last_5m):max:system.cpu.user{*} by {host} >= 50 mute_when: mute_a
- 実行例
$ dogpush mute Muting alert 'MuteAlert' until yyyy-mm-dd 10:00:00+09:00
対象モニターが mute 状態となります。
Downtimes でも確認できます。
まとめ
Datadog 公式の dogshell には monitor の pull/push がありません(ダッシュボード screenboard/timeboard 操作は用意されていますが、 monitor はありません。)ので、 その部分を補完できると思います。
注意事項に記載した通りいくつか制約はありますが、 YAML での記述となるので、JSONファイルよりは扱い易いかと思いました。