oodle-dashboards について
oodle-dashboardsは、Oodle CLIでダッシュボードとフォルダーを管理するエージェント向けスキルです。編集前に定義全体を取得してパネル設定を保ち、保存先フォルダーを明示する手順を扱います。
主な機能
- 01ダッシュボードの一覧・取得・作成・削除
- 02フォルダーの作成とダッシュボードの整理
- 03更新前の全定義取得によるパネル保持
- 04共有ダッシュボードの段階的な削除
- 05PromQLの時間窓と統計パネルの指針
活用シーン
- 01フォルダー別にチームのダッシュボードを整理
- 02パネルを失わずにタイトルを変更
- 03指定フォルダーにダッシュボードを作成
- 04不要なデータ読み込みを避けるクエリ調整
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oodle-ai/ agent-skills --skill oodle-dashboardsインストール後、Claude Code で/oodle-dashboardsを入力して読み込まれたか確認します。
詳細
Oodle ダッシュボード — CRUD と整理
このスキルでは、パネルの状態を失ったり、ルートフォルダーにダッシュボードを孤立させたりせずに、エージェントが Oodle のダッシュボードとフォルダーを管理する方法を説明します。
前提条件
brew install oodle-ai/oodle/oodle
oodle configure
# or
export OODLE_API_KEY=<key>
export OODLE_INSTANCE=<instance>
export OODLE_DEPLOYMENT=<url>
ダッシュボードのエンドポイントが動作することを確認します。
oodle dashboards list -o json | jq 'length'
oodle folders list -o json | jq 'length'
コマンドの実行順序
oodle コマンドを実行する前に、次の手順を行います。
- 必要なリソース ID または名前がすでにコンテキストにあるか確認します。
- ない場合は、検出コマンド(例:
oodle dashboards list -o json)を実行します。 - 結果が曖昧な場合は、実行する前にユーザーに確認を求めます。
- 解決した ID を使って対象のコマンドを実行します。
- 推測に基づくコマンドは実行しないでください(例:リソースを先に
getせずにdeleteしないでください)。
クイックリファレンス
| タスク | コマンド |
|---|---|
| ダッシュボードを一覧表示 | oodle dashboards list -o json |
| ダッシュボードを取得 | oodle dashboards get <uid> -o json |
| ダッシュボードを作成 | oodle dashboards create -f save.json |
| ダッシュボードを更新 | "overwrite": true を指定して oodle dashboards create -f save.json を実行(dashboards update はありません) |
| ダッシュボードを削除 | oodle dashboards delete <uid> --force |
| フォルダーを一覧表示 | oodle folders list -o json |
| フォルダーを作成 | oodle folders create --title "Platform" -o json |
| フォルダーを削除 | CLI コマンドはありません。Oodle UI を使用してください |
よくある操作
ダッシュボードの一覧表示
# ✅ CORRECT
oodle dashboards list -o json
# ✅ CORRECT — filter by folder (the list also has folders, with `type` "dash-folder")
oodle dashboards list -o json | jq '.[] | select(.type=="dash-db" and .folderUid=="platform")'
# ❌ WRONG — parsing table output to find an ID
oodle dashboards list | grep "API Overview" | awk '{print $1}'
変更前にダッシュボードを読み込む
# ✅ CORRECT — fetch the full definition first; preserves all panels and queries
oodle dashboards get dash_123 -o json > current.json
jq '{dashboard: .dashboard, folderUid: .meta.folderUid, overwrite: true}' current.json > save.json
$EDITOR save.json
oodle dashboards create -f save.json
# ❌ WRONG — sending an incomplete payload removes panels
oodle dashboards create -f <(echo '{"dashboard":{"uid":"dash_123","title":"new title"},"overwrite":true}')
ダッシュボードの作成
oodle dashboards create -f は保存リクエストを受け取ります。dashboard には Grafana ダッシュボード JSON を、folderUid と overwrite も指定します。パネルの PromQL は targets[].expr に保持されます。完全な保存リクエストでは、ダッシュボードを既知のフォルダーに配置します。
{
"dashboard": {
"title": "API Overview",
"description": "Latency, error rate, and throughput for the API service.",
"tags": ["service:api", "team:platform"],
"panels": [
{
"title": "Request rate",
"type": "timeseries",
"targets": [{"refId": "A", "expr": "sum(rate(http_requests_total{service=\"api\"}[$__rate_interval]))"}]
},
{
"title": "Error rate",
"type": "timeseries",
"targets": [{"refId": "A", "expr": "sum(rate(http_requests_total{service=\"api\",status=~\"5..\"}[$__rate_interval]))"}]
},
{
"title": "P99 latency",
"type": "timeseries",
"targets": [{"refId": "A", "expr": "histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket{service=\"api\"}[$__rate_interval])))"}]
}
]
},
"folderUid": "platform",
"overwrite": false
}
# ✅ CORRECT
oodle dashboards create -f save.json
# ❌ WRONG — no folderUid, dashboard ends up in root and is hard to find
oodle dashboards create -f <(echo '{"dashboard":{"title":"API Overview","panels":[...]}}')
フォルダーの管理
# ✅ CORRECT — create folder first, capture id, then create dashboards in it
FOLDER_UID=$(oodle folders create --title "Platform" -o json | jq -r '.uid')
jq --arg f "$FOLDER_UID" '.folderUid=$f' save.json > save.with-folder.json
oodle dashboards create -f save.with-folder.json
# ❌ WRONG — creating dashboards before folders, then trying to move them later
oodle dashboards create -f save.json
oodle folders create --title "Platform"
安全な削除 — 2 段階
ダッシュボードは、運用手順書、Slack メッセージ、ブックマークからリンクされています。削除は 2 段階で行います。
# ✅ CORRECT — phase 1: rename so users see it's about to be removed
oodle dashboards get dash_123 -o json > dash.json
jq '{dashboard: (.dashboard | .title = "[MARKED FOR DELETION] " + .title), folderUid: .meta.folderUid, overwrite: true}' dash.json > dash.deletion.json
oodle dashboards create -f dash.deletion.json
# wait at least 7 days, then:
oodle dashboards delete dash_123 --force
# ❌ WRONG — immediate hard delete, breaks every existing link
oodle dashboards delete dash_123 --force
ベストプラクティス
パネルのルックバック期間に $__range を使用しない
$__range はダッシュボードの時間範囲全体に展開されるため、どのステップでもウィンドウ幅は変わりません。その結果、各ステップで直前のステップとほぼ同じデータを再読み込みします。6h のダッシュボードでは、[$__range] ウィンドウを使うと、同じパネルで [$__dd_interval] を使う場合と比べて約 180 倍のサンプルを読み込みます。また、ユーザーがズームアウトするほどその倍率は大きくなり、ダッシュボードがタイムアウトする原因になります。Oodle は、そのようなパネルに警告の三角形を表示します。
代わりに、時間範囲に応じて変わるウィンドウを使用します。
| 変数 | 内容 | 用途 |
|---|---|---|
$__rate_interval | Grafana 組み込みのレートウィンドウです。max(step + scrape interval, 4 x scrape interval) と等しく、レートを定義するのに十分なサンプル数を常に確保します。 | グラフでの rate() と increase() |
$__dd_interval | 時間範囲に応じて Oodle が選ぶロールアップウィンドウで、Datadog のデフォルトに一致します。上限は 4h です。 | デフォルトのロールアップと、統計パネルの合計値 |
$__large_interval | 同じ時間範囲における、$__dd_interval より粗いロールアップです。上限は 12h です。 | 棒グラフと長いルックバック |
2 つの Oodle ロールアップは、次のように解決されます。
| ダッシュボードの範囲 | $__dd_interval | $__large_interval |
|---|---|---|
| 1 hour | 20s | 1m |
| 6 hours | 2m | 5m |
| 24 hours | 5m | 20m |
| 7 days | 1h | 4h |
| 30 days | 4h | 12h |
3 つの変数はいずれもダッシュボードの時間範囲に応じて拡大・縮小するため、ユーザーがどれだけズームアウトしても、ステップごとに読み込むサンプル数はほぼ一定に保たれます。
# ✅ CORRECT — the window shrinks and grows with the dashboard range
"expr": "sum(rate(http_requests_total[$__rate_interval]))"
# ✅ CORRECT — coarser rollup for a bar chart
"expr": "topk(10, sum by (route) (rate(http_request_duration_seconds_sum[$__large_interval])))"
# ❌ WRONG — one flat line at the range average, read 180 times over
"expr": "sum(rate(http_requests_total[$__range]))"
# ❌ WRONG — `$__range_s` is there to undo an `increase`; use `rate` instead
"expr": "sum(increase(http_requests_total[$__range])) / $__range_s"
$__range ではなくウィンドウを合計する統計パネル
範囲全体の数値を1つ表示する統計パネルでは、すべてのサンプルが必要ですが、一度に読み取る必要はありません。範囲をウィンドウに分割し、それぞれのウィンドウの値を合計してください。
# ✅ CORRECT — window == min step, range query, reduced back to one number
"expr": "sum(increase(http_requests_total[$__dd_interval]))"
"interval": "$__dd_interval"
"instant": false
"transformations": [{"id": "reduce", "options": {"reducers": ["sum"]}}]
# ❌ WRONG — instant query that reads the whole range on every refresh
"expr": "sum(increase(http_requests_total[$__range]))"
"instant": true
ウィンドウが範囲を隙間なく埋めるよう、最小ステップをウィンドウと同じ値にしてください。ステップが小さいとサンプルが二重にカウントされ、大きいとサンプルが抜け落ちます。関数に合わせてリデューサーを選んでください。increase には sum、sum_over_time と count_over_time には sum、max_over_time には max、min_over_time には min、avg_over_time には mean を使います。quantile_over_time、changes、resets にはこの方法で分割しないでください。削減後の値は範囲全体に対する値ではありません。
パネル設定を保持するため、必ず update の前に get を実行する
"overwrite": true を指定して保存すると、ドキュメント全体が置き換えられます。ペイロードに含まれていないパネルは削除されます。
# ✅ CORRECT
oodle dashboards get dash_123 -o json > dash.json
jq '{dashboard: (.dashboard | .panels[0].title = "Request rate (per second)"), folderUid: .meta.folderUid, overwrite: true}' dash.json > dash.new.json
oodle dashboards create -f dash.new.json
# ❌ WRONG — sends a single-field payload; all panels disappear
oodle dashboards create -f <(echo '{"dashboard":{"uid":"dash_123","description":"updated"},"overwrite":true}')
ダッシュボードを作成するときは必ず folderUid を設定する
ルートフォルダー内のダッシュボードは、チームが見つけにくくなります。
# ✅ CORRECT
"folderUid": "platform"
# ❌ WRONG — omitting folderUid means root
"folderUid": null
共有ダッシュボードでは、名前変更 → 待機 → 削除の2段階の手順を使う
ダッシュボードを完全に削除すると、外部リンク(運用手順書、Slack のリアクション、ブックマーク)がすべて使えなくなります。
# ✅ CORRECT — phase 1: rename
oodle dashboards create -f dash.deletion.json
# wait, confirm no traffic, then phase 2: delete
oodle dashboards delete dash_123 --force
# ❌ WRONG — same-day delete on a shared dashboard
oodle dashboards delete dash_123 --force
ダッシュボードに service と team のラベルを付ける
タグを付けるとダッシュボードを検索できるようになり、他のツール(サービスカタログなど)からリンクできるようになります。
# ✅ CORRECT
"tags": ["service:api", "team:platform", "env:prod"]
# ❌ WRONG
"tags": []
エラーへの対処
| エラー | 原因 | 修正方法 |
|---|---|---|
| 401 Unauthorized | API キーが無効、または設定されていません | oodle configure を実行するか、OODLE_API_KEY を設定してください |
| 404 Not Found | ダッシュボードまたはフォルダーの ID が存在しません | oodle dashboards list -o json で確認してください |
| connection refused | OODLE_DEPLOYMENT の URL が間違っています | OODLE_DEPLOYMENT 環境変数を確認してください |
folder not found | folderUid が削除済みのフォルダーを参照しています | oodle folders list -o json でフォルダーを一覧表示し、既存の ID を選ぶか、新しいフォルダーを作成してください |
| 更新後にパネルが消えた | "overwrite": true を指定した保存で、ペイロードが不完全でした | 直近の get スナップショットから再作成してください。今後は必ず get → 編集 → 保存の順に実行してください |
| フォルダーを削除できない | フォルダーにダッシュボードが残っています。また、CLI に folders delete がありません | 先にダッシュボードを移動または削除してください(`oodle dashboards list -o json |
| 429 Too Many Requests | ダッシュボードの一括同期 | --retries 3 を追加し、作成頻度を1秒あたり10件未満に抑えてください |