メインコンテンツへスキップ

SPL・トークン 公式コード完全解説 - 1行ずつコメント版

    # 📝 SPL・トークン 公式コード完全解説 - 1行ずつコメント版
    
    
    
    ---
    
    ## 💻 1. 基本パターン(公式推奨構造)
    
    ```xml
    <?xml version="1.0" encoding="UTF-8"?>    <!-- XML宣言 -->
                                              <!-- バージョン1.0、文字コードUTF-8 -->
                                              <!-- Splunkダッシュボードは全てXML形式 -->
    
    <form>                                    <!-- フォーム型ダッシュボードの開始タグ -->
                                              <!-- form = ユーザー入力を受け付ける -->
                                              <!-- (formの代わりにdashboardも可) -->
                                              <!-- 公式用語: Form Dashboard -->
    
      <label>基本的なダッシュボード</label>   <!-- ダッシュボードのタイトル -->
                                              <!-- Splunk画面の上部に表示される名前 -->
                                              <!-- 公式推奨: 分かりやすい日本語も可 -->
    
      <description>                           <!-- ダッシュボードの説明(オプション) -->
        このダッシュボードはログ分析用です     <!-- 説明文 -->
      </description>                          <!-- タイトルの下に小さく表示される -->
    
      <!-- ========================================== -->
      <!-- セクション1: 入力フォームエリア              -->
      <!-- 公式用語: Form Inputs / Input Controls     -->
      <!-- ========================================== -->
    
      <fieldset submitButton="false">         <!-- 入力フォームのグループ化 -->
                                              <!-- fieldset = 入力欄をまとめるコンテナ -->
                                              <!-- submitButton="false" = 送信ボタン非表示 -->
                                              <!-- ↑公式推奨: 即座に反映させる場合 */
                                              <!-- true にすると検索ボタンが表示される */
    
        <!-- ========================================== -->
        <!-- 入力1: ドロップダウンメニュー               -->
        <!-- 公式用語: Dropdown Input                   -->
        <!-- ========================================== -->
    
        <input type="dropdown"                <!-- 入力タイプの指定 -->
                                              <!-- type="dropdown" = プルダウンメニュー */
                                              <!-- 公式: 選択肢から1つ選ぶ形式 */
               
               token="field_tok">             <!-- ★トークン名を定義★ -->
                                              <!-- token= でトークン名を指定 */
                                              <!-- "field_tok" = この名前で値を保存 */
                                              <!-- 公式命名例: field_tok */
                                              <!-- (fieldとtokenを組み合わせた名前) */
    
          <label>フィールド選択</label>       <!-- 入力欄のラベル(表示名) -->
                                              <!-- ユーザーに見える文字 */
                                              <!-- 公式推奨: 分かりやすい日本語 */
    
          <!-- 選択肢を定義 -->
          <choice value="host">Host</choice>  <!-- 選択肢1 -->
                                              <!-- value="host" = 実際にトークンに入る値 */
                                              <!-- >Host< = 画面に表示される文字 */
                                              <!-- 選ぶと $field_tok$ = "host" になる */
    
          <choice value="source">Source</choice>     <!-- 選択肢2 -->
                                              <!-- value="source" = トークンの値 */
                                              <!-- >Source< = 表示文字 */
    
          <choice value="sourcetype">Sourcetype</choice>  <!-- 選択肢3 -->
                                              <!-- sourcetype = ログの種類 */
    
          <default>host</default>             <!-- デフォルト値(初期選択) -->
                                              <!-- default= 画面を開いた時点で選ばれている値 */
                                              <!-- 公式必須: これが無いと最初はエラー! */
                                              <!-- ページ読込時に $field_tok$ = "host" */
    
        </input>                              <!-- ドロップダウン入力の終了タグ -->
    
        <!-- ========================================== -->
        <!-- 入力2: 時間範囲選択ピッカー                 -->
        <!-- 公式用語: Time Range Picker                -->
        <!-- ========================================== -->
    
        <input type="time"                    <!-- 入力タイプ: 時間範囲 -->
                                              <!-- type="time" = 時間選択UI */
                                              <!-- カレンダーとプリセットが表示される */
               
               token="time">                  <!-- ★時間トークン名★ -->
                                              <!-- "time" という名前で時間を保存 */
                                              <!-- 公式: このトークンは特殊! */
                                              <!-- 2つのプロパティを持つ: */
                                              <!-- $time.earliest$ = 開始時刻 */
                                              <!-- $time.latest$ = 終了時刻 */
    
          <label>時間範囲</label>             <!-- ラベル表示 */
    
          <default>                           <!-- デフォルトの時間範囲 */
                                              <!-- 画面を開いた時の初期値 */
    
            <earliest>-24h@h</earliest>       <!-- 開始時刻の定義 */
                                              <!-- -24h = 24時間前 */
                                              <!-- @h = 時の単位に丸める */
                                              <!-- 例: 現在が13:45なら */
                                              <!-- → 前日の13:00になる */
                                              <!-- 公式構文: relative time modifier */
    
            <latest>now</latest>              <!-- 終了時刻の定義 */
                                              <!-- now = 現在時刻 */
                                              <!-- 公式: リアルタイムまで検索 */
    
          </default>                          <!-- デフォルト設定の終了タグ */
    
          <!-- オプション: プリセットを追加 -->
          <preset>                            <!-- よく使う時間範囲のプリセット1 */
            <label>過去1時間</label>           <!-- プリセット名 */
            <earliest>-1h</earliest>           <!-- 1時間前から */
            <latest>now</latest>               <!-- 今まで */
          </preset>
    
          <preset>                            <!-- プリセット2 */
            <label>今日</label>
            <earliest>@d</earliest>            <!-- @d = 今日の00:00:00 */
            <latest>now</latest>
          </preset>
    
          <preset>                            <!-- プリセット3 */
            <label>過去7日間</label>
            <earliest>-7d@d</earliest>         <!-- 7日前の00:00:00 */
            <latest>now</latest>
          </preset>
    
        </input>                              <!-- 時間入力の終了タグ -->
    
      </fieldset>                             <!-- 入力フォームグループの終了 -->
    
      <!-- ========================================== -->
      <!-- セクション2: 検索定義エリア                 -->
      <!-- 公式用語: Search Definition                -->
      <!-- ========================================== -->
    
      <search id="base_search">               <!-- ★検索の定義★ -->
                                              <!-- search = SPL検索を定義 */
                                              <!-- id="base_search" = この検索を識別する名前 */
                                              <!-- 公式用語: Base Search */
                                              <!-- 他のパネルから参照できる共通検索 */
    
        <query>                               <!-- SPLクエリを書く場所 -->
                                              <!-- query = 検索処理言語(SPL)のコード */
    
          index=_internal                     <!-- インデックスを指定 */
                                              <!-- index= データの保管場所 */
                                              <!-- _internal = Splunk内部ログ */
                                              <!-- 公式サンプルでよく使われる */
                                              <!-- 必ず最初に書く(パフォーマンス重要) */
    
          source=*splunkd.log                 <!-- ソース(ファイル)を指定 */
                                              <!-- source= ログファイルのパス */
                                              <!-- * = ワイルドカード(任意の文字列) */
                                              <!-- splunkd.log = Splunkデーモンのログ */
    
          earliest=$time.earliest$            <!-- ★時間トークンの開始時刻を使用★ -->
                                              <!-- $time.earliest$ = トークンの値を埋め込む */
                                              <!-- ユーザーが選択した開始時刻が入る */
                                              <!-- 公式構文: Token substitution */
    
          latest=$time.latest$                <!-- ★時間トークンの終了時刻を使用★ */
                                              <!-- $time.latest$ = 終了時刻 */
                                              <!-- ユーザーが選択した終了時刻が入る */
    
          | stats count by $field_tok$        <!-- ★パイプラインコマンド★ */
                                              <!-- | = パイプ(前の結果を次に渡す) */
                                              <!-- 公式用語: Pipeline */
                                              <!-- stats = 統計コマンド */
                                              <!-- count = 件数をカウント */
                                              <!-- by $field_tok$ = フィールド別に集計 */
                                              <!-- ↑ドロップダウンで選んだ値が入る */
                                              <!-- 例: hostを選んだら */
                                              <!-- → | stats count by host */
    
        </query>                              <!-- クエリの終了タグ */
    
        <earliest>$time.earliest$</earliest>  <!-- 時間範囲の明示的指定(オプション) -->
                                              <!-- query内でも指定しているが */
                                              <!-- ここでも指定できる(冗長だが明示的) */
    
        <latest>$time.latest$</latest>        <!-- 終了時刻の明示的指定 */
    
      </search>                               <!-- 検索定義の終了タグ */
    
      <!-- ========================================== -->
      <!-- セクション3: 表示エリア                     -->
      <!-- 公式用語: Visualization Panels             -->
      <!-- ========================================== -->
    
      <row>                                   <!-- 行(横並びのパネルグループ) -->
                                              <!-- row = 1つの横並び行 */
                                              <!-- 公式: ダッシュボードのレイアウト単位 */
                                              <!-- 複数のpanelを横に並べられる */
    
        <!-- ========================================== -->
        <!-- パネル1: テーブル表示                       -->
        <!-- 公式用語: Table Visualization              -->
        <!-- ========================================== -->
    
        <panel>                               <!-- パネル(表示領域)の開始 -->
                                              <!-- panel = 1つの表示エリア */
                                              <!-- 公式: ダッシュボードの基本単位 */
    
          <title>集計結果</title>              <!-- パネルのタイトル -->
                                              <!-- パネル上部に表示される見出し */
    
          <table>                             <!-- テーブル(表)形式で表示 -->
                                              <!-- table = 表形式のビジュアライゼーション */
                                              <!-- 公式: 詳細データの表示に適している */
    
            <search base="base_search">       <!-- ★ベースサーチを参照★ -->
                                              <!-- base="base_search" = 上で定義した検索を使用 */
                                              <!-- 公式用語: Post-process search */
                                              <!-- 元の検索結果をさらに加工できる */
                                              <!-- メリット: 検索は1回だけ実行(効率的) */
    
              <query>                         <!-- 追加の処理(オプション) -->
                | sort -count                 <!-- ソート処理 */
                                              <!-- sort = 並べ替えコマンド */
                                              <!-- - (マイナス) = 降順(大きい順) */
                                              <!-- count = カウント数でソート */
              </query>
    
            </search>                         <!-- 検索の終了 */
    
            <!-- テーブルのオプション設定 -->
            <option name="drilldown">cell</option>  <!-- ドリルダウン設定 -->
                                              <!-- drilldown = クリック時の動作 */
                                              <!-- cell = セルをクリック可能に */
                                              <!-- 公式用語: Drilldown action */
                                              <!-- 他の値: row(行), none(無効) */
    
            <option name="count">10</option>  <!-- 1ページあたりの表示行数 */
                                              <!-- 10行ごとにページング */
    
            <option name="wrap">true</option> <!-- テキストの折り返し */
                                              <!-- true = 長いテキストを折り返す */
    
          </table>                            <!-- テーブルの終了タグ */
    
        </panel>                              <!-- パネル1の終了タグ -->
    
        <!-- ========================================== -->
        <!-- パネル2: KPI(シングル値)表示               -->
        <!-- 公式用語: Single Value Visualization       -->
        <!-- ========================================== -->
    
        <panel>                               <!-- パネル2の開始 */
    
          <title>総件数</title>               <!-- パネルタイトル */
    
          <single>                            <!-- シングル値表示 -->
                                              <!-- single = 大きな数字1つを強調表示 */
                                              <!-- 公式用語: Single Value Viz */
                                              <!-- KPI(重要指標)の表示に最適 */
    
            <search base="base_search">       <!-- ★同じベースサーチを参照★ -->
                                              <!-- 同じ検索結果を再利用 */
                                              <!-- インデックスアクセスは1回だけ! */
    
              <query>                         <!-- 追加処理 */
                | stats sum(count) as total   <!-- 合計を計算 */
                                              <!-- sum() = 合計関数 */
                                              <!-- count = カウント数を合計 */
                                              <!-- as total = 結果を"total"と命名 */
              </query>
    
            </search>
    
            <!-- シングル値のオプション -->
            <option name="drilldown">none</option>  <!-- クリック無効 */
                                              <!-- KPIは通常クリックしない */
    
            <option name="numberPrecision">0</option>  <!-- 小数点以下の桁数 */
                                              <!-- 0 = 整数表示(小数なし) */
                                              <!-- 公式: numberPrecision option */
    
            <option name="unit">件</option>   <!-- 単位の表示 */
                                              <!-- 数字の後ろに"件"と表示 */
                                              <!-- 例: 1234件 */
    
            <option name="underLabel">総アクセス数</option>  <!-- 下のラベル */
                                              <!-- 数字の下に説明を表示 */
    
          </single>                           <!-- シングル値の終了タグ -->
    
        </panel>                              <!-- パネル2の終了タグ -->
    
      </row>                                  <!-- 行1の終了タグ -->
    
      <!-- ========================================== -->
      <!-- セクション4: グラフ表示エリア               -->
      <!-- ========================================== -->
    
      <row>                                   <!-- 行2の開始 -->
    
        <!-- ========================================== -->
        <!-- パネル3: 折れ線グラフ                      -->
        <!-- 公式用語: Line Chart                       -->
        <!-- ========================================== -->
    
        <panel>                               <!-- パネル3 -->
    
          <title>時系列推移</title>            <!-- タイトル -->
    
          <chart>                             <!-- チャート(グラフ)表示 -->
                                              <!-- chart = グラフ系ビジュアライゼーション */
                                              <!-- 公式用語: Chart Visualization */
    
            <search>                          <!-- 新しい検索(ベースサーチ使わない) -->
    
              <query>                         <!-- SPLクエリ -->
    
                index=_internal               <!-- インデックス指定 */
                source=*splunkd.log
                earliest=$time.earliest$      <!-- ★トークン使用★ */
                latest=$time.latest$
    
                | timechart span=1h count by $field_tok$  <!-- ★時系列グラフ用コマンド★ -->
                                              <!-- timechart = 時系列集計コマンド */
                                              <!-- 公式: グラフに最適なコマンド */
                                              <!-- span=1h = 1時間ごとに集計 */
                                              <!-- count = 件数をカウント */
                                              <!-- by $field_tok$ = フィールド別に分ける */
    
              </query>
    
            </search>
    
            <!-- チャートのオプション設定 -->
            <option name="charting.chart">line</option>  <!-- ★グラフの種類★ -->
                                              <!-- charting.chart = グラフタイプ */
                                              <!-- line = 折れ線グラフ */
                                              <!-- 公式: Chart Type Option */
                                              <!-- 他: column(棒), pie(円), area(面) */
    
            <option name="charting.axisTitleX.text">時刻</option>  <!-- X軸のタイトル */
                                              <!-- 横軸の説明文字 */
    
            <option name="charting.axisTitleY.text">件数</option>  <!-- Y軸のタイトル -->
                                              <!-- 縦軸の説明文字 */
    
            <option name="charting.legend.placement">bottom</option>  <!-- 凡例の位置 -->
                                              <!-- legend = 凡例(色の説明) */
                                              <!-- bottom = 下部に配置 */
                                              <!-- 他: top(上), left(左), right(右) */
    
            <option name="charting.chart.showDataLabels">none</option>  <!-- データラベル */
                                              <!-- showDataLabels = 値の表示 */
                                              <!-- none = 表示しない */
                                              <!-- all = すべての点に値を表示 */
    
          </chart>                            <!-- チャートの終了タグ */
    
        </panel>                              <!-- パネル3の終了タグ -->
    
      </row>                                  <!-- 行2の終了タグ -->
    
    </form>                                   <!-- フォーム型ダッシュボードの終了タグ -->
    
    
    <!-- ========================================== -->
    <!-- 公式ドキュメント参照先                      -->
    <!-- ========================================== -->
    <!--
    Token Usage:
    https://docs.splunk.com/Documentation/Splunk/latest/Viz/tokens
    
    Search Reference:
    https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/
    
    Chart Options:
    https://docs.splunk.com/Documentation/Splunk/latest/Viz/ChartConfigurationReference
    -->
    ```
    
    ---
    
    ## 💻 2. ドリルダウンパターン(完全コメント版)
    
    ```xml
    <form>
      <label>クリック連動ダッシュボード</label>
    
      <!-- ========================================== -->
      <!-- 時間範囲入力                                -->
      <!-- ========================================== -->
    
      <fieldset submitButton="false">         <!-- 入力フォーム -->
    
        <input type="time" token="time">      <!-- 時間選択 -->
          <label>期間</label>
          <default>
            <earliest>-24h</earliest>         <!-- 過去24時間 -->
            <latest>now</latest>              <!-- 現在まで -->
          </default>
        </input>
    
      </fieldset>
    
      <!-- ========================================== -->
      <!-- パネル1: クリック元(サマリー表示)           -->
      <!-- 公式用語: Source Panel                     -->
      <!-- ========================================== -->
    
      <row>                                   <!-- 行1 -->
        <panel>                               <!-- クリック元パネル -->
    
          <title>ホスト一覧(クリックで詳細表示)</title>  <!-- タイトル -->
                                              <!-- ユーザーへの指示を含める -->
    
          <table>                             <!-- テーブル表示 -->
    
            <search>                          <!-- 検索定義 -->
              <query>
    
                index=_internal               <!-- インデックス指定 -->
                source=*splunkd.log
                earliest=$time.earliest$      <!-- 時間トークン使用 */
                latest=$time.latest$
    
                | stats                       <!-- 統計コマンド */
                    count as アクセス数,       <!-- カウント数を集計 */
                                              <!-- as アクセス数 = 日本語の別名 */
                                              <!-- 公式: Field aliasing */
                    dc(component) as コンポーネント数  <!-- ユニーク数 */
                                              <!-- dc() = distinct count関数 */
                                              <!-- 重複を除いてカウント */
                    by host                   <!-- hostごとにグループ化 */
    
                | sort -アクセス数             <!-- 降順ソート */
    
              </query>
            </search>
    
            <!-- ========================================== -->
            <!-- ★ドリルダウン設定(クリック時の動作)★       -->
            <!-- 公式用語: Drilldown Configuration         -->
            <!-- ========================================== -->
    
            <drilldown>                       <!-- ドリルダウンブロック開始 -->
                                              <!-- drilldown = クリック時の処理 */
                                              <!-- 公式: Event handler */
    
              <!-- ========================================== -->
              <!-- トークン1: クリックした行の値を保存         -->
              <!-- ========================================== -->
    
              <set token="clicked_host">      <!-- ★トークンに値をセット★ */
                                              <!-- set token= トークンを作成/更新 */
                                              <!-- clicked_host = トークン名 */
                                              <!-- 公式用語: Set token action */
    
                $row.host$                    <!-- ★クリックした行のhost値★ */
                                              <!-- $row.フィールド名$ = 行の値を取得 */
                                              <!-- 公式構文: Row token reference */
                                              <!-- 例: hostが"server01"の行をクリック */
                                              <!-- → $clicked_host$ = "server01" */
    
              </set>                          <!-- setの終了タグ */
    
              <!-- ========================================== -->
              <!-- トークン2: アクセス数も保存                -->
              <!-- ========================================== -->
    
              <set token="clicked_count">     <!-- 2つ目のトークン */
    
                $row.アクセス数$               <!-- クリックした行のアクセス数 */
                                              <!-- 日本語フィールド名も使える! */
    
              </set>
    
              <!-- ========================================== -->
              <!-- トークン3: 表示制御フラグ                  -->
              <!-- ========================================== -->
    
              <set token="show_detail">       <!-- 表示フラグトークン -->
                                              <!-- このトークンの存在で表示/非表示を制御 */
                
                true                          <!-- 値は"true"(文字列) */
                                              <!-- 公式: Control token */
                                              <!-- 重要なのは「存在すること」 */
                                              <!-- 値の内容は実はあまり重要じゃない */
    
              </set>
    
            </drilldown>                      <!-- ドリルダウンの終了タグ */
    
            <!-- テーブルオプション -->
            <option name="drilldown">row</option>  <!-- 行全体をクリック可能に -->
                                              <!-- row = 行のどこでもクリックOK */
                                              <!-- cell = セルだけクリック可 */
    
          </table>
    
        </panel>                              <!-- クリック元パネルの終了 -->
      </row>
    
      <!-- ========================================== -->
      <!-- パネル2: クリック先(詳細表示) - 条件付き    -->
      <!-- 公式用語: Dependent Panel                  -->
      <!-- ========================================== -->
    
      <row>                                   <!-- 行2(条件付き表示) -->
    
        <panel depends="$show_detail$">       <!-- ★条件付きパネル★ -->
                                              <!-- depends= 依存条件 */
                                              <!-- $show_detail$ = トークンが存在する時だけ表示 */
                                              <!-- 公式用語: Conditional visibility */
                                              <!-- つまり: クリックするまで非表示! */
    
          <!-- タイトルにトークンを埋め込む -->
          <title>                             <!-- タイトル開始タグ -->
            ホスト詳細: $clicked_host$ (アクセス数: $clicked_count$件)
                                              <!-- ★タイトルにトークン埋め込み★ -->
                                              <!-- $clicked_host$ = クリックしたホスト名 */
                                              <!-- $clicked_count$ = クリックしたアクセス数 */
                                              <!-- 例: "ホスト詳細: server01 (アクセス数: 1234件)" */
          </title>
    
          <!-- ========================================== -->
          <!-- サブパネル1: 時系列グラフ                  -->
          <!-- ========================================== -->
    
          <chart>                             <!-- チャート表示 -->
    
            <title>時間別アクセス推移</title>   <!-- サブタイトル */
    
            <search>
              <query>
    
                index=_internal               <!-- インデックス -->
                source=*splunkd.log
                earliest=$time.earliest$      <!-- 時間トークン */
                latest=$time.latest$
    
                host="$clicked_host$"         <!-- ★クリックしたホストで絞り込み★ -->
                                              <!-- host= フィールド名 */
                                              <!-- "$clicked_host$" = トークンの値 */
                                              <!-- ダブルクォートで囲む = 完全一致 */
                                              <!-- 公式推奨: セキュリティのため引用符で囲む */
                                              <!-- 例: host="server01" */
    
                | timechart span=1h count     <!-- 1時間ごとの件数 -->
    
              </query>
            </search>
    
            <option name="charting.chart">area</option>  <!-- 面グラフ -->
                                              <!-- area = 面積を塗りつぶす折れ線 */
    
            <option name="charting.chart.stackMode">stacked</option>  <!-- 積み上げ -->
                                              <!-- stacked = 複数系列を積み上げ表示 */
    
          </chart>
    
          <!-- ========================================== -->
          <!-- サブパネル2: コンポーネント別円グラフ       -->
          <!-- ========================================== -->
    
          <chart>
    
            <title>コンポーネント別分布</title>
    
            <search>
              <query>
    
                index=_internal
                source=*splunkd.log
                earliest=$time.earliest$
                latest=$time.latest$
                host="$clicked_host$"         <!-- ★同じホストで絞り込み★ -->
    
                | stats count by component    <!-- コンポーネント別に集計 */
    
                | sort -count                 <!-- 降順ソート */
    
                | head 10                     <!-- 上位10件のみ */
                                              <!-- head = 先頭N件を取得 */
                                              <!-- 公式: Limit results */
    
              </query>
            </search>
    
            <option name="charting.chart">pie</option>  <!-- 円グラフ -->
    
            <option name="charting.chart.showPercent">true</option>  <!-- パーセント表示 */
                                              <!-- showPercent = 割合を表示 */
                                              <!-- true = 各セクションに%表示 */
    
          </chart>
    
          <!-- ========================================== -->
          <!-- サブパネル3: 詳細ログテーブル              -->
          <!-- ========================================== -->
    
          <table>
    
            <title>直近のログ(最新100件)</title>
    
            <search>
              <query>
    
                index=_internal
                source=*splunkd.log
                earliest=$time.earliest$
                latest=$time.latest$
                host="$clicked_host$"         <!-- ★同じホストで絞り込み★ -->
    
                | table                       <!-- テーブル表示用コマンド */
                                              <!-- table = 指定フィールドだけ表示 */
                                              <!-- 公式: Table command */
                    _time,                    <!-- タイムスタンプ */
                    component,                <!-- コンポーネント名 */
                    log_level,                <!-- ログレベル(INFO, WARN等) */
                    message                   <!-- ログメッセージ */
    
                | sort -_time                 <!-- 新しい順にソート */
                                              <!-- _time = タイムスタンプフィールド */
                                              <!-- - = 降順(新しい→古い) */
    
                | head 100                    <!-- 最新100件のみ */
    
              </query>
            </search>
    
            <option name="wrap">true</option>  <!-- テキスト折り返し -->
            <option name="rowNumbers">true</option>  <!-- 行番号表示 */
                                              <!-- rowNumbers = 左端に番号表示 */
    
          </table>
    
          <!-- ========================================== -->
          <!-- 閉じるボタン(HTMLとJavaScript)            -->
          <!-- 公式用語: Custom HTML with JavaScript     -->
          <!-- ========================================== -->
    
          <html>                              <!-- HTML埋め込み開始 -->
                                              <!-- html = 自由にHTMLを書ける */
                                              <!-- 公式: HTML Panel */
    
            <!-- ボタンのスタイル定義 -->
            <style>                           <!-- CSSスタイル定義 */
              .close-button {                 /* クラス名: close-button */
                background: linear-gradient(135deg, #f093fb  0%, #f5576c  100%);
                                              /* グラデーション背景 */
                                              /* 135度の角度 */
                                              /* ピンク→赤のグラデーション */
                color: white;                 /* 文字色: 白 */
                padding: 12px 24px;           /* 内側の余白 */
                                              /* 12px=上下, 24px=左右 */
                border: none;                 /* 枠線なし */
                border-radius: 8px;           /* 角を丸く(8px) */
                cursor: pointer;              /* マウスカーソルを指の形に */
                font-size: 16px;              /* 文字サイズ */
                font-weight: bold;            /* 太字 */
                box-shadow: 0 4px 8px rgba(0,0,0,0.2);  /* 影を付ける */
                                              /* 0=横ずれなし, 4px=下に4px */
                                              /* 8px=ぼかし, 透明度20%の黒 */
                transition: all 0.3s ease;    /* アニメーション */
                                              /* 0.3秒かけて滑らかに変化 */
              }
              .close-button:hover {           /* マウスを乗せた時 */
                transform: translateY(-2px);  /* 2px上に移動 */
                box-shadow: 0 6px 12px rgba(0,0,0,0.3);  /* 影を濃く */
              }
            </style>
    
            <!-- ボタン要素 -->
            <button id="close_detail_btn"     <!-- ボタンのHTML要素 -->
                                              <!-- id= JavaScriptから識別する名前 */
                    class="close-button">     <!-- class= 上のCSSを適用 */
              ✕ 詳細パネルを閉じる            <!-- ボタンの表示文字 -->
                                              <!-- ✕ = バツ印(Unicode文字) */
            </button>
    
            <!-- JavaScript -->
            <script>                          <!-- JavaScriptコード開始 -->
                                              <!-- script = プログラムを実行 */
    
              require([                       <!-- Splunk MVCフレームワークを読込 -->
                                              <!-- require = ライブラリ読込の仕組み */
                                              <!-- 公式: Splunk MVC Framework */
                
                "jquery",                     <!-- jQuery = JavaScript簡単化ライブラリ */
                                              <!-- DOM操作を簡単にする */
                
                "splunkjs/mvc"                <!-- Splunk MVC = トークン操作ライブラリ */
                                              <!-- トークンを操作するために必要 */
              
              ], function($, mvc) {           <!-- 読込完了後に実行する関数 */
                                              <!-- $ = jQueryオブジェクト */
                                              <!-- mvc = Splunk MVCオブジェクト */
    
                // トークンマネージャーを取得
                var tokens = mvc.Components.getInstance("submitted");
                                              /* tokens = トークン管理オブジェクト */
                                              /* getInstance = インスタンス取得 */
                                              /* "submitted" = 送信済みトークン */
                                              /* 公式: Token model */
    
                // ボタンクリック時の処理を設定
                $("#close_detail_btn").on("click", function() {
                                              /* $("#close_detail_btn") = ボタンを選択 */
                                              /* # = IDセレクタ */
                                              /* .on("click", ...) = クリック時の処理 */
                                              /* function() = 実行する関数 */
    
                  // ★トークンを削除★
                  tokens.unset("show_detail");     /* トークン削除 */
                                              /* unset() = トークンを消す */
                                              /* "show_detail" = フラグトークン */
                                              /* 公式: Unset token */
                                              /* これで depends条件が偽になる */
                                              /* → パネルが非表示になる! */
    
                  tokens.unset("clicked_host");    /* ホストトークンも削除 */
                  tokens.unset("clicked_count");   /* 件数トークンも削除 */
                                              /* 念のため全部クリア */
    
                });                           /* クリック処理の終了 */
    
              });                             /* require関数の終了 */
    
            </script>                         <!-- JavaScriptコード終了 */
    
          </html>                             <!-- HTML埋め込み終了 */
    
        </panel>                              <!-- 条件付きパネルの終了 */
    
      </row>                                  <!-- 行2の終了 */
    
    </form>                                   <!-- フォームの終了 -->
    
    
    <!-- ========================================== -->
    <!-- 動作の流れまとめ                            -->
    <!-- ========================================== -->
    <!--
    1. ユーザーがテーブルの行をクリック
       ↓
    2. drilldownが発火
       $clicked_host$ = "server01"
       $clicked_count$ = "1234"
       $show_detail$ = "true"
       ↓
    3. depends="$show_detail$"が真になる
       ↓
    4. 詳細パネルが出現
       ↓
    5. 3つの検索が実行される(host="server01"で絞り込み)
       - 時系列グラフ
       - 円グラフ
       - 詳細テーブル
       ↓
    6. ユーザーが「閉じる」ボタンをクリック
       ↓
    7. JavaScriptでtokens.unset()実行
       ↓
    8. $show_detail$が削除される
       ↓
    9. depends条件が偽になる
       ↓
    10. パネルが非表示になる
    -->
    ```
    
    ---
    
    ## 💻 3. 検索結果トークン(完全コメント版)
    
    ```xml
    <dashboard>
      <label>検索結果をトークンに保存</label>
    
      <!-- ========================================== -->
      <!-- 検索1: 総件数を計算してトークンに保存       -->
      <!-- 公式用語: Search with Token Setting        -->
      <!-- ========================================== -->
    
      <search id="count_search">              <!-- 検索にID付与 -->
                                              <!-- id="count_search" = 検索の識別名 */
    
        <query>                               <!-- SPLクエリ -->
    
          index=_internal                     <!-- インデックス指定 -->
          source=*splunkd.log
          earliest=-24h                       <!-- 過去24時間 -->
          latest=now                          <!-- 現在まで */
    
          | stats count                       <!-- 件数を集計 */
                                              <!-- 結果: 1行1列のテーブル */
                                              <!-- count = 12345 (例) */
    
        </query>
    
        <!-- ========================================== -->
        <!-- ★検索完了時の処理(<done>)★                -->
        <!-- 公式用語: Done Event Handler              -->
        <!-- ========================================== -->
    
        <done>                                <!-- 検索完了時に実行 -->
                                              <!-- done = 検索が終わったら */
                                              <!-- 公式: Event handler */
                                              <!-- エラー時は実行されない -->
    
          <!-- ========================================== -->
          <!-- トークン1: 検索結果の値を保存             -->
          <!-- ========================================== -->
    
          <set token="total_count">           <!-- トークンに値をセット -->
                                              <!-- total_count = トークン名 */
    
            $result.count$                    <!-- ★検索結果の値を取得★ -->
                                              <!-- $result.フィールド名$ */
                                              <!-- 公式構文: Result token reference */
                                              <!-- 検索結果の最初の行のcount値 */
                                              <!-- 例: 12345 */
    
          </set>
    
          <!-- ========================================== -->
          <!-- 条件付きトークン設定                       -->
          <!-- 公式用語: Conditional Token Setting       -->
          <!-- ========================================== -->
    
          <condition match="$result.count$ > 10000">  <!-- 条件1 -->
                                              <!-- condition = 条件分岐 */
                                              <!-- match= 条件式 */
                                              <!-- $result.count$ > 10000 = 1万件超 */
                                              <!-- 公式: Conditional logic */
    
            <set token="status_color">red</set>  <!-- 赤色を設定 */
                                              <!-- 件数が多い場合は赤 */
    
            <set token="status_text">警告: 件数が多すぎます</set>
                                              <!-- 警告メッセージ */
    
          </condition>
    
          <condition match="$result.count$ <= 10000">  <!-- 条件2 */
                                              <!-- 1万件以下の場合 */
    
            <set token="status_color">green</set>  <!-- 緑色を設定 */
                                              <!-- 件数が正常範囲なら緑 */
    
            <set token="status_text">正常</set>  <!-- 正常メッセージ */
    
          </condition>
    
        </done>                               <!-- done処理の終了 */
    
        <!-- ========================================== -->
        <!-- エラー時の処理(<error>) - オプション       -->
        <!-- ========================================== -->
    
        <error>                               <!-- 検索エラー時に実行 -->
                                              <!-- error = 検索が失敗したら */
    
          <set token="error_msg">             <!-- エラーメッセージ保存 -->
            検索でエラーが発生しました
          </set>
    
        </error>
    
      </search>                               <!-- 検索1の終了 -->
    
      <!-- ========================================== -->
      <!-- 検索2: 統計情報を計算してトークンに保存     -->
      <!-- ========================================== -->
    
      <search id="stats_search">              <!-- 検索2 -->
    
        <query>
    
          index=_internal
          source=*splunkd.log
          earliest=-24h
          latest=now
    
          | stats                             <!-- 複数の統計を計算 */
              count as total,                 /* 総件数 */
              count(eval(log_level="ERROR")) as error_count,  /* エラー件数 */
                                              /* eval() = 条件に合うものだけカウント */
                                              /* log_level="ERROR" = エラーレベル */
              dc(host) as unique_hosts        /* ユニークホスト数 */
                                              /* dc() = distinct count */
    
          | eval error_rate=round(error_count/total*100, 2)  /* エラー率計算 */
                                              /* round(値, 桁数) = 四捨五入 */
                                              /* *100 = パーセントに変換 */
                                              /* 2 = 小数点2桁 */
    
        </query>
    
        <done>                                <!-- 検索完了時 */
    
          <!-- ========================================== -->
          <!-- 複数のトークンに値を保存                   -->
          <!-- ========================================== -->
    
          <set token="error_count">           <!-- エラー件数トークン -->
            $result.error_count$              <!-- 検索結果から取得 */
          </set>
    
          <set token="error_rate">            <!-- エラー率トークン -->
            $result.error_rate$               <!-- 計算済みのエラー率 */
          </set>
    
          <set token="unique_hosts">          <!-- ユニークホスト数 -->
            $result.unique_hosts$
          </set>
    
        </done>
    
      </search>                               <!-- 検索2の終了 */
    
      <!-- ========================================== -->
      <!-- 表示エリア: 保存したトークンを使用          -->
      <!-- ========================================== -->
    
      <row>
    
        <!-- ========================================== -->
        <!-- HTMLパネルでKPI表示                        -->
        <!-- ========================================== -->
    
        <panel>
          <html>
            <style>
              .kpi-container {                /* KPIコンテナのスタイル */
                display: flex;                /* フレックスボックス */
                                              /* 横並びレイアウト */
                justify-content: space-around;  /* 均等配置 */
                flex-wrap: wrap;              /* 折り返し許可 */
              }
              .kpi-card {                     /* KPIカードのスタイル */
                background: linear-gradient(135deg, #667eea  0%, #764ba2  100%);
                                              /* グラデーション背景 */
                border-radius: 15px;          /* 角を丸く */
                padding: 30px;                /* 内側余白 */
                margin: 10px;                 /* 外側余白 */
                color: white;                 /* 文字色: 白 */
                text-align: center;           /* 中央揃え */
                min-width: 200px;             /* 最小幅 */
                box-shadow: 0 8px 16px rgba(0,0,0,0.2);  /* 影 */
              }
              .kpi-value {                    /* 数値のスタイル */
                font-size: 48px;              /* 大きなフォント */
                font-weight: bold;            /* 太字 */
                margin: 10px 0;               /* 上下余白 */
              }
              .kpi-label {                    /* ラベルのスタイル */
                font-size: 18px;              /* フォントサイズ */
                opacity: 0.9;                 /* 少し透明に */
              }
              .status-badge {                 /* ステータスバッジ */
                display: inline-block;        /* インライン表示 */
                padding: 5px 15px;            /* 余白 */
                border-radius: 20px;          /* 丸く */
                font-size: 14px;              /* 小さめ */
                margin-top: 10px;             /* 上余白 */
              }
            </style>
    
            <div class="kpi-container">       <!-- KPIコンテナ開始 -->
    
              <!-- KPI カード1: 総件数 -->
              <div class="kpi-card">
                <div class="kpi-label">総リクエスト数</div>
                <div class="kpi-value">$total_count$</div>  <!-- ★トークン表示1★ -->
                                              <!-- 検索1で保存した値 -->
                                              <!-- 例: 12,345 -->
                <div class="status-badge" style="background: $status_color$;">
                                              <!-- ★動的に色を変更★ -->
                                              <!-- $status_color$ = red or green -->
                  $status_text$               <!-- ★ステータステキスト★ -->
                                              <!-- 警告 or 正常 -->
                </div>
              </div>
    
              <!-- KPI カード2: エラー率 -->
              <div class="kpi-card">
                <div class="kpi-label">エラー率</div>
                <div class="kpi-value">$error_rate$%</div>  <!-- ★トークン表示2★ -->
                                              <!-- 検索2で計算した値 */
                                              <!-- 例: 3.45% -->
                <div class="kpi-label">($error_count$件)</div>  <!-- ★エラー件数★ -->
                                              <!-- 例: (423件) -->
              </div>
    
              <!-- KPI カード3: ユニークホスト数 -->
              <div class="kpi-card">
                <div class="kpi-label">アクティブホスト数</div>
                <div class="kpi-value">$unique_hosts$</div>  <!-- ★トークン表示3★ */
                                              <!-- 例: 15 -->
                <div class="kpi-label">台</div>
              </div>
    
            </div>                            <!-- KPIコンテナ終了 -->
    
          </html>
        </panel>
    
      </row>
    
    </dashboard>
    
    
    <!-- ========================================== -->
    <!-- データの流れまとめ                          -->
    <!-- ========================================== -->
    <!--
    【検索1のフロー】
    1. index=_internal ... | stats count 実行
       ↓
    2. 検索完了(<done>)
       ↓
    3. 結果: count=12345
       ↓
    4. $result.count$ = 12345 を取得
       ↓
    5. $total_count$ = 12345 に保存
       ↓
    6. 条件判定: 12345 > 10000 ?
       ↓
    7. YES → $status_color$="red", $status_text$="警告"
       ↓
    8. HTMLパネルでトークンを表示
    
    【検索2のフロー】
    1. 統計計算実行
       ↓
    2. 検索完了
       ↓
    3. 結果: error_count=423, error_rate=3.45, unique_hosts=15
       ↓
    4. 各トークンに保存
       ↓
    5. HTMLパネルでトークンを表示
    -->
    ```
    
    ---
    
    
    **重要ポイント:**
    1. **$トークン名$** - この形式で値を埋め込む
    2. **<done>** - 検索完了時に実行
    3. **depends="$token$"** - トークン存在で表示制御
    4. **drilldown** - クリック時の動作
    
    **次のステップ:**
    1. このコードをコピーして実行してみる
    2. トークン名を変えて実験
    3. 自分のインデックスで試す
    
    

    あなたへのおすすめ