読者です 読者をやめる 読者になる 読者になる

vague memory

うろ覚えを無くしていこうともがき苦しむ人の備忘録

Datadog (dogコマンド) screenboard編

Datadog

Datadog公式のツール dog 使用方法まとめ screenboard 編です。

f:id:htnosm:20170323212159p:plain


目次


screenboard Modes

ダッシュボード(screenboard) 操作を行います。

f:id:htnosm:20170323212200p:plain

サブコマンド 説明
show スクリーンボード情報出力
post スクリーンボード新規作成
update スクリーンボード更新
pull スクリーンボード定義取得
push スクリーンボード更新
new_file スクリーンボードの新規作成と定義取得 (post後にpull)
delete スクリーンボードの削除
share Public URL の払い出し
revoke Public URL の削除

timeboard と異なる点としては、show_all、pull_all、web_view が無い事と、 public URL を操作する shore,revoke がある事です。

JSON形式で定義することになりますが、 1からJSONを作るのは中々難しいため、 参照用のスクリーンボードを用意して確認します。

  • サンプルスクリーンボード

f:id:htnosm:20170323212201p:plain

show

スクリーンボード定義を出力します。JSON形式で出力されます。

usage: dog screenboard show [-h] screenboard_id

前述の通り、全ダッシュボードを対象としたリスト出力(show_all)は未サポートです。 (APIとしては存在します)

実行結果

$ board_id=XXXXX3
$ dog screenboard show ${board_id} | jq '.'
{
  "board_title": "SampleScreenBoard",
  "read_only": false,
  "isIntegration": false,
  "board_bgtype": "board_graph",
  "created": "yyyy-mm-ddThh:mm:ss.454510+00:00",
  "original_title": "SampleScreenBoard",
  "modified": "yyyy-mm-ddThh:mm:ss.634253+00:00",
  "disableEditing": false,
  "height": 80,
  "width": "100%",
  "template_variables": [
    {
      "default": "*",
      "prefix": null,
      "name": "scope"
    },
・・・略
    }
  ],
  "templated": true,
  "widgets": [
    {
      "metric": "aws.ec2.host_ok",
・・・略
      },
      "res_calc_func": "raw",
      "aggr": "sum",
      "y": 13,
      "calc_func": "raw"
    },
・・・略
    }
  ],
  "disableCog": false,
  "id": XXXXX3,
  "title_edited": false,
  "isShared": false
}
# 存在しないID指定の場合
$ dog screenboard show ${board_id}X | jq '.'
ERROR: The value provided for parameter 'board_id' is invalid

post

スクリーンボードを作成します。

usage: dog screenboard post [-h] [--template_variables TEMPLATE_VARIABLES]
                            [--width WIDTH] [--height HEIGHT]
                            title description [graphs]

意図した動作となりません
新規スクリーンボードの作成は行えましたが、APIに問題があるようで、指定値が反映されません。

positional arguments:

引数 説明
title スクリーンボード名
description スクリーンボードの説明
graphs グラフ定義JSON。標準入力から読み込ませる事も可能。

optional arguments:

ロングオプション 説明
–template_variables テンプレート変数定義JSON
–width スクリーンボードの横幅を指定。pixel
–height スクリーンボードの縦幅を指定。pixel

実行例(エラー)

未修正、show コマンド結果JSONの使用

graphs の扱いに問題が有り、読み込みが行われません。 引数として渡した場合、中断(Ctrl+C)するまで返ってこず、標準入力から渡した場合、エラー Exception: bad json parameter となります。

# 引数として渡す
$ dog screenboard post "sb1" "ScreenBoard Test 1" "$(cat SampleScreenBoard.post.single.json)"
^CTraceback (most recent call last):
  File "/usr/bin/dog", line 9, in <module>
    load_entry_point('datadog==0.15.0', 'console_scripts', 'dog')()
  File "/usr/lib/python2.7/site-packages/datadog/dogshell/__init__.py", line 69, in main
    args.func(args)
  File "/usr/lib/python2.7/site-packages/datadog/dogshell/screenboard.py", line 169, in _post
    graphs = sys.stdin.read()
KeyboardInterrupt
# 標準入力から渡す
$ cat SampleScreenBoard.post.single.json | dog screenboard post "sb1" "ScreenBoard Test 1"
Traceback (most recent call last):
  File "/usr/bin/dog", line 9, in <module>
    load_entry_point('datadog==0.15.0', 'console_scripts', 'dog')()
  File "/usr/lib/python2.7/site-packages/datadog/dogshell/__init__.py", line 69, in main
    args.func(args)
  File "/usr/lib/python2.7/site-packages/datadog/dogshell/screenboard.py", line 178, in _post
    raise Exception('bad json parameter')
Exception: bad json parameter

一部修正、show コマンド結果JSONの使用(widgets配下)

post 時の不要な読み込みを削除し、showコマンド結果JSONwidgets 配下の状態で実行するとコマンド実行は成功しました。

  • screenboard.py
@@ -166,7 +166,7 @@

     @classmethod
     def _post(cls, args):
-        graphs = sys.stdin.read()
+#        graphs = sys.stdin.read()
         api._timeout = args.timeout
         format = args.format
         graphs = args.graphs
$ dog screenboard post "sb1" "ScreenBoard Test 1" "$(cat SampleScreenBoard.post.single.json)" | jq '.'
{
  "read_only": false,
  "description": "ScreenBoard Test 1",
  "title": "sb1",
  "created": "yyyy-mm-ddThh:mm:ss.739591+00:00",
  "modified": "yyyy-mm-ddThh:mm:ss.739608+00:00",
  "height": null,
  "graphs": [
    {
      "board_id": XXXX6,
      "title_size": 13,
      "title": true,
      "title_align": "left",
      "title_text": "CPU utilization by name (top 10)",
      "height": 21,
      "tile_def": {
        "viz": "timeseries",
        "requests": [
          {
            "q": "top(avg:aws.ec2.cpuutilization{$scope,$region,$availability-zone} by {name},10,'mean','desc')",
            "aggregator": "avg",
            "style": {
              "palette": "warm"
            },
            "type": "line",
            "conditional_formats": []
          }
        ]
      },
      "width": 42,
      "timeframe": "4h",
      "y": 0,
      "x": 82,
      "legend_size": "0",
      "type": "timeseries",
      "legend": false
    }
  ],
  "template_variables": [],
  "id": XXXXX1,
  "width": null
}

作成されたダッシュボードを見ると、空の状態で作成されてしまっています。

f:id:htnosm:20170323212202p:plain

show コマンドで返却される値は正しいように見えます。

$ dog screenboard show XXXXX1 | jq '.'
{
  "read_only": false,
  "description": "ScreenBoard Test 1",
  "title": "sb1",
  "created": "yyyy-mm-ddThh:mm:ss.739591+00:00",
  "modified": "yyyy-mm-ddThh:mm:ss.739608+00:00",
  "height": null,
  "graphs": [
    {
      "board_id": XXXX6,
      "title_size": 13,
      "title": true,
      "title_align": "left",
      "title_text": "CPU utilization by name (top 10)",
      "height": 21,
      "tile_def": {
        "viz": "timeseries",
        "requests": [
          {
            "q": "top(avg:aws.ec2.cpuutilization{$scope,$region,$availability-zone} by {name},10,'mean','desc')",
            "aggregator": "avg",
            "style": {
              "palette": "warm"
            },
            "type": "line",
            "conditional_formats": []
          }
        ]
      },
      "width": 42,
      "timeframe": "4h",
      "y": 0,
      "x": 82,
      "legend_size": "0",
      "type": "timeseries",
      "legend": false
    }
  ],
  "template_variables": [],
  "id": XXXXX1,
  "width": null
}

APIの直実行

同じJSON定義でAPIを直接実行してみましたが、同様の結果となりました。 API側の問題になりそうです。

$ curl -X POST -H "Content-type: application/json" \
> -d '@SampleScreenBoard.post.single.json' \
> "https://app.datadoghq.com/api/v1/screen?api_key=${api_key}&application_key=${app_key}"
{"board_id":XXXX6,"read_only":false,"title_size":13,"title":true,"id": XXXXX7,"title_align":"left","modified":"yyyy-mm-ddThh:mm:ss.495185+00:00","title_text":"CPU utilization by name (top 10)","height":21,"tile_def":{"viz":"timeseries","requests":[{"q":"top(avg:aws.ec2.cpuutilization{$scope,$region,$availability-zone} by {name},10,'mean','desc')","aggregator":"avg","style":{"palette":"warm"},"type":"line","conditional_formats":[]}]},"width":42,"created":"yyyy-mm-ddThh:mm:ss.495175+00:00","timeframe":"4h","y":0,"x":82,"legend_size":"0","type":"timeseries","legend":false}$

API Reference 上のサンプルをそのまま実行してみます。また違う結果になりましたが、やはり正常に動作していないように見えます。

> "https://app.datadoghq.com/api/v1/screen?api_key=${api_key}&application_key=${app_key}"
{"board_title":"dogapi test","read_only":false,"created":"yyyy-mm-ddThh:mm:ss.329178+00:00","modified":"yyyy-mm-ddThh:mm:ss.329191+00:00","height":768,"width":1024,"widgets":[{"url":"https://path/to/image.jpg","height":20,"width":32,"y":7,"x":32,"type":"image"}],"id": XXXXX9}$

f:id:htnosm:20170323212203p:plain

一部修正、template_variables、width、height オプション

オプション付与で実行してみた所、オプションは有効なようです。

$ dog screenboard post --template_variables "$(cat TEMPLATE_VARIABLES.json)" --width 1024 --height 768 "sb1" "ScreenBoard Test 1" "$(cat SampleScreenBoard.post.single.json)" | jq '.'
{
  "read_only": false,
  "description": "ScreenBoard Test 1",
  "title": "sb1",
  "created": "yyyy-mm-ddThh:mm:ss.222671+00:00",
  "modified": "yyyy-mm-ddThh:mm:ss.222682+00:00",
  "height": 768,
  "graphs": [
    {
      "board_id": XXXX6,
      "title_size": 13,
      "title": true,
      "title_align": "left",
      "title_text": "CPU utilization by name (top 10)",
      "height": 21,
      "tile_def": {
        "viz": "timeseries",
        "requests": [
          {
            "q": "top(avg:aws.ec2.cpuutilization{$scope,$region,$availability-zone} by {name},10,'mean','desc')",
            "aggregator": "avg",
            "style": {
              "palette": "warm"
            },
            "type": "line",
            "conditional_formats": []
          }
        ]
      },
      "width": 42,
      "timeframe": "4h",
      "y": 0,
      "x": 82,
      "legend_size": "0",
      "type": "timeseries",
      "legend": false
    }
  ],
  "template_variables": [
    {
      "default": "*",
      "prefix": "host",
      "name": "host"
    },
    {
      "default": "region:ap-northeast-1",
      "prefix": "region",
      "name": "region"
    }
  ],
  "id": XXXXX1,
  "width": 1024
}

f:id:htnosm:20170323212204p:plain

update

スクリーンボードを更新します。 post とほぼ同じ構文で、対象の screenboard_id を指定します。

usage: dog screenboard update [-h] [--template_variables TEMPLATE_VARIABLES]
                              [--width WIDTH] [--height HEIGHT]
                              screenboard_id title description [graphs]

意図した動作となりません
処理は正常終了しているように見えますが、指定値が反映されません。

pull

usage: dog screenboard pull [-h] screenboard_id filename

positional arguments:

引数 説明
screenboard_id スクリーンボードID
filename 出力ファイル名

実行例

JSON形式で出力されます。

$ board_id=169723
$ dog screenboard pull ${board_id} pull_${board_id}.json
XXXXX3 pull_XXXXX3.json
# 出力結果
$ cat pull_XXXXX3.json
{
  "board_title": "SampleScreenBoard",
  "read_only": false,
  "isIntegration": false,
  "board_bgtype": "board_graph",
  "created": "2017-03-23T16:57:56.454510+00:00",
  "original_title": "SampleScreenBoard",
  "modified": "2017-03-23T16:59:49.634253+00:00",
  "disableEditing": false,
  "height": 80,
  "width": "100%",
  "template_variables": [
    {
      "default": "*",
      "prefix": null,
      "name": "scope"
    },
・・・略
    }
  ],
  "templated": true,
  "widgets": [
    {
      "metric": "aws.ec2.host_ok",
      "text_align": "center",
      "query": "sum:aws.ec2.host_ok{$zone,$region,$account}",
      "text_size": "auto",
      "autoscale": true,
      "title": true,
      "aggregator": "max",
      "title_align": "left",
      "custom_unit": null,
      "width": 18,
      "timeframe": "1h",
      "wrapped": true,
      "legend_size": "0",
      "type": "query_value",
      "tags": [
        "$zone",
        "$region",
        "$account"
      ],
      "precision": 2,
      "title_text": "Active EC2 instances (max)",
      "padding": 8,
      "x": 20,
      "metric_type": "standard",
      "title_size": 13,
      "height": 8,
      "legend": false,
      "conditional_formats": [],
      "is_valid_query": true,
      "tile_def": {
        "text_align": "center",
        "autoscale": true,
        "custom_unit": null,
        "precision": 2,
        "viz": "query_value",
        "requests": [
          {
            "q": "sum:aws.ec2.host_ok{$scope,$region,$availability-zone}",
            "aggregator": "max",
            "conditional_formats": []
          }
        ]
      },
      "res_calc_func": "raw",
      "aggr": "sum",
      "y": 13,
      "calc_func": "raw"
    },
・・・略
    }
  ],
  "disableCog": false,
  "id": XXXXX3,
  "title_edited": false,
  "isShared": false
}$

push

JSON (pull した結果) を基に更新します。

positional arguments:

引数 説明
file 入力ファイル名。JSON

optional arguments:

ロングオプション 説明
–append_auto_text 対象タイムボードの description に日時とファイル名を追記します

append_auto_text はヘルプ上に記載はありますが、利用できません。 スクリーンボードはWebUI上 description が参照できないため、不要なオプションなのだと思います。

実行例

$ ls *${board_id}*
pull_XXXXX3.json  pull_XXXXX3.json.org
$ diff -w pull_XXXXX3.json.org pull_XXXXX3.json
22,26d21
<     },
<     {
<       "default": "*",
<       "prefix": "availability-zone",
<       "name": "availability-zone"
69c64
<             "q": "sum:aws.ec2.host_ok{$scope,$region,$availability-zone}",
---
>             "q": "sum:aws.ec2.host_ok{$scope,$region}",
104c99
<       "bgcolor": "gray",
---
>       "bgcolor": "blue",
134,135c129
<           "$region",
<           "$availability-zone"
---
>           "$region"
139c133
<             "q": "avg:aws.ec2.cpuutilization{$scope,$region,$availability-zone} by {host}",
---
>             "q": "avg:aws.ec2.cpuutilization{$scope,$region} by {host}",
166c160
<             "q": "top(avg:aws.ec2.cpuutilization{$scope,$region,$availability-zone} by {name},10,'mean','desc')",
---
>             "q": "top(avg:aws.ec2.cpuutilization{$scope,$region} by {name},10,'mean','desc')",
$ dog screenboard push pull_${board_id}.json | jq '.'
{
  "board_title": "SampleScreenBoard",
・・・略
  "id": XXXXX3,
  "title_edited": false,
  "isShared": false
}

f:id:htnosm:20170323212205p:plain

append_auto_text オプション

pull 結果に description が含まれていないため失敗します。

$ dog screenboard push --append_auto_text pull_${board_id}.json | jq '.'
Traceback (most recent call last):
  File "/usr/bin/dog", line 9, in <module>
    load_entry_point('datadog==0.15.0', 'console_scripts', 'dog')()
  File "/usr/lib/python2.7/site-packages/datadog/dogshell/__init__.py", line 69, in main
    args.func(args)
  File "/usr/lib/python2.7/site-packages/datadog/dogshell/screenboard.py", line 119, in _push
    screen_obj["description"] += auto_text
KeyError: 'description'
$ grep -c 'description'  pull_${board_id}.json
0

description を追記すれば動作します。また、 description を追加した状態で pull すると結果ファイルに description が含まれます。
ですが、WebUI上で作成した物には付与されないので使用しない方が良いかと思います。

$ diff pull_${board_id}.json pull_${board_id}_add_description.json
1a2
>   "description": "test",
$ dog screenboard push --append_auto_text pull_${board_id}_add_description.json | jq '.'
{
  "board_title": "SampleScreenBoard",
  "read_only": false,
  "isIntegration": false,
  "description": "test<br/>\nUpdated at mm/dd/yy hh:mm:dd from pull_XXXXX3_add_description.json (XXXXX3) on XXXXX.local",
・・・略
  "isShared": false
}
# 更新後にpull
$ dog screenboard pull ${board_id} pull_${board_id}_after.json
XXXXX3 pull_XXXXX3_after.json
$ grep -c description pull_XXXXX3.json pull_XXXXX3_after.json
pull_XXXXX3.json:0
pull_XXXXX3_after.json:1

new_file

新規でダッシュボードおよびpush用のファイルを作成します。

usage: dog screenboard new_file [-h] filename [graphs]

positional arguments:

引数 説明
filename 出力ファイル名。タイムボード名も兼ねる(説明にも記載される)。JSON
graphs グラフ定義JSON。標準入力から読み込ませる事も可能。

実行例

post して pull する動作となり、post と同じ問題が出てくるため省きます。

delete

スクリーンボードを削除します。

usage: dog screenboard delete [-h] screenboard_id

実行例

成功時のレスポンスはありません。

$ board_id=XXXXX1
$ dog screenboard delete ${board_id}
# 存在しない(削除済み) ID を指定
$ dog screenboard show ${board_id}
ERROR: Unable to find Screenboard for id XXXXX1

share | revoke

Public URL の払い出しと削除を行います。

# share
usage: dog screenboard share [-h] screenboard_id
# revoke
usage: dog screenboard revoke [-h] screenboard_id

実行例

share

PublicURL が払い出されます。再実行しても PublicURL の更新はされません。

$ board_id=XXXXX9
$ dog screenboard share ${board_id}
{"board_id": XXXXX9, "public_url": "https://p.datadoghq.com/sb/XXXXXXXXX-YYYYY5b001"}
$ dog screenboard share ${board_id}
{"board_id": XXXXX9, "public_url": "https://p.datadoghq.com/sb/XXXXXXXXX-YYYYY5b001"}

f:id:htnosm:20170323212206p:plain

ダッシュボードリスト(Dashboards) 上は share が表示されます。

f:id:htnosm:20170323212207p:plain

revoke

払い出し済みの PublicURL を削除します。
削除後に再度払い出し(share)を行うと別URLが払い出されます。

$ dog screenboard revoke ${board_id}
null
$ dog screenboard revoke ${board_id}
{"errors": ["Unable to find shared Screenboard for id XXXXX9"]}
# 再払い出し
$ dog screenboard share ${board_id}
{"board_id": XXXXX9, "public_url": "https://p.datadoghq.com/sb/XXXXXXXXX-YYYYY5c178"}
$

screenboard編まとめ

指定しているグラフの定義が悪いのか、想定した動作を確認できませんでした。
pull -> push の流れは利用できるので、現状はWebUIで作成したスクリーンボードを用意した後、定義のコード管理を行うことになりそうです。