Grafana ダッシュボードのクエリを抜き出すツールを生成 AI に作成してもらった

Grafana ダッシュボードでパネルに設定したクエリが多数に膨れた場合に、いちいちパネルを見るのが辛くなってきます。  
JSON を見るのも辛くて嫌になってしまいます。  
そこで、エクスポートした JSON からクエリを抜き出すツールについて検討してみました。  
また、生成 AI をうまいこと使えないか、の学習も並行で進めてみたく、本記事をつくりました。

## 背景

みなさまは生成 AI を自由に使えていますでしょうか？  
私は現場で不便を感じています。  
そのようなこともあり、そもそも使い方が下手なのを解消したいのと、フルに使えたとしてどうなるのかを実験してみました。  
ちなみに今は、検索代行程度での利用のみ。  
スマホで当たり障りのない汎用的な内容を生成 AI に聞いているような使い方をしています。

## 実験結果

- 生産効率  
  作業時間は 4 分の 1 以下に。使わない手はない。

- 使い方

  - フル利用できるに越したことはない  
    生成コードはそのまま流用できるものも多く、コピペできる環境があると理想。  
    ただ、プロンプトを書くことが下手なので、好みの回答にならない場合も多く苦慮。  
    そうした練習、工夫を繰り返さないと前進しないはずで、やはりフル利用できるに越したことがない。

  - フル利用できないとしても活用方法はある、が生産性は激減  
    スマホに入っていれば、部分的な作業効率は上がる。  
    探せる情報量が増えるので選択肢が広がり、部分的に注目しながら作業を進めるので情報蓄積にはこちらもアリ。  
    しかし、コピペできないと生産量には紐つけにくい。

- 現場状況とどう向き合うか  
  情報収集、情報活用の進み具合が段違いなので、利用有無の時間経過とともに蓄積スキル差が大きくなりそうです。  
  仮にスマホ利用すら制限されてしまうような現場の場合、成長の阻害要因にもなりかねません。  
  あまり条件が良くない場合には、そうした環境を避けてしまった方がよいこともあるのではないでしょうか。

## 実験内容

### プロンプト

今回は ChatGPT を使いました。お金は払っていませんが高機能でありがたいです。  
[前の記事](https://qiita.com/wf-kenji-ikeda/items/05970766dc96bc231b2c)でやりたいことを整理していたのでプロンプトは下記の通り。  
（前は git bash だけあれば動くパターンが欲しかったのでそちらで作成。今回は jq 利用版。）

```md
# 依頼

あなたは{# 役割}です。次の{# ルール}を守り、{# 前提}に沿った Shell Script のソースコードを出力してください。

# 役割

Shell Script の作成者。

# 前提

- 利用 OS は Windows。
- 利用ツールは git bash、jq。
- jq がローカルディレクトリに存在しないときには curl でダウンロードする。

# ルール

- Shell Script は{# 前提}の環境のみで実行します。他環境の考慮は不要。
- アップロードしたファイルを読み込み、rawSql を改行も反映されたファイルとして書き出す。
- パネルごとに複数の rawSql が発生する可能性もあり、パネルは今後追加される可能性がある。
- 書き出す rawSql はパネル名と一致するファイルに出力する。
```

### アウトプット

やりたいことそのままだと思います。  
一発でこれが出てくるのはとてもありがたいです。  
ただ、プロンプトを一発で書いたかというとそうでもなく、より良いものを書けるように練習が必要そうです。

```shell
#!/bin/bash

# Step 1: Check if jq exists, if not, download it
if ! command -v jq &> /dev/null; then
    echo "jq not found, downloading..."
    curl -L -o ./jq.exe "https://github.com/stedolan/jq/releases/download/jq-1.6/jq-win64.exe"
    chmod +x ./jq.exe
    JQ="./jq.exe"
else
    JQ="jq"
fi

# Step 2: Define input JSON file (adjust if necessary)
JSON_FILE="./MySQL 8_ Sakila Video Store Dummy Data-1729375414173.json"

# Step 3: Parse JSON and safely extract panel titles and rawSql
$JQ -c '.panels[] | {title: .title, rawSql: (.targets[]?.rawSql // null)}' "$JSON_FILE" | while read -r panel; do
    # Extract the title and rawSql from the JSON object
    PANEL_TITLE=$(echo "$panel" | $JQ -r '.title')
    RAW_SQL=$(echo "$panel" | $JQ -r '.rawSql')

    # Check if rawSql exists and is not empty, skip if absent
    if [ -z "$RAW_SQL" ] || [ "$RAW_SQL" == "null" ]; then
        echo "Skipping panel '$PANEL_TITLE' as it has no rawSql."
        continue
    fi

    # Create a valid filename from the panel title
    FILE_NAME=$(echo "$PANEL_TITLE" | sed 's/[^a-zA-Z0-9]/_/g').sql

    # Step 4: Write rawSql to the corresponding file
    echo "$RAW_SQL" > "$FILE_NAME"
    echo "Written rawSql to $FILE_NAME"
done
```

### 使い方はいろいろあるのかも？

会話形式で進めることで好みに近づく可能性もあるのかもしれません。  
今後もいろいろ試したいです。

#### 前の記事との関り

前の記事のソースコードは部分的に調べて自分で作成したソースコードとほとんど同じものです。  
[Grafana ダッシュボードのクエリを抜き出すツールの検討](https://qiita.com/wf-kenji-ikeda/items/05970766dc96bc231b2c)

自作成すると、「IFS」とか、「sed」とか、「echo -e "$xx"（改行ありの echo 出力）」とか調べて、まあまあ時間がかかりました。  
対して、適当にやりたいことを打ち込んでも、作業時間は 4 分の 1 程度になり、その際のアウトプットが[前の記事](https://qiita.com/wf-kenji-ikeda/items/05970766dc96bc231b2c)のソースコードです。  
以下のようなやり取りが発生し、傾向として「指示しきれていない性能的な面」や、「JSON 内の情報出力順」の把握はできていなかった模様でした。  
そうはいっても、短時間でゴールに近づける理想的なアプローチには違いないと感じました。

```txt
▼①
いまから渡すファイルにあるrawSqlを改行も反映されたファイルとして書き出すshell scriptを作成してください。
ただし、jqなどのツールは使用せず、git bash のみを利用する、ピュアなshell script で実現します。
パネルごとに複数のrawSqlが発生する可能性もあり、パネルは今後追加される可能性があります。

▼②
出力ファイル名はパネル名にしてください。

▼③
while に json_file を読み込むととても時間がかかります。
最初に関係する行のみgrep で一時ファイルに書き出し、そのファイルを処理対象として処理時間を短くしてください。

▼④
ファイル名やパネル名にスペースを含むので、うまくファイル名操作ができていません。

▼⑤
tmp には下記の様に抽出できています。しかし、.sqlファイルの名称が空です。

"rawSql": "SELECT\n  $__timeGroupAlias(payment_date,1h,NULL),\n  sum(amount) AS \"amount\"\nFROM payment\nWHERE\n  $__timeFilter(payment_date)\nGROUP BY 1\nORDER BY $__timeGroup(payment_date,1h,NULL)",
      "title": "Total Sales Per Hour",
  "title": "MySQL 8: Sakila Video Store Dummy Data",

▼⑥
まだ出力ファイル名が空です。rawSqlの処理結果をtmp.sqlなどで書き出してから、リネームしてください。
```