ダッシュボードのエクスポート機能について
少し前にダッシュボードのエクスポート機能が強化され、ダッシュボードでフィルタを適用した状態の内容をPDF/PNGで落としたり、APIで取得することが可能になりました
手動で落とす場合は、ダッシュボード開いて、画面右上の3点リーダー -> Download dashboardから可能です
APIでの定期取得について
今回定期的に取得したい要件があったので、APIを定期的に叩くシェルスクリプトを組みました
同様のことをやりたい人の参考になれば幸いです
リファレンス
作成したシェルスクリプトの仕様
指定した New Relic ダッシュボードに対して https://api.newrelic.com/graphql を叩き、GraphQL API 経由で PDF スナップショット URL を作成します。その URL から PDF をダウンロードし、ローカルのフォルダに保存します。
- 引数でtime_rangeを指定可 (時数で指定)
- レポート
- PDF形式
- ファイル名に実行日時、time_rangeを付与
筆者実行環境
- Windows + WSL
- cronで1h, 3h, 6h, 24hおきに実行 (レポートのtime_rangeも1h, 3h, 6h, 24hの内容)
- レポートは WSL から参照できる保存先に出力
前提
1.. NewRelicでUser Keyを取得
2.. NEW_RELIC_USER_KEY環境変数でUser Keyをセットする
(シェルスクリプトに直書きを避けるため環境変数を利用する)
手動実行の場合
シェルで以下を実行
export NEW_RELIC_USER_KEY=NRAK-xxxx
cron実行の場合 (例)
$HOME/.newrelic-dashboard.env を作成し環境変数をセット
vi $HOME/.newrelic-dashboard.env
※以下を記載
export NEW_RELIC_USER_KEY=NRAK-xxxx
chmod 600 $HOME/.newrelic-dashboard.env
※cronから実行するシェルスクリプトの冒頭でsource $HOME/.newrelic-dashboard.env を実行する
3.. ダッシュボードのGUIDを取得
ダッシュボードを開くとURLが以下形式になっているので、/detail/ ~ ?account= の間の文字列をコピーする
https://one.newrelic.com/dashboards/detail/<ダッシュボードGUID>?account=xxxx&state=xxxx
シェルスクリプト
export-newrelic-dashboard-pdf.sh を以下内容で作成
以下部分を修正する (xxxx部分)
- DASHBOARD_GUID ※NewRelicのダッシュボードのGUID
- DEFAULT_OUT ※PDF出力先ディレクトリ
vi export-newrelic-dashboard-pdf.sh
chmod 700 export-newrelic-dashboard-pdf.sh
#!/usr/bin/env bash
set -euo pipefail
ENV_FILE="${NEW_RELIC_DASHBOARD_ENV_FILE:-$HOME/.newrelic-dashboard.env}"
if [[ -f "$ENV_FILE" ]]; then
# Load credentials/config for cron, which does not inherit the interactive shell environment.
source "$ENV_FILE"
fi
DASHBOARD_GUID="${DASHBOARD_GUID:-xxxx}"
NEW_RELIC_GRAPHQL_ENDPOINT="${NEW_RELIC_GRAPHQL_ENDPOINT:-https://api.newrelic.com/graphql}"
DURATION_HOURS="${1:-}"
DEFAULT_OUT="/xxxx/newrelic-dashboard-$(date +%Y%m%d-%H%M%S)${DURATION_HOURS:+-$DURATION_HOURS}.pdf"
OUT="${2:-$DEFAULT_OUT}"
mkdir -p "$(dirname -- "$OUT")"
SNAPSHOT_DURATION_MS="${SNAPSHOT_DURATION_MS:-}"
if [[ -n "$DURATION_HOURS" ]]; then
if [[ ! "$DURATION_HOURS" =~ ^[1-9][0-9]*$ ]]; then
echo "ERROR: Duration hours must be a positive integer." >&2
echo "Usage: $0 [duration_hours] [output_pdf_path]" >&2
echo "Example: $0 1" >&2
exit 8
fi
SNAPSHOT_DURATION_MS=$((DURATION_HOURS * 60 * 60 * 1000))
fi
if [[ -z "${NEW_RELIC_USER_KEY:-}" ]]; then
echo "ERROR: NEW_RELIC_USER_KEY is not set." >&2
echo "Run: export NEW_RELIC_USER_KEY='NRAK-...'" >&2
exit 2
fi
if ! command -v jq >/dev/null 2>&1; then
echo "ERROR: jq is required. Install jq and retry." >&2
exit 3
fi
page_query=$(jq -n --arg dashboardGuid "$DASHBOARD_GUID" '{
query: ("{ actor { entitySearch(query: \"parentId = '\''" + $dashboardGuid + "'\'' AND tags.isDashboardPage = '\''true'\''\") { results { entities { guid name } } } } }")
}')
page_response=$(curl -sS "$NEW_RELIC_GRAPHQL_ENDPOINT" \
-H "API-Key: $NEW_RELIC_USER_KEY" \
-H "Content-Type: application/json" \
--data-raw "$page_query")
if echo "$page_response" | jq -e '.errors' >/dev/null; then
echo "ERROR: Failed to retrieve dashboard page GUID:" >&2
echo "$page_response" | jq '.errors' >&2
exit 4
fi
page_guid=$(echo "$page_response" | jq -r '.data.actor.entitySearch.results.entities[0].guid // empty')
page_name=$(echo "$page_response" | jq -r '.data.actor.entitySearch.results.entities[0].name // empty')
if [[ -z "$page_guid" ]]; then
echo "ERROR: No dashboard page GUID found. Response:" >&2
echo "$page_response" | jq >&2
exit 5
fi
echo "Using dashboard page: ${page_name:-unknown}"
if [[ -n "$SNAPSHOT_DURATION_MS" ]]; then
snapshot_query=$(jq -n --arg pageGuid "$page_guid" --arg durationMs "$SNAPSHOT_DURATION_MS" '{
query: ("mutation { dashboardCreateSnapshotUrl(guid: \"" + $pageGuid + "\", params: { format: PDF, timeWindow: { duration: " + $durationMs + " } }) }")
}')
else
snapshot_query=$(jq -n --arg pageGuid "$page_guid" '{
query: ("mutation { dashboardCreateSnapshotUrl(guid: \"" + $pageGuid + "\", params: { format: PDF }) }")
}')
fi
snapshot_response=$(curl -sS "$NEW_RELIC_GRAPHQL_ENDPOINT" \
-H "API-Key: $NEW_RELIC_USER_KEY" \
-H "Content-Type: application/json" \
--data-raw "$snapshot_query")
if echo "$snapshot_response" | jq -e '.errors' >/dev/null; then
echo "ERROR: Failed to create snapshot URL:" >&2
echo "$snapshot_response" | jq '.errors' >&2
exit 6
fi
snapshot_url=$(echo "$snapshot_response" | jq -r '.data.dashboardCreateSnapshotUrl // empty')
if [[ -z "$snapshot_url" || "$snapshot_url" == "null" ]]; then
echo "ERROR: Snapshot URL was empty. Response:" >&2
echo "$snapshot_response" | jq >&2
exit 7
fi
curl -fL --retry 3 --retry-delay 2 "$snapshot_url" -o "$OUT"
file "$OUT"
ls -lh "$OUT"
echo "Saved: $OUT"
cronの設定
mkdir -p $HOME/.local/state/newrelic-dashboard-pdf
crontab -e
# BEGIN newrelic-dashboard-pdf
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 * * * * /xxxx/export-newrelic-dashboard-pdf.sh 1 >> $HOME/.local/state/newrelic-dashboard-pdf/cron.log 2>&1
0 */3 * * * /xxxx/export-newrelic-dashboard-pdf.sh 3 >> $HOME/.local/state/newrelic-dashboard-pdf/cron.log 2>&1
0 */6 * * * /xxxx/export-newrelic-dashboard-pdf.sh 6 >> $HOME/.local/state/newrelic-dashboard-pdf/cron.log 2>&1
0 0 * * * /xxxx/export-newrelic-dashboard-pdf.sh 24 >> $HOME/.local/state/newrelic-dashboard-pdf/cron.log 2>&1
# END newrelic-dashboard-pdf
実行方法
凡例
/xxxx/export-newrelic-dashboard-pdf.sh ${time_range}
実行例 (直近24時間の内容を出力)
/xxxx/export-newrelic-dashboard-pdf.sh 24
出力レポートの例
ファイル名凡例
newrelic-dashboard-$(yyyymmdd)-$(hhmmss)-$(time_range).pdf
実際の例
"/xxxx/newrelic-dashboard-20260902-080532-24.pdf"
利用効果
GUI操作が減って楽になりました!
各クラウドにもこの機能欲しい
追記
Google Apps ScriptでGoogle Driveに定期出力を実装しました



