正確な原理原則を図解しますね!完璧です!公式ドキュメントを入手しました。図解と公式情報を組み合わせて完全解説しますね!
---
```
┌─────────────────────────────────────────────┐
│ 📖 Splunk 公式ドキュメント │
└─────────────────────────────────────────────┘
【トークン関連】
🔹 Token Usage in Dashboards
https:
🔹 Token Filters (高度な構文)
https:
🔹 Dashboard Examples App (サンプル集)
https:
【SPL関連】
🔹 Search Reference (コマンド一覧)
https:
🔹 SPL Quick Reference Guide
https:
🔹 Commands by Category
https:
```
---
```
┌─────────────────────────────────────────────────────┐
│ 📘 Splunk公式ドキュメントより引用 │
└─────────────────────────────────────────────────────┘
"Tokens are like programming variables.
A token name represents a value that can change,
such as a user selection in a form input."
【日本語訳】
トークンはプログラミング変数のようなもの。
トークン名は変更可能な値を表し、
例えばフォーム入力でのユーザー選択などに使われる。
【公式の構文】
$token_name$ ← 基本構文(デリミタは$)
$token_name.property$ ← プロパティアクセス
$token_name|filter$ ← フィルター適用
```
---
```
┌─────────────────────────────────────────────────────┐
│ 📘 Splunk公式ドキュメントより引用 │
└─────────────────────────────────────────────────────┘
"The Splunk Search Processing Language (SPL)
encompasses all the search commands and their
functions, arguments and clauses."
【日本語訳】
Splunk検索処理言語(SPL)は、
すべての検索コマンドとその関数、引数、句を包含する。
【SPLの構成要素】(公式定義)
┌─────────────────────┐
│ 1. Search Terms │ 検索語(キーワード)
│ 2. Commands │ コマンド(アクション)
│ 3. Functions │ 関数(計算処理)
│ 4. Arguments │ 引数(関数への入力)
│ 5. Clauses │ 句(グループ化・命名)
└─────────────────────┘
【公式】SPLコマンド数
140+ commands available
(140以上のコマンドが利用可能)
```
---
```
┌─────────────────────────────────────────────────────────────┐
│ 📊 SPL Commands - 公式6分類(カラフル図解) │
└─────────────────────────────────────────────────────────────┘
🟦 【1】Distributable Streaming Commands
┌──────────────────────────────────┐
│ インデクサー/サーチヘッドで並列実行 │
│ ⚡ 最速! │
└──────────────────────────────────┘
代表コマンド:
• eval - フィールド計算
• fields - フィールド選択
• regex - 正規表現フィルタ
• rename - フィールド名変更
• convert - 値の変換
特徴: データを並列処理できる(超高速)
🟩 【2】Centralized Streaming Commands
┌──────────────────────────────────┐
│ サーチヘッドのみで実行 │
│ ⚡ やや速い │
└──────────────────────────────────┘
代表コマンド:
• head - 先頭N件取得
• tail - 末尾N件取得
• dedup - 重複削除
• join - 結合(非推奨)
• transaction - トランザクション化
特徴: 並列化できないが高速
🟨 【3】Transforming Commands
┌──────────────────────────────────┐
│ データをテーブル形式に変換 │
│ 📊 グラフ・統計に必須 │
└──────────────────────────────────┘
代表コマンド:
• stats - 統計計算
• timechart - 時系列グラフ
• chart - クロス集計
• top - 上位N件
• rare - 下位N件
• sort - ソート
特徴: 結果はStatisticsタブに表示
🟧 【4】Generating Commands
┌──────────────────────────────────┐
│ データを生成する │
│ 🔄 インデックスアクセス不要 │
└──────────────────────────────────┘
代表コマンド:
• makeresults - ダミーデータ生成
• inputlookup - ルックアップ読込
• dbxquery - DB検索
• rest - REST API呼出
特徴: 検索の先頭で使用
🟪 【5】Orchestrating Commands
┌──────────────────────────────────┐
│ 複数の検索を制御 │
│ 🔀 サブサーチ │
└──────────────────────────────────┘
代表コマンド:
• append - 結果を追加
• appendcols - カラム追加
• join - 結合
• subsearch - サブサーチ
特徴: パフォーマンス注意
🟥 【6】Dataset Processing Commands
┌──────────────────────────────────┐
│ データセット全体を処理 │
│ 📈 Data Model加速 │
└──────────────────────────────────┘
代表コマンド:
• tstats - 高速統計(推奨!)
• pivot - Data Model検索
特徴: 最も高速な統計処理
```
---
```
┌─────────────────────────────────────────────────────────────┐
│ 🎯 Token Types - 公式分類図解 │
└─────────────────────────────────────────────────────────────┘
🟥 【A】Form Input Tokens (入力トークン)
┌───────────────────────────────────┐
│ ユーザー入力を保存 │
└───────────────────────────────────┘
<input type="dropdown" token="status">
<choice value="200">Success</choice>
</input>
使用: $status$
値: "200"
🟢 【B】Predefined Tokens (定義済みトークン)
┌───────────────────────────────────┐
│ Splunkが自動で提供 │
└───────────────────────────────────┘
環境トークン:
• $env:user$ - ログインユーザー名
• $env:user_realname$ - ユーザー実名
クリックトークン:
• $click.value$ - クリックした値
• $click.value2$ - セルの値(テーブル)
• $row.fieldname$ - 行のフィールド値
時間トークン:
• $time.earliest$ - 開始時刻
• $time.latest$ - 終了時刻
🟡 【C】Search Result Tokens (結果トークン)
┌───────────────────────────────────┐
│ 検索結果から値を取得 │
└───────────────────────────────────┘
<search id="search1">
<query>| stats count</query>
<done>
<set token="total">$result.count$</set>
</done>
</search>
使用: $total$
🔵 【D】Search Job Metadata Tokens (メタデータトークン)
┌───────────────────────────────────┐
│ 検索ジョブの情報を取得 │
└───────────────────────────────────┘
構文: $search_name:job.<property>$
• $search1:job.resultCount$ - 結果件数
• $search1:job.startTime$ - 開始時刻
• $search1:job.hasResults$ - 結果有無(true/false)
🟪 【E】Eval Tokens (計算トークン)
┌───────────────────────────────────┐
│ evalで計算した値を保存 │
└───────────────────────────────────┘
<eval token="converted">
$original$ * 100
</eval>
注意: JavaScript正規表現エンジンを使用
(SPLとは異なる!)
```
---
```
┌─────────────────────────────────────────────────────────────┐
│ 💻 Token Syntax - 公式構文パターン │
└─────────────────────────────────────────────────────────────┘
【基本構文】
$token_name$ ← 基本
$$token_name$$ ← エスケープされたリテラル
【フィルター構文】(公式)
$token_name|s$ ← Safe (危険文字除去)
$token_name|h$ ← HTML encode
$token_name|u$ ← URL encode
$token_name|n$ ← No quotes
【プロパティアクセス】
$time.earliest$ ← timeトークンの開始
$time.latest$ ← timeトークンの終了
$result.fieldname$ ← 結果のフィールド
$row.fieldname$ ← 行のフィールド
【条件構文】
depends="$token$" ← トークンが存在すれば表示
rejects="$token$" ← トークンが無ければ表示
【設定構文】
<set token="name">value</set> ← 値を設定
<unset token="name"></unset> ← 値を削除
<condition ...> ← 条件付き設定
【evalトークン】
<eval token="name">expression</eval> ← 計算結果を設定
```
---
```
┌─────────────────────────────────────────────────────────────┐
│ 🔄 Complete Data Flow - 公式アーキテクチャ │
└─────────────────────────────────────────────────────────────┘
【レイヤー1: データ保管】
🟦 Index Layer
┌──────────────────────────┐
│ 📦 Indexed Data │
│ • web_logs │ ← 公式: "Events stored in index"
│ • app_logs │
│ • security │
└──────┬───────────────────┘
│
│ SPL Query (公式: "Search Processing")
▼
【レイヤー2: 検索処理】
🟪 Search Layer
┌──────────────────────────┐
│ 🔍 SPL Processing │
│ index=web_logs │ ← 公式: "Search commands"
│ | stats count by host │
└──────┬───────────────────┘
│
│ Results (公式: "Search results")
▼
【レイヤー3: 値の保管】
🟩 Token Layer
┌──────────────────────────┐
│ 💼 Token Storage │
│ $status$ = "200" │ ← 公式: "Token represents value"
│ $host$ = "server01" │
└──────┬───────────────────┘
│
│ Embed (公式: "Token values in searches")
▼
【レイヤー4: 可視化】
🟨 Visualization Layer
┌──────────────────────────┐
│ 📊 Chart Rendering │
│ • Line Chart │ ← 公式: "Visualization"
│ • Pie Chart │
│ • Table │
└──────────────────────────┘
【公式用語対応表】
━━━━━━━━━━━━━━━━━━━━━━━━
英語(公式) 日本語
━━━━━━━━━━━━━━━━━━━━━━━━
Index インデックス
Search 検索
Token トークン
Visualization 可視化
Dashboard ダッシュボード
Panel パネル
Drilldown ドリルダウン
Form Input フォーム入力
Search Result 検索結果
━━━━━━━━━━━━━━━━━━━━━━━━
```
---
```xml
<form>
<!-- ========================================== -->
<!-- 公式: Form Input Tokens -->
<!-- ========================================== -->
<label>Official Pattern Dashboard</label>
<fieldset submitButton="false"> <!-- 公式推奨: 即時反映 -->
<input type="dropdown" <!-- 公式: dropdown input -->
token="field_tok"> <!-- 公式命名例: field_tok -->
<label>Field Selection</label>
<choice value="host">Host</choice>
<choice value="source">Source</choice>
<choice value="sourcetype">Sourcetype</choice>
<default>host</default> <!-- 公式推奨: 必ずdefault設定 -->
</input>
<input type="time" token="time"> <!-- 公式: time input -->
<label>Time Range</label>
<default>
<earliest>-24h@h</earliest> <!-- 公式構文: -24h@h -->
<latest>now</latest>
</default>
</input>
</fieldset>
<!-- ========================================== -->
<!-- 公式: Token Usage in Search -->
<!-- ========================================== -->
<row>
<panel>
<table>
<search>
<query>
index=_internal <!-- 公式サンプル: _internal -->
source=*splunkd.log <!-- 公式パターン -->
earliest=$time.earliest$ <!-- 公式: time token -->
latest=$time.latest$
| stats count by $field_tok$ <!-- 公式例: by $field_tok$ -->
</query>
</search>
</table>
</panel>
</row>
</form>
<!-- ========================================== -->
<!-- 公式ドキュメント引用元 -->
<!-- ========================================== -->
<!--
Source: https:
Example from official docs:
<search>
index=_internal source=*splunkd.log
| stats count by $field_tok$
</search>
-->
```
---
```xml
<dashboard>
<label>Search Result Tokens (Official)</label>
<!-- ========================================== -->
<!-- 公式: Setting tokens from search results -->
<!-- ========================================== -->
<search id="activity_search"> <!-- 公式: searchにid付与 -->
<query>
index=_internal
| stats count by sourcetype
</query>
<!-- 公式パターン: <done>で結果を保存 -->
<done>
<!-- 公式構文: $result.<field>$ -->
<set token="result_count">
$result.count$ <!-- 公式: 最初の行のcount -->
</set>
</done>
</search>
<!-- ========================================== -->
<!-- 公式: Using search job metadata -->
<!-- ========================================== -->
<row>
<panel>
<html>
<h3>Search Metadata (Official)</h3>
<!-- 公式構文: $search_name:job.<metadata>$ -->
<p>Start Time: $activity_search:job.startTime$</p>
<p>Result Count: $activity_search:job.resultCount$</p>
<p>Has Results: $activity_search:job.hasResults$</p>
</html>
</panel>
</row>
</dashboard>
<!-- ========================================== -->
<!-- 公式メタデータオプション(完全リスト) -->
<!-- ========================================== -->
<!--
From: https:
Available metadata:
• startTime - 検索開始時刻
• endTime - 検索終了時刻
• resultCount - 結果件数
• hasResults - 結果有無(true/false)
• isDone - 完了状態
• isError - エラー有無
-->
```
---
```xml
<form>
<label>Drilldown Pattern (Official)</label>
<fieldset submitButton="false">
<input type="time" token="time">
<default>
<earliest>-24h</earliest>
<latest>now</latest>
</default>
</input>
</fieldset>
<row>
<panel>
<title>Click to Drill Down</title>
<table>
<search>
<query>
index=_internal
| stats count by sourcetype
| sort -count
</query>
</search>
<!-- ========================================== -->
<!-- 公式: Predefined tokens for drilldown -->
<!-- ========================================== -->
<drilldown>
<!-- 公式: $click.value2$ for table cell -->
<set token="clicked_value">
$click.value2$ <!-- 公式推奨トークン -->
</set>
<!-- 公式: $row.<fieldname>$ for specific field -->
<set token="clicked_sourcetype">
$row.sourcetype$ <!-- 公式構文 -->
</set>
<!-- 公式: Control token for panel display -->
<set token="show_panel">true</set>
</drilldown>
</table>
</panel>
</row>
<!-- ========================================== -->
<!-- 公式: Conditional panel display -->
<!-- ========================================== -->
<row>
<panel depends="$show_panel$"> <!-- 公式: depends構文 -->
<title>Details for: $clicked_sourcetype$</title>
<table>
<search>
<query>
index=_internal
sourcetype=$clicked_sourcetype$ <!-- 公式: トークン埋込 -->
earliest=$time.earliest$
latest=$time.latest$
| head 100
| table _time, host, source
</query>
</search>
</table>
</panel>
</row>
</form>
<!-- ========================================== -->
<!-- 公式: Predefined Click Tokens -->
<!-- ========================================== -->
<!--
From: https:
Available click tokens:
• $click.value$ - The value of the field clicked
• $click.value2$ - The value in a table cell
• $click.name$ - The field name clicked
• $click.name2$ - The row field name
Available row tokens:
• $row.<fieldname>$ - Value of specific field in clicked row
• $row.<fieldname>.value$ - Alternate syntax
-->
```
---
```
┌─────────────────────────────────────────────────────────────┐
│ ✅ Official Best Practices from Splunk Docs │
└─────────────────────────────────────────────────────────────┘
【トークン命名】(公式推奨)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ GOOD: field_tok, time_range, selected_host
❌ BAD: tok1, t, x, temp
【トークンフィルター使用】(公式)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 推奨: $user_input|s$ ← Safe (セキュア)
❌ 非推奨: $user_input$ ← 危険
【デフォルト値】(公式必須)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 必須:
<input type="dropdown" token="status">
<default>200</default> ← これが無いとエラー!
</input>
【パフォーマンス】(公式推奨)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 推奨: tstats (最速の統計コマンド)
✅ 推奨: Base search (検索の再利用)
❌ 非推奨: subsearch (遅い)
❌ 非推奨: join (遅い)
【検索の書き方】(公式)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ GOOD:
index=main status=200
| stats count
最初に絞り込み(index, status)
次にコマンド(stats)
❌ BAD:
index=main
| stats count
| where status=200
後で絞り込むと遅い!
```
---
```
┌─────────────────────────────────────────────────────────────┐
│ 📖 Official Learning Resources │
└─────────────────────────────────────────────────────────────┘
【必読ドキュメント】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1️⃣ Token Usage in Dashboards
https:
→ トークンの完全ガイド
2️⃣ Search Reference
https:
→ SPLコマンド全リスト
3️⃣ Commands by Category
https:
→ コマンドの分類
4️⃣ Dashboard Examples App
https:
→ 実装サンプル集(必須!)
【公式チュートリアル】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎓 Search Tutorial
https:
🎓 Dashboard Tutorial
https:
【クイックリファレンス】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📄 SPL Quick Reference (PDF)
https:
📄 Commands Quick Reference
https:
【公式トレーニング】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎓 Splunk Fundamentals 1
→ 基礎
🎓 Splunk Fundamentals 2
→ SPL中級
🎓 Creating Dashboards
→ ダッシュボード開発
```
---
```
┌─────────────────────────────────────────────────────────────┐
│ 📚 Official Terminology (Splexicon) │
└─────────────────────────────────────────────────────────────┘
【A】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• App - アプリケーション
• Argument - 引数
• Artifact - 成果物
【C】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Command - コマンド
• Clause - 句
• Click Event - クリックイベント
【D】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Dashboard - ダッシュボード
• Drilldown - ドリルダウン(詳細表示)
• Default - デフォルト値
【E】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Event - イベント(ログ1行)
• Eval - 評価・計算
• Earliest - 開始時刻
【F】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Field - フィールド
• Form - フォーム
• Function - 関数
• Filter - フィルター
【I】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Index - インデックス
• Input - 入力
• Indexer - インデクサー(データ保管)
【J】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Job - ジョブ(検索実行)
• Join - 結合
【L】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Latest - 終了時刻
• Lookup - ルックアップ(外部データ)
【M】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Metadata - メタデータ
• Makeresults - ダミーデータ生成
【P】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Panel - パネル
• Pipe - パイプ(|)
• Predefined - 定義済み
【R】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Result - 結果
• Row - 行
【S】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• SPL - Search Processing Language
• Search - 検索
• Sourcetype - ソースタイプ
• Stats - 統計
• Streaming - ストリーミング
【T】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Token - トークン
• Transforming - 変換
• Timechart - 時系列グラフ
【V】
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Visualization - 可視化
• Value - 値
```
---
# 📝 SPL・トークン 公式コード完全解説 - 1行ずつコメント版
YUKIKOさん、公式パターンのコードを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:
Search Reference:
https:
Chart Options:
https:
-->
```
---
## 💻 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 {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white;
padding: 12px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
transition: all 0.3s ease;
}
.close-button:hover {
transform: translateY(-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");
$("#close_detail_btn").on("click", function() {
tokens.unset("show_detail");
tokens.unset("clicked_host");
tokens.unset("clicked_count");
});
});
</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,
dc(host) as unique_hosts
| eval error_rate=round(error_count/total*100, 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 {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
.kpi-card {
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パネルでトークンを表示
-->
```
---