Dogshellを使ってDatadogのモニターの設定を変更してみた

2020.05.19

こんにちは、CX事業本部の若槻です。

今回は、DatadogのCLIツールである「Dogshell」の基本的な使い方を確認しつつ、モニターの設定変更を行ってみたのでご紹介します。

Dogshellの基本的な使い方

まずは、Dogshellの基本的な使い方を確認します。

インストール

Dogshellはpipでインストールできます。

$ pip install datadog

認証の設定

DogshellでDatadogに接続する際の認証の設定を行います。(基本的にはこちらに書いてある内容です。)

認証には「API key」と「application key」を使います。これらのキー値は、Datadogのコンソールで[Integrations] - [APIs]より確認可能です。未作成だったり既存と別のキーを使いたい場合は、[New API Key]や[New application key]から新規作成してください。 image.png

Dogshellの認証を設定するには、何かしらのdogコマンドを実行します。

$ dog metric post test_metric 1

.dogrcファイルが未作成なら、以下のように聞かれるのでYを入力して[Enter]を押下します。

/home/ec2-user/.dogrc does not exist. Would you like to create it? [Y/n]

API Keyを聞かれるので、先ほど確認したキー値を入力して[Enter]を押下します。

What is your api key? (Get it here: https://app.datadoghq.com/account/settings#api) 

application keyを聞かれるので、先ほど確認したキー値を入力して[Enter]を押下します。

What is your application key? (Generate one here: https://app.datadoghq.com/account/settings#api) 

最後に以下のように応答があれば認証の設定は完了です。

Wrote /home/ec2-user/.dogrc

キー値が不正の場合は下記のように応答があります。この場合は.dogrcファイルを削除して最初から認証の設定をやり直してください。

Wrote /home/ec2-user/.dogrc
ERROR: Forbidden

利用可能なdogコマンドとパラメータの確認

ドキュメントによると以下のコマンドが利用可能とのことです。使用方法はそれぞれのコマンドに-hオプションを追加すると確認できます。

  • dog metric
  • dog event
  • dog status_check
  • dog monitor
  • dog downtime
  • dog timeboard
  • dog screenboard
  • dog host
  • dog tag
  • dog search
  • dog comment

例:dog monitorの場合

$ dog monitor -h
usage: dog monitor [-h] [--string_ids]
                   {post,fpost,update,fupdate,show,show_all,delete,mute_all,unmute_all,mute,unmute,can_delete,validate}
                   ...

optional arguments:
  -h, --help            show this help message and exit
  --string_ids          Represent monitor IDs as strings instead of ints in
                        JSON

Verbs:
  {post,fpost,update,fupdate,show,show_all,delete,mute_all,unmute_all,mute,unmute,can_delete,validate}
    post                Create a monitor
    fpost               Create a monitor from file
    update              Update existing monitor
    fupdate             Update existing monitor from file
    show                Show a monitor definition
    show_all            Show a list of all monitors
    delete              Delete a monitor
    mute_all            Globally mute monitors (downtime over *)
    unmute_all          Globally unmute monitors (cancel downtime over *)
    mute                Mute a monitor
    unmute              Unmute a monitor
    can_delete          Check if you can delete some monitors
    validate            Validates if a monitor definition is correct

コマンドごとの詳細なパラメータについては[Datadog API REFERENCE V1 MONITORS]を参照します。DogshellはDatadog APIを叩く公式CLIなので、shell自体のドキュメントはありませんが、APIドキュメントを見れば確認は可能です。

例えばdog monitor updateコマンドの場合は、[Monitors]の[Edit a monitor]の箇所を参照すれば、API利用時のリクエストボディのFIELDの指定について記載があるので確認が可能です。

image.png

dogコマンドの戻り値について

dogコマンドをそのまま実行した場合は、その出力はテキストライクな戻り値となります。

$ dog monitor show_all
18558846        sample-table's item count is over the threshole!!!      [DynamoDB] item count alert     {'notify_audit': False, 'locked': False, 'timeout_h': 1, 'silenced': {}, 'include_tags': True, 'new_host_delay': 300, 'notify_no_data': False}       416420  sum(last_1h):avg:aws.dynamodb.item_count{tablename:sample-table} > 1    metric alert
18604789        dynamodb's account max read is over the threshole!!!    [DynamoDB] account max read     {'notify_audit': False, 'locked': False, 'timeout_h': 0, 'silenced': {}, 'include_tags': True, 'no_data_timeframe': None, 'require_full_window': False, 'new_host_delay': 300, 'notify_no_data': False, 'renotify_interval': 0, 'escalation_message': '', 'thresholds': {'critical': 100.0}} 416420  sum(last_5m):avg:aws.dynamodb.account_max_reads{*}.as_count() > 100  query alert
18604871        DynamoDB's invocations count is over the threshole!!!   [Lambda] invocations count alert        {'notify_audit': False, 'locked': False, 'timeout_h': 0, 'silenced': {}, 'include_tags': True, 'no_data_timeframe': None, 'require_full_window': False, 'new_host_delay': 300, 'notify_no_data': False, 'renotify_interval': 0, 'escalation_message': '', 'thresholds': {'critical': 50.0}}  416420  sum(last_5m):avg:aws.lambda.invocations{*}.as_count() > 50   query alert

戻り値をJSON形式としたい場合は--rawオプションを付与して実行します。--rawを付与することによりオプションなしでは取得できない詳細な項目も取得できます。

$ dog --raw monitor show_all
[{"restricted_roles": null, "tags": [], "deleted": null, "query": "sum(last_1h):avg:aws.dynamodb.item_count{tablename:sample-table} > 1", "message": "sample-table's item count is over the threshole!!!", "matching_downtimes": [], "id": 18558846, "multi": false, "name": "[DynamoDB] item count alert", "created": "2020-05-17T14:26:41.188341+00:00", "created_at": 1589725601000, "creator": {"id": 1779447, "handle": "hoge@contoso.com", "name": "Name, fuga", "email": "hoge@contoso.com"}, "org_id": 416420, "modified": "2020-05-17T17:29:20.690451+00:00", "overall_state_modified": "2020-05-17T14:28:27+00:00", "overall_state": "Alert", "type": "metric alert", "options": {"notify_audit": false, "locked": false, "timeout_h": 1, "silenced": {}, "include_tags": true, "new_host_delay": 300, "notify_no_data": false}}, {"restricted_roles": null, "tags": [], "deleted": null, "query": "sum(last_5m):avg:aws.dynamodb.account_max_reads{*}.as_count() > 100", "message": "dynamodb's account max read is over the threshole!!!", "matching_downtimes": [], "id": 18604789, "multi": false, "name": "[DynamoDB] account max read", "created": "2020-05-19T10:28:44.760092+00:00", "created_at": 1589884124000, "creator": {"id": 1779447, "handle": "hoge@contoso.com", "name": "Name, fuga", "email": "hoge@contoso.com"}, "org_id": 416420, "modified": "2020-05-19T10:28:44.760092+00:00", "overall_state_modified": "2020-05-19T10:31:09+00:00", "overall_state": "Alert", "type": "query alert", "options": {"notify_audit": false, "locked": false, "timeout_h": 0, "silenced": {}, "include_tags": true, "no_data_timeframe": null, "require_full_window": false, "new_host_delay": 300, "notify_no_data": false, "renotify_interval": 0, "escalation_message": "", "thresholds": {"critical": 100.0}}}, {"restricted_roles": null, "tags": [], "deleted": null, "query": "sum(last_5m):avg:aws.lambda.invocations{*}.as_count() > 50", "message": "DynamoDB's invocations count is over the threshole!!!", "matching_downtimes": [], "id": 18604871, "multi": false, "name": "[Lambda] invocations count alert", "created": "2020-05-19T10:30:50.374286+00:00", "created_at": 1589884250000, "creator": {"id": 1779447, "handle": "hoge@contoso.com", "name": "Name, fuga", "email": "hoge@contoso.com"}, "org_id": 416420, "modified": "2020-05-19T10:30:50.374286+00:00", "overall_state_modified": null, "overall_state": "No Data", "type": "query alert", "options": {"notify_audit": false, "locked": false, "timeout_h": 0, "silenced": {}, "include_tags": true, "no_data_timeframe": null, "require_full_window": false, "new_host_delay": 300, "notify_no_data": false, "renotify_interval": 0, "escalation_message": "", "thresholds": {"critical": 50.0}}}]

戻り値がJSON形式なので、jqコマンドにパイプすれば整形も可能です。

$ dog --raw monitor show_all | jq .
[
  {
    "restricted_roles": null,
    "tags": [],
    "deleted": null,
    "query": "sum(last_1h):avg:aws.dynamodb.item_count{tablename:sample-table} > 1",
    "message": "sample-table's item count is over the threshole!!!",
    "matching_downtimes": [],
    "id": 18558846,
    "multi": false,
    "name": "[DynamoDB] item count alert",
    "created": "2020-05-17T14:26:41.188341+00:00",
    "created_at": 1589725601000,
    "creator": {
      "id": 1779447,
      "handle": "hoge@contoso.com",
      "name": "Name, fuga",
      "email": "hoge@contoso.com"
    },
    "org_id": 416420,
    "modified": "2020-05-17T17:29:20.690451+00:00",
    "overall_state_modified": "2020-05-17T14:28:27+00:00",
    "overall_state": "Alert",
    "type": "metric alert",
    "options": {
      "notify_audit": false,
      "locked": false,
      "timeout_h": 1,
      "silenced": {},
      "include_tags": true,
      "new_host_delay": 300,
      "notify_no_data": false
    }
  },
  {
    "restricted_roles": null,
    "tags": [],
    "deleted": null,
    "query": "sum(last_5m):avg:aws.dynamodb.account_max_reads{*}.as_count() > 100",
    "message": "dynamodb's account max read is over the threshole!!!",
    "matching_downtimes": [],
    "id": 18604789,
    "multi": false,
    "name": "[DynamoDB] account max read",
    "created": "2020-05-19T10:28:44.760092+00:00",
    "created_at": 1589884124000,
    "creator": {
      "id": 1779447,
      "handle": "hoge@contoso.com",
      "name": "Name, fuga",
      "email": "hoge@contoso.com"
    },
    "org_id": 416420,
    "modified": "2020-05-19T10:28:44.760092+00:00",
    "overall_state_modified": "2020-05-19T10:31:09+00:00",
    "overall_state": "Alert",
    "type": "query alert",
    "options": {
      "notify_audit": false,
      "locked": false,
      "timeout_h": 0,
      "silenced": {},
      "include_tags": true,
      "no_data_timeframe": null,
      "require_full_window": false,
      "new_host_delay": 300,
      "notify_no_data": false,
      "renotify_interval": 0,
      "escalation_message": "",
      "thresholds": {
        "critical": 100
      }
    }
  },
  {
    "restricted_roles": null,
    "tags": [],
    "deleted": null,
    "query": "sum(last_5m):avg:aws.lambda.invocations{*}.as_count() > 50",
    "message": "DynamoDB's invocations count is over the threshole!!!",
    "matching_downtimes": [],
    "id": 18604871,
    "multi": false,
    "name": "[Lambda] invocations count alert",
    "created": "2020-05-19T10:30:50.374286+00:00",
    "created_at": 1589884250000,
    "creator": {
      "id": 1779447,
      "handle": "hoge@contoso.com",
      "name": "Name, fuga",
      "email": "hoge@contoso.com"
    },
    "org_id": 416420,
    "modified": "2020-05-19T10:30:50.374286+00:00",
    "overall_state_modified": null,
    "overall_state": "No Data",
    "type": "query alert",
    "options": {
      "notify_audit": false,
      "locked": false,
      "timeout_h": 0,
      "silenced": {},
      "include_tags": true,
      "no_data_timeframe": null,
      "require_full_window": false,
      "new_host_delay": 300,
      "notify_no_data": false,
      "renotify_interval": 0,
      "escalation_message": "",
      "thresholds": {
        "critical": 50
      }
    }
  }
]

Dogshellでモニターの設定変更をしてみる

ここでは、作成されているすべてのDynamoDBに対するモニター(nameの先頭に[DynamoDB]とあるもの)の自動リカバリー時間(AUTO RESOLVE:timeout_h)を無期限(0)から1時間(1)に設定変更してみます。

  • すべてのモニターを取得
$ dog --raw monitor show_all | jq . > show_all.json
  • (確認)すべてのモニターをカウント
$ cat show_all.json | jq '. | length'
3
  • (確認)設定対象のモニター(モニター名が[DynamoDB]から始まる)のみ取得。現在の設定は"timeout_h": 0です。
$ cat show_all.json | jq '.[] | select(.name | startswith("[DynamoDB]"))' | jq . -s > dynamodb_monitors.json
$ cat dynamodb_monitors.json
[
  {
    "restricted_roles": null,
    "tags": [],
    "deleted": null,
    "query": "sum(last_1h):avg:aws.dynamodb.item_count{tablename:sample-table} > 1",
    "message": "sample-table's item count is over the threshole!!!",
    "matching_downtimes": [],
    "id": 18558846,
    "multi": false,
    "name": "[DynamoDB] item count alert",
    (一部項目は省略しています)
    "overall_state": "Alert",
    "type": "query alert",
    "options": {
      "notify_audit": false,
      "locked": false,
      "timeout_h": 0,
      "silenced": {},
      "include_tags": true,
      "new_host_delay": 300,
      "notify_no_data": false
    }
  },
  {
    "restricted_roles": null,
    "tags": [],
    "deleted": null,
    "query": "sum(last_5m):avg:aws.dynamodb.account_max_reads{*}.as_count() > 100",
    "message": "dynamodb's account max read is over the threshole!!!",
    "matching_downtimes": [],
    "id": 18604789,
    "multi": false,
    "name": "[DynamoDB] account max read",
    (一部項目は省略しています)
    "overall_state": "Alert",
    "type": "query alert",
    "options": {
      "notify_audit": false,
      "locked": false,
      "timeout_h": 0,
      "silenced": {},
      "include_tags": true,
      "new_host_delay": 300,
      "notify_no_data": false
    }
  }
]
  • (確認)設定対象のモニターをカウント
$ cat dynamodb_monitors.json | jq '. | length'
2
  • (確認)設定対象のモニターのid一覧
$ cat dynamodb_monitors.json | jq .[].id
18558846
18604789
  • (確認)id一覧に対するshowコマンドのループ
$ ids=$(cat dynamodb_monitors.json | jq .[].id)
$ for id in $ids
>  do
>   dog monitor show "${id}" | jq .name
>  done
"[DynamoDB] item count alert"
"[DynamoDB] account max read"

AUTO RESOLVE(option.timeout_h)をAfter 1 hourにする設定変更を実施

$ ids=$(cat dynamodb_monitors.json | jq .[].id)
$ for id in $ids
>  do
>   dog monitor update "${id}" --options '{"timeout_h": "1"}' | jq .name
>  done
"[DynamoDB] item count alert"
"[DynamoDB] account max read"

(確認)設定変更実施後の確認。timeout_h1に変更されています。

$ dog --raw monitor show_all | jq '.[] | select(.name | startswith("[DynamoDB]"))' | jq . -s > dynamodb_monitors_after.json
$ cat dynamodb_monitors_after.json
[
  {
    "restricted_roles": null,
    "tags": [],
    "deleted": null,
    "query": "sum(last_1h):avg:aws.dynamodb.item_count{tablename:sample-table} > 1",
    "message": "sample-table's item count is over the threshole!!!",
    "matching_downtimes": [],
    "id": 18558846,
    "multi": false,
    "name": "[DynamoDB] item count alert",
    (一部項目は省略しています)
    "overall_state": "Alert",
    "type": "query alert",
    "options": {
      "notify_audit": false,
      "locked": false,
      "timeout_h": 1,
      "silenced": {},
      "include_tags": true,
      "new_host_delay": 300,
      "notify_no_data": false
    }
  },
  {
    "restricted_roles": null,
    "tags": [],
    "deleted": null,
    "query": "sum(last_5m):avg:aws.dynamodb.account_max_reads{*}.as_count() > 100",
    "message": "dynamodb's account max read is over the threshole!!!",
    "matching_downtimes": [],
    "id": 18604789,
    "multi": false,
    "name": "[DynamoDB] account max read",
    (一部項目は省略しています)
    "overall_state": "Alert",
    "type": "query alert",
    "options": {
      "notify_audit": false,
      "locked": false,
      "timeout_h": 1,
      "silenced": {},
      "include_tags": true,
      "new_host_delay": 300,
      "notify_no_data": false
    }
  }
]

おわりに

今回はDogshellを介してDogshell APIを叩くことによりDatadogの設定変更を行ってみました。ターミナル上で対話式でDatadogを操作できるのでこれはこれで便利ですし、一方でDatadog APIを直接叩くのももちろん良いと思います。シチュエーションによって便利に使いこなしたいですね。

参考

以上