🎓 Splunk先生の超詳しい新人エンジニア向け解説
このコードを完全に理解できるよう、一行ずつ丁寧に解説します!
📋 全体構成の概要
このダッシュボードは3つのパートで構成されています:
- データ取得部分 - SPLクエリで線の色・太さを決定
- 図形表示部分 - HTML/CSSで四角形と線を描画
- 状態表示部分 - 現在の値をテーブルで確認
🔍 パート1: ダッシュボードの基本設定
<!-- XMLの開始。Splunkダッシュボードのバージョンを指定 -->
<dashboard version="1.1">
<!-- ダッシュボードのタイトル(Splunk画面の上部に表示される) -->
<label>0120しかくと線と斜め外船OKインデックスなしあとで見返す</label>
<!-- ダッシュボードの説明文(現在は空欄) -->
<description></description>
🔍 パート2: データ取得用の検索クエリ
<!-- コメント: この検索はUI上には表示されない(非表示で裏で動く) -->
<!-- データ取得用の検索 (非表示) -->
<!-- 検索の定義開始。id="line_data_search"で他の場所から参照可能 -->
<search id="line_data_search">
<!-- SPLクエリの開始 -->
<query>
<!-- ==================================================== -->
<!-- ステップ1: ダミーデータを1行生成 -->
<!-- ==================================================== -->
<!-- makeresultsコマンド: 空のイベントを1行作成 -->
| makeresults count=1
<!-- ==================================================== -->
<!-- ステップ2: 各線の状態を示すフィールドを作成 -->
<!-- ==================================================== -->
<!-- evalコマンド: フィールドを計算して追加 -->
| eval
<!-- 上辺の線の状態: ランダムに "ok" または "error" を生成 -->
<!-- random()%2==0 → 2で割った余りが0(つまり偶数)なら"ok"、それ以外は"error" -->
line_outer_top_status=case(random()%2==0, "ok", 1==1, "error"),
<!-- 右辺の線の値: 0〜99のランダムな数値 -->
<!-- random() % 100 → ランダム値を100で割った余り -->
line_outer_right_value=random() % 100,
<!-- 下辺の線のカウント: 0〜19のランダムな数値 -->
line_outer_bottom_count=random() % 20,
<!-- 左辺の線の状態: ランダムに "down" または "up" を生成 -->
<!-- random()%3==0 → 3で割り切れる時だけ"down"、それ以外は"up" -->
line_outer_left_status=case(random()%3==0, "down", 1==1, "up"),
<!-- 対角線1のレイテンシ: 0〜199のランダムな数値 -->
line_diag_1_latency=random() % 200,
<!-- 対角線2の帯域幅: 0〜99のランダムな数値 -->
line_diag_2_bandwidth=random() % 100,
<!-- 水平線のトラフィック: 0〜1999のランダムな数値 -->
line_cross_h_traffic=random() % 2000,
<!-- 垂直線の負荷: 0.00〜0.99のランダムな小数 -->
<!-- (random() % 100) / 100.0 → 100で割って小数にする -->
line_cross_v_load=(random() % 100) / 100.0
<!-- ==================================================== -->
<!-- ステップ3: 状態に基づいて線の「色」を決定 -->
<!-- ==================================================== -->
<!-- evalコマンド: 各線の色をif文で条件分岐 -->
| eval
<!-- 上辺の色: statusが"error"なら赤(#FF0000)、それ以外は緑(#00FF00) -->
line_outer_top_color=if(line_outer_top_status=="error", "#FF0000", "#00FF00"),
<!-- 右辺の色: 値が80より大きい(>は>の意味)なら赤、それ以外は緑 -->
<!-- XMLでは<や>は特殊文字なので > や < でエスケープが必要 -->
line_outer_right_color=if(line_outer_right_value>80, "#FF0000", "#00FF00"),
<!-- 下辺の色: カウントが10未満(<は<の意味)なら赤、それ以外は緑 -->
line_outer_bottom_color=if(line_outer_bottom_count<10, "#FF0000", "#00FF00"),
<!-- 左辺の色: statusが"down"なら赤、それ以外は緑 -->
line_outer_left_color=if(line_outer_left_status=="down", "#FF0000", "#00FF00"),
<!-- 対角線1の色: レイテンシが100msより大きいなら赤、それ以外はシアン(#00FFFF) -->
line_diag_1_color=if(line_diag_1_latency>100, "#FF0000", "#00FFFF"),
<!-- 対角線2の色: 帯域が50Mbps未満なら赤、それ以外はシアン -->
line_diag_2_color=if(line_diag_2_bandwidth<50, "#FF0000", "#00FFFF"),
<!-- 水平線の色: トラフィックが1000より大きいなら赤、それ以外は黄色(#FFFF00) -->
line_cross_h_color=if(line_cross_h_traffic>1000, "#FF0000", "#FFFF00"),
<!-- 垂直線の色: 負荷が0.8より大きいなら赤、それ以外は黄色 -->
line_cross_v_color=if(line_cross_v_load>0.8, "#FF0000", "#FFFF00")
<!-- ==================================================== -->
<!-- ステップ4: 状態に基づいて線の「太さ」を決定 -->
<!-- ==================================================== -->
<!-- evalコマンド: 各線の太さをif文で条件分岐 -->
| eval
<!-- 上辺の太さ: statusが"error"なら太く(6px)、それ以外は普通(4px) -->
line_outer_top_width=if(line_outer_top_status=="error", "6", "4"),
<!-- 右辺の太さ: 値が80より大きいなら太く、それ以外は普通 -->
line_outer_right_width=if(line_outer_right_value>80, "6", "4"),
<!-- 下辺の太さ: カウントが10未満なら太く、それ以外は普通 -->
line_outer_bottom_width=if(line_outer_bottom_count<10, "6", "4"),
<!-- 左辺の太さ: statusが"down"なら太く、それ以外は普通 -->
line_outer_left_width=if(line_outer_left_status=="down", "6", "4"),
<!-- 対角線1の太さ: レイテンシが100msより大きいなら太く、それ以外は普通 -->
line_diag_1_width=if(line_diag_1_latency>100, "6", "4"),
<!-- 対角線2の太さ: 帯域が50Mbps未満なら太く、それ以外は普通 -->
line_diag_2_width=if(line_diag_2_bandwidth<50, "6", "4"),
<!-- 水平線の太さ: トラフィックが1000より大きいなら太く、それ以外は普通 -->
line_cross_h_width=if(line_cross_h_traffic>1000, "6", "4"),
<!-- 垂直線の太さ: 負荷が0.8より大きいなら太く、それ以外は普通 -->
line_cross_v_width=if(line_cross_v_load>0.8, "6", "4")
<!-- ==================================================== -->
<!-- ステップ5: 必要なフィールドだけを残す -->
<!-- ==================================================== -->
<!-- fieldsコマンド: 指定したフィールドだけを残して、それ以外を削除 -->
<!-- これにより、トークンに設定するデータが整理される -->
| fields line_outer_top_status, line_outer_top_color, line_outer_top_width,
line_outer_right_value, line_outer_right_color, line_outer_right_width,
line_outer_bottom_count, line_outer_bottom_color, line_outer_bottom_width,
line_outer_left_status, line_outer_left_color, line_outer_left_width,
line_diag_1_latency, line_diag_1_color, line_diag_1_width,
line_diag_2_bandwidth, line_diag_2_color, line_diag_2_width,
line_cross_h_traffic, line_cross_h_color, line_cross_h_width,
line_cross_v_load, line_cross_v_color, line_cross_v_width
<!-- SPLクエリの終了 -->
</query>
<!-- 5秒ごとに検索を自動実行(リフレッシュ) -->
<refresh>5s</refresh>
<!-- リフレッシュタイプ: delay → 前回の検索完了から5秒後に次を実行 -->
<refreshType>delay</refreshType>
<!-- ==================================================== -->
<!-- ステップ6: 検索完了時にトークンに値を設定 -->
<!-- ==================================================== -->
<!-- doneイベント: 検索が完了したときに実行される -->
<done>
<!-- 各フィールドの値をトークン変数に保存 -->
<!-- $result.フィールド名$ で検索結果の値を取得できる -->
<!-- 上辺の線の色をトークンに保存 -->
<set token="line_outer_top_color">$result.line_outer_top_color$</set>
<!-- 上辺の線の太さをトークンに保存 -->
<set token="line_outer_top_width">$result.line_outer_top_width$</set>
<!-- 右辺の線の色をトークンに保存 -->
<set token="line_outer_right_color">$result.line_outer_right_color$</set>
<!-- 右辺の線の太さをトークンに保存 -->
<set token="line_outer_right_width">$result.line_outer_right_width$</set>
<!-- 下辺の線の色をトークンに保存 -->
<set token="line_outer_bottom_color">$result.line_outer_bottom_color$</set>
<!-- 下辺の線の太さをトークンに保存 -->
<set token="line_outer_bottom_width">$result.line_outer_bottom_width$</set>
<!-- 左辺の線の色をトークンに保存 -->
<set token="line_outer_left_color">$result.line_outer_left_color$</set>
<!-- 左辺の線の太さをトークンに保存 -->
<set token="line_outer_left_width">$result.line_outer_left_width$</set>
<!-- 対角線1の色をトークンに保存 -->
<set token="line_diag_1_color">$result.line_diag_1_color$</set>
<!-- 対角線1の太さをトークンに保存 -->
<set token="line_diag_1_width">$result.line_diag_1_width$</set>
<!-- 対角線2の色をトークンに保存 -->
<set token="line_diag_2_color">$result.line_diag_2_color$</set>
<!-- 対角線2の太さをトークンに保存 -->
<set token="line_diag_2_width">$result.line_diag_2_width$</set>
<!-- 水平線の色をトークンに保存 -->
<set token="line_cross_h_color">$result.line_cross_h_color$</set>
<!-- 水平線の太さをトークンに保存 -->
<set token="line_cross_h_width">$result.line_cross_h_width$</set>
<!-- 垂直線の色をトークンに保存 -->
<set token="line_cross_v_color">$result.line_cross_v_color$</set>
<!-- 垂直線の太さをトークンに保存 -->
<set token="line_cross_v_width">$result.line_cross_v_width$</set>
<!-- 表示用: 上辺の状態値("ok" or "error")をトークンに保存 -->
<set token="line_outer_top_status">$result.line_outer_top_status$</set>
<!-- 表示用: 右辺の数値(0〜99)をトークンに保存 -->
<set token="line_outer_right_value">$result.line_outer_right_value$</set>
<!-- 表示用: 下辺のカウント(0〜19)をトークンに保存 -->
<set token="line_outer_bottom_count">$result.line_outer_bottom_count$</set>
<!-- 表示用: 左辺の状態値("up" or "down")をトークンに保存 -->
<set token="line_outer_left_status">$result.line_outer_left_status$</set>
<!-- 表示用: 対角線1のレイテンシ(0〜199ms)をトークンに保存 -->
<set token="line_diag_1_latency">$result.line_diag_1_latency$</set>
<!-- 表示用: 対角線2の帯域(0〜99Mbps)をトークンに保存 -->
<set token="line_diag_2_bandwidth">$result.line_diag_2_bandwidth$</set>
<!-- 表示用: 水平線のトラフィック(0〜1999)をトークンに保存 -->
<set token="line_cross_h_traffic">$result.line_cross_h_traffic$</set>
<!-- 表示用: 垂直線の負荷(0.00〜0.99)をトークンに保存 -->
<set token="line_cross_v_load">$result.line_cross_v_load$</set>
<!-- doneイベントの終了 -->
</done>
<!-- 検索の定義終了 -->
</search>
🔍 パート3: 図形と線の描画(HTML/CSS)
<!-- ダッシュボードの行(横方向のレイアウト単位)を開始 -->
<row>
<!-- パネル(個別のコンテンツ領域)を開始 -->
<panel>
<!-- HTMLコンテンツの開始(ここから自由にHTML/CSSが書ける) -->
<html>
<!-- CSSスタイルの開始 -->
<style>
/* ========================================== */
/* コンテナ (図形の親要素) */
/* ========================================== */
/* .container クラスのスタイル定義 */
.container {
position: relative; /* 子要素の絶対配置の基準点になる */
width: 600px; /* コンテナの幅を600pxに設定 */
height: 400px; /* コンテナの高さを400pxに設定 */
background: #f5f5f5; /* 背景色を明るいグレーに設定 */
margin: 30px; /* 外側に30pxの余白を設定 */
}
/* ========================================== */
/* 四角形 (BOX) の共通スタイル */
/* ========================================== */
/* .box クラスのスタイル定義(全ての四角形に適用) */
.box {
position: absolute; /* 絶対配置: 親要素を基準に自由に配置可能 */
width: 120px; /* 四角形の幅を120pxに設定 */
height: 80px; /* 四角形の高さを80pxに設定 */
border-radius: 10px; /* 角を10pxの丸みにする */
color: white; /* テキストの色を白に設定 */
display: flex; /* フレックスボックスレイアウトを使用 */
justify-content: center; /* 水平方向の中央揃え */
align-items: center; /* 垂直方向の中央揃え */
font-weight: bold; /* テキストを太字に設定 */
z-index: 10; /* 重なり順: 10(線より前面に表示) */
box-shadow: 0 4px 8px rgba(0,0,0,0.2); /* 影の効果を追加 */
}
/* 左上の四角形(BOX1)のスタイル */
.box1 {
top: 20px; /* 上端から20px下の位置 */
left: 20px; /* 左端から20px右の位置 */
background: #42A5F5; /* 背景色を青色に設定 */
}
/* 右上の四角形(BOX2)のスタイル */
.box2 {
top: 20px; /* 上端から20px下の位置 */
right: 20px; /* 右端から20px左の位置 */
background: #4CAF50; /* 背景色を緑色に設定 */
}
/* 左下の四角形(BOX3)のスタイル */
.box3 {
bottom: 20px; /* 下端から20px上の位置 */
left: 20px; /* 左端から20px右の位置 */
background: #FFA726; /* 背景色をオレンジ色に設定 */
}
/* 右下の四角形(BOX4)のスタイル */
.box4 {
bottom: 20px; /* 下端から20px上の位置 */
right: 20px; /* 右端から20px左の位置 */
background: #E53935; /* 背景色を赤色に設定 */
}
/* ========================================== */
/* SVG (線を描画するためのキャンバス) */
/* ========================================== */
/* svg要素のスタイル定義 */
svg {
position: absolute; /* 絶対配置 */
top: 0; /* 上端に配置 */
left: 0; /* 左端に配置 */
width: 100%; /* 親要素の幅いっぱいに広げる */
height: 100%; /* 親要素の高さいっぱいに広げる */
pointer-events: none; /* マウスクリックを無効化(下の要素が反応する) */
z-index: 1; /* 重なり順: 1(四角形より背面) */
}
/* ========================================== */
/* 線 (LINE) の共通スタイル */
/* ========================================== */
/* .line クラスのスタイル定義(全ての線に適用) */
.line {
fill: none; /* 塗りつぶしなし(線だけ描画) */
transition: stroke 0.5s ease, stroke-width 0.3s ease;
/* ↑色と太さが変わる時、0.5秒かけてスムーズに変化させる */
}
/* 対角線専用のスタイル */
.line-diag {
stroke-dasharray: 8, 4; /* 破線パターン: 8px描画、4px空白 */
}
<!-- CSSスタイルの終了 -->
</style>
<!-- ========================================== -->
<!-- HTML構造 (トークンで色と太さを動的に変更) -->
<!-- ========================================== -->
<!-- コンテナ要素の開始(四角形と線の親要素) -->
<div class="container">
<!-- SVG要素の開始(ここに線を描画) -->
<svg>
<!-- ========================================== -->
<!-- 外枠の線 (4辺) -->
<!-- ========================================== -->
<!-- 上辺の線: BOX1の中央(80,60) → BOX2の中央(520,60) -->
<!-- id="line-outer-top" → この線を識別するためのID -->
<!-- class="line" → 上で定義した.lineスタイルを適用 -->
<!-- x1,y1 → 線の始点の座標 -->
<!-- x2,y2 → 線の終点の座標 -->
<!-- stroke="$line_outer_top_color$" → トークンから色を取得 -->
<!-- stroke-width="$line_outer_top_width$" → トークンから太さを取得 -->
<line id="line-outer-top" class="line"
x1="80" y1="60" x2="520" y2="60"
stroke="$line_outer_top_color$"
stroke-width="$line_outer_top_width$"/>
<!-- 右辺の線: BOX2の中央(520,60) → BOX4の中央(520,340) -->
<line id="line-outer-right" class="line"
x1="520" y1="60" x2="520" y2="340"
stroke="$line_outer_right_color$"
stroke-width="$line_outer_right_width$"/>
<!-- 下辺の線: BOX4の中央(520,340) → BOX3の中央(80,340) -->
<line id="line-outer-bottom" class="line"
x1="520" y1="340" x2="80" y2="340"
stroke="$line_outer_bottom_color$"
stroke-width="$line_outer_bottom_width$"/>
<!-- 左辺の線: BOX3の中央(80,340) → BOX1の中央(80,60) -->
<line id="line-outer-left" class="line"
x1="80" y1="340" x2="80" y2="60"
stroke="$line_outer_left_color$"
stroke-width="$line_outer_left_width$"/>
<!-- ========================================== -->
<!-- 対角線 (串刺し) -->
<!-- ========================================== -->
<!-- 対角線1: 左上BOX1(80,60) → 右下BOX4(520,340) -->
<!-- class="line line-diag" → 2つのクラスを適用(破線になる) -->
<line id="line-diag-1" class="line line-diag"
x1="80" y1="60" x2="520" y2="340"
stroke="$line_diag_1_color$"
stroke-width="$line_diag_1_width$"/>
<!-- 対角線2: 右上BOX2(520,60) → 左下BOX3(80,340) -->
<line id="line-diag-2" class="line line-diag"
x1="520" y1="60" x2="80" y2="340"
stroke="$line_diag_2_color$"
stroke-width="$line_diag_2_width$"/>
<!-- ========================================== -->
<!-- 中央十字 -->
<!-- ========================================== -->
<!-- 水平線: 左中央(80,200) → 右中央(520,200) -->
<line id="line-cross-h" class="line"
x1="80" y1="200" x2="520" y2="200"
stroke="$line_cross_h_color$"
stroke-width="$line_cross_h_width$"/>
<!-- 垂直線: 上中央(300,60) → 下中央(300,340) -->
<line id="line-cross-v" class="line"
x1="300" y1="60" x2="300" y2="340"
stroke="$line_cross_v_color$"
stroke-width="$line_cross_v_width$"/>
<!-- SVG要素の終了 -->
</svg>
<!-- ========================================== -->
<!-- 4つの四角形 -->
<!-- ========================================== -->
<!-- 左上の四角形: class="box box1"で2つのクラスを適用 -->
<!-- box → 共通スタイル、box1 → 個別の位置と色 -->
<div class="box box1">BOX1</div>
<!-- 右上の四角形 -->
<div class="box box2">BOX2</div>
<!-- 左下の四角形 -->
<div class="box box3">BOX3</div>
<!-- 右下の四角形 -->
<div class="box box4">BOX4</div>
<!-- コンテナ要素の終了 -->
</div>
<!-- HTMLコンテンツの終了 -->
</html>
<!-- パネルの終了 -->
</panel>
<!-- 行の終了 -->
</row>
🎓 続き:データ監視パネルと状態表示パネルの解説
🔍 パート4: データ監視パネル(デバッグ用)
<!-- ========================================== -->
<!-- データ監視パネル (デバッグ用) -->
<!-- ========================================== -->
<!-- 2行目の開始 -->
<row>
<!-- パネルの開始 -->
<panel>
<!-- パネルのタイトル -->
<title>📊 線の状態データ (5秒ごとに自動更新)</title>
<!-- テーブル要素の開始(検索結果を表形式で表示) -->
<table>
<!-- base属性: 上で定義したline_data_search検索の結果を再利用 -->
<!-- これにより、同じクエリを2回実行せずに済む(効率的) -->
<search base="line_data_search"></search>
<!-- オプション設定: ドリルダウン(クリック)を無効化 -->
<option name="drilldown">none</option>
<!-- オプション設定: リフレッシュ中にプログレスバーを表示 -->
<option name="refresh.display">progressbar</option>
<!-- テーブル要素の終了 -->
</table>
<!-- パネルの終了 -->
</panel>
<!-- 2行目の終了 -->
</row>
解説ポイント:
-
<search base="line_data_search">で、上で定義した検索を再利用 - 同じデータを2回取得しないのでパフォーマンスが良い
-
drilldownを無効化することで、誤クリックを防止
🔍 パート5: 現在の線の状態パネル
<!-- 3行目の開始 -->
<row>
<!-- パネルの開始 -->
<panel>
<!-- パネルのタイトル -->
<title>🎯 現在の線の状態</title>
<!-- HTMLコンテンツの開始 -->
<html>
<!-- CSSスタイルの開始 -->
<style>
/* ========================================== */
/* 状態表示用のグリッドレイアウト */
/* ========================================== */
/* .status-grid クラスのスタイル定義 */
.status-grid {
display: grid; /* グリッドレイアウトを使用 */
grid-template-columns: repeat(2, 1fr);
/* ↑2列のグリッド、各列は均等な幅(1fr = 1フラクション) */
gap: 15px; /* グリッド間の隙間を15pxに設定 */
padding: 20px; /* 内側の余白を20pxに設定 */
background: #f9f9f9; /* 背景色をごく薄いグレーに設定 */
}
/* .status-item クラスのスタイル定義(各状態ボックス) */
.status-item {
background: white; /* 背景色を白に設定 */
border-left: 4px solid #42A5F5;
/* ↑左側に4pxの青い線(アクセント) */
padding: 12px; /* 内側の余白を12pxに設定 */
border-radius: 4px; /* 角を4pxの丸みにする */
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
/* ↑軽い影の効果(立体感を出す) */
}
/* .status-label クラスのスタイル定義(ラベル部分) */
.status-label {
font-size: 11px; /* フォントサイズを11pxに設定 */
color: #666; /* 文字色をグレーに設定 */
font-weight: bold; /* 太字に設定 */
margin-bottom: 5px; /* 下に5pxの余白を設定 */
}
/* .status-value クラスのスタイル定義(値の部分) */
.status-value {
font-size: 16px; /* フォントサイズを16pxに設定 */
font-weight: bold; /* 太字に設定 */
color: #333; /* 文字色を濃いグレーに設定 */
}
/* .status-color クラスのスタイル定義(色の四角) */
.status-color {
display: inline-block; /* インライン要素だが幅・高さを指定可能 */
width: 20px; /* 幅を20pxに設定 */
height: 20px; /* 高さを20pxに設定 */
border-radius: 3px; /* 角を3pxの丸みにする */
vertical-align: middle; /* 縦方向の中央揃え */
margin-left: 8px; /* 左に8pxの余白を設定 */
border: 1px solid #ccc; /* 1pxの薄いグレーの枠線 */
}
<!-- CSSスタイルの終了 -->
</style>
<!-- ========================================== -->
<!-- HTML構造(8本の線の状態を表示) -->
<!-- ========================================== -->
<!-- グリッドコンテナの開始 -->
<div class="status-grid">
<!-- ========================================== -->
<!-- 1つ目: 上辺の線の状態 -->
<!-- ========================================== -->
<!-- 状態アイテムの開始 -->
<div class="status-item">
<!-- ラベル部分: 絵文字 + 線の名前 + 管理ID -->
<div class="status-label">🔵 上辺 (line-outer-top)</div>
<!-- 値の部分 -->
<div class="status-value">
<!-- トークンから状態値を表示("ok" または "error") -->
$line_outer_top_status$
<!-- 色の四角: トークンから背景色を取得 -->
<!-- style属性で動的にbackground colorを設定 -->
<!-- 自己終了タグ: <span .../> -->
<span class="status-color" style="background: $line_outer_top_color$;"/>
<!-- 値の部分の終了 -->
</div>
<!-- 状態アイテムの終了 -->
</div>
<!-- ========================================== -->
<!-- 2つ目: 右辺の線の状態 -->
<!-- ========================================== -->
<div class="status-item">
<div class="status-label">🟢 右辺 (line-outer-right)</div>
<div class="status-value">
<!-- トークンから数値を表示 + "%" 記号を追加 -->
$line_outer_right_value$%
<!-- 色の四角 -->
<span class="status-color" style="background: $line_outer_right_color$;"/>
</div>
</div>
<!-- ========================================== -->
<!-- 3つ目: 下辺の線の状態 -->
<!-- ========================================== -->
<div class="status-item">
<div class="status-label">🟠 下辺 (line-outer-bottom)</div>
<div class="status-value">
<!-- "Count: " というラベル + トークンから数値を表示 -->
Count: $line_outer_bottom_count$
<span class="status-color" style="background: $line_outer_bottom_color$;"/>
</div>
</div>
<!-- ========================================== -->
<!-- 4つ目: 左辺の線の状態 -->
<!-- ========================================== -->
<div class="status-item">
<div class="status-label">🔴 左辺 (line-outer-left)</div>
<div class="status-value">
<!-- トークンから状態値を表示("up" または "down") -->
$line_outer_left_status$
<span class="status-color" style="background: $line_outer_left_color$;"/>
</div>
</div>
<!-- ========================================== -->
<!-- 5つ目: 対角線1の状態 -->
<!-- ========================================== -->
<div class="status-item">
<div class="status-label">💠 対角線1 (line-diag-1)</div>
<div class="status-value">
<!-- トークンからレイテンシの数値を表示 + "ms"(ミリ秒)を追加 -->
$line_diag_1_latency$ms
<span class="status-color" style="background: $line_diag_1_color$;"/>
</div>
</div>
<!-- ========================================== -->
<!-- 6つ目: 対角線2の状態 -->
<!-- ========================================== -->
<div class="status-item">
<div class="status-label">💠 対角線2 (line-diag-2)</div>
<div class="status-value">
<!-- トークンから帯域幅の数値を表示 + " Mbps"(メガビット毎秒)を追加 -->
$line_diag_2_bandwidth$ Mbps
<span class="status-color" style="background: $line_diag_2_color$;"/>
</div>
</div>
<!-- ========================================== -->
<!-- 7つ目: 水平線の状態 -->
<!-- ========================================== -->
<div class="status-item">
<div class="status-label">➖ 水平線 (line-cross-h)</div>
<div class="status-value">
<!-- "Traffic: " というラベル + トークンからトラフィック値を表示 -->
Traffic: $line_cross_h_traffic$
<span class="status-color" style="background: $line_cross_h_color$;"/>
</div>
</div>
<!-- ========================================== -->
<!-- 8つ目: 垂直線の状態 -->
<!-- ========================================== -->
<div class="status-item">
<div class="status-label">| 垂直線 (line-cross-v)</div>
<div class="status-value">
<!-- "Load: " というラベル + トークンから負荷値を表示 -->
Load: $line_cross_v_load$
<span class="status-color" style="background: $line_cross_v_color$;"/>
</div>
</div>
<!-- グリッドコンテナの終了 -->
</div>
<!-- HTMLコンテンツの終了 -->
</html>
<!-- パネルの終了 -->
</panel>
<!-- 3行目の終了 -->
</row>
<!-- ダッシュボードの終了 -->
</dashboard>
🔍 パート6: コメント部分(実際の使用例)
<!--
==========================================
実際の使用例
==========================================
例1: ネットワーク回線監視
index=network sourcetype=cisco:ios
| stats latest(link_status) as line_outer_top_status,
avg(bandwidth_util) as line_outer_right_value,
count(errors) as line_outer_bottom_count,
latest(interface_status) as line_outer_left_status
| eval line_outer_top_color=if(line_outer_top_status=="down", "#FF0000", "#00FF00"),
line_outer_right_color=if(line_outer_right_value>80, "#FF0000", "#00FF00"),
line_outer_bottom_color=if(line_outer_bottom_count<10, "#FF0000", "#00FF00"),
line_outer_left_color=if(line_outer_left_status=="down", "#FF0000", "#00FF00")
例2: サーバー間通信監視
index=app sourcetype=api_logs
| stats avg(response_time) as line_diag_1_latency,
avg(throughput_mbps) as line_diag_2_bandwidth
| eval line_diag_1_color=if(line_diag_1_latency>100, "#FF0000", "#00FFFF"),
line_diag_2_color=if(line_diag_2_bandwidth<50, "#FF0000", "#00FFFF")
==========================================
-->
解説:
- この部分はコメントなので、Splunkでは実行されない
- 実際のインデックスデータを使う時のサンプルクエリ
-
makeresultsの部分を、この例のように置き換えて使う
📚 全体の動作フロー まとめ
1. 検索実行 (5秒ごとに自動リフレッシュ)
↓
2. SPLクエリでデータを生成・計算
- ランダムな値を生成
- 条件に応じて色を決定 (#FF0000 or #00FF00)
- 条件に応じて太さを決定 (6px or 4px)
↓
3. 検索完了時に<done>イベント発火
↓
4. 各フィールドの値をトークンに保存
例: $line_outer_top_color$ = "#FF0000"
↓
5. HTMLが再レンダリング
- SVGの<line>要素のstroke属性にトークンが展開される
- 例: stroke="$line_outer_top_color$" → stroke="#FF0000"
↓
6. 線の色と太さが変わる!
↓
7. 5秒後に再度1に戻る(ループ)
🎯 重要な技術ポイント
1️⃣ XMLエスケープ
<!-- ❌ 間違い: XMLパーサーがエラー -->
line_outer_right_value>80
<!-- ✅ 正しい: > を使う -->
line_outer_right_value>80
-
<は< -
>は> -
&は&
2️⃣ トークンの仕組み
<!-- トークンに保存 -->
<set token="my_color">#FF0000</set>
<!-- HTMLで使用 -->
<line stroke="$my_color$"/>
<!-- 実際に展開される -->
<line stroke="#FF0000"/>
3️⃣ CSS変数ではなくSVG属性で直接指定
<!-- JavaScriptを使わない方法 -->
<line stroke="$token_color$" stroke-width="$token_width$"/>
<!-- トークンがSVG属性に直接埋め込まれる -->
4️⃣ 検索の再利用
<!-- 元の検索 -->
<search id="my_search">...</search>
<!-- 再利用 -->
<search base="my_search"></search>
- 同じクエリを2回実行しない
- パフォーマンスが向上
🚀 カスタマイズ方法
線を追加したい場合
- SPLクエリに追加
| eval line_new_color=if(条件, "#FF0000", "#00FF00"),
line_new_width=if(条件, "6", "4")
- トークンに追加
<set token="line_new_color">$result.line_new_color$</set>
<set token="line_new_width">$result.line_new_width$</set>
- SVGに追加
<line id="line-new" class="line"
x1="..." y1="..." x2="..." y2="..."
stroke="$line_new_color$"
stroke-width="$line_new_width$"/>
💡 新人エンジニアへのアドバイス
-
まずは動かしてみる
- Splunkにコピペして実際に動作確認
- 5秒ごとに色が変わることを確認
-
少しずつ変更してみる
- 色を変える:
#FF0000→#0000FF(青) - 条件を変える:
>80→>50 - 座標を変える:
x1="80"→x1="100"
- 色を変える:
-
コメントを追加する
- 自分の言葉で理解したことをメモ
- 後で見返した時に思い出せる
-
エラーが出たら
- XMLのタグが閉じているか確認
-
<や>をエスケープしているか確認 - トークン名のスペルミスがないか確認
<dashboard version="1.1">
<label>0120しかくと線と斜め外船OKインデックスなしあとで見返す</label>
<description></description>
<!-- データ取得用の検索 (非表示) -->
<search id="line_data_search">
<query>
| makeresults count=1
| eval line_outer_top_status=case(random()%2==0, "ok", 1==1, "error"),
line_outer_right_value=random() % 100,
line_outer_bottom_count=random() % 20,
line_outer_left_status=case(random()%3==0, "down", 1==1, "up"),
line_diag_1_latency=random() % 200,
line_diag_2_bandwidth=random() % 100,
line_cross_h_traffic=random() % 2000,
line_cross_v_load=(random() % 100) / 100.0
| eval line_outer_top_color=if(line_outer_top_status=="error", "#FF0000", "#00FF00"),
line_outer_right_color=if(line_outer_right_value>80, "#FF0000", "#00FF00"),
line_outer_bottom_color=if(line_outer_bottom_count<10, "#FF0000", "#00FF00"),
line_outer_left_color=if(line_outer_left_status=="down", "#FF0000", "#00FF00"),
line_diag_1_color=if(line_diag_1_latency>100, "#FF0000", "#00FFFF"),
line_diag_2_color=if(line_diag_2_bandwidth<50, "#FF0000", "#00FFFF"),
line_cross_h_color=if(line_cross_h_traffic>1000, "#FF0000", "#FFFF00"),
line_cross_v_color=if(line_cross_v_load>0.8, "#FF0000", "#FFFF00")
| eval line_outer_top_width=if(line_outer_top_status=="error", "6", "4"),
line_outer_right_width=if(line_outer_right_value>80, "6", "4"),
line_outer_bottom_width=if(line_outer_bottom_count<10, "6", "4"),
line_outer_left_width=if(line_outer_left_status=="down", "6", "4"),
line_diag_1_width=if(line_diag_1_latency>100, "6", "4"),
line_diag_2_width=if(line_diag_2_bandwidth<50, "6", "4"),
line_cross_h_width=if(line_cross_h_traffic>1000, "6", "4"),
line_cross_v_width=if(line_cross_v_load>0.8, "6", "4")
| fields line_outer_top_status, line_outer_top_color, line_outer_top_width,
line_outer_right_value, line_outer_right_color, line_outer_right_width,
line_outer_bottom_count, line_outer_bottom_color, line_outer_bottom_width,
line_outer_left_status, line_outer_left_color, line_outer_left_width,
line_diag_1_latency, line_diag_1_color, line_diag_1_width,
line_diag_2_bandwidth, line_diag_2_color, line_diag_2_width,
line_cross_h_traffic, line_cross_h_color, line_cross_h_width,
line_cross_v_load, line_cross_v_color, line_cross_v_width
</query>
<refresh>5s</refresh>
<refreshType>delay</refreshType>
<done>
<set token="line_outer_top_color">$result.line_outer_top_color$</set>
<set token="line_outer_top_width">$result.line_outer_top_width$</set>
<set token="line_outer_right_color">$result.line_outer_right_color$</set>
<set token="line_outer_right_width">$result.line_outer_right_width$</set>
<set token="line_outer_bottom_color">$result.line_outer_bottom_color$</set>
<set token="line_outer_bottom_width">$result.line_outer_bottom_width$</set>
<set token="line_outer_left_color">$result.line_outer_left_color$</set>
<set token="line_outer_left_width">$result.line_outer_left_width$</set>
<set token="line_diag_1_color">$result.line_diag_1_color$</set>
<set token="line_diag_1_width">$result.line_diag_1_width$</set>
<set token="line_diag_2_color">$result.line_diag_2_color$</set>
<set token="line_diag_2_width">$result.line_diag_2_width$</set>
<set token="line_cross_h_color">$result.line_cross_h_color$</set>
<set token="line_cross_h_width">$result.line_cross_h_width$</set>
<set token="line_cross_v_color">$result.line_cross_v_color$</set>
<set token="line_cross_v_width">$result.line_cross_v_width$</set>
<set token="line_outer_top_status">$result.line_outer_top_status$</set>
<set token="line_outer_right_value">$result.line_outer_right_value$</set>
<set token="line_outer_bottom_count">$result.line_outer_bottom_count$</set>
<set token="line_outer_left_status">$result.line_outer_left_status$</set>
<set token="line_diag_1_latency">$result.line_diag_1_latency$</set>
<set token="line_diag_2_bandwidth">$result.line_diag_2_bandwidth$</set>
<set token="line_cross_h_traffic">$result.line_cross_h_traffic$</set>
<set token="line_cross_v_load">$result.line_cross_v_load$</set>
</done>
</search>
<row>
<panel>
<html>
<style>
/* ========================================== */
/* コンテナ (図形の親要素) */
/* ========================================== */
.container {
position: relative;
width: 600px;
height: 400px;
background: #f5f5f5;
margin: 30px;
}
/* ========================================== */
/* 四角形 (BOX) の共通スタイル */
/* ========================================== */
.box {
position: absolute;
width: 120px;
height: 80px;
border-radius: 10px;
color: white;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
z-index: 10;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
/* 左上 */
.box1 {
top: 20px;
left: 20px;
background: #42A5F5;
}
/* 右上 */
.box2 {
top: 20px;
right: 20px;
background: #4CAF50;
}
/* 左下 */
.box3 {
bottom: 20px;
left: 20px;
background: #FFA726;
}
/* 右下 */
.box4 {
bottom: 20px;
right: 20px;
background: #E53935;
}
/* ========================================== */
/* SVG (線を描画するためのキャンバス) */
/* ========================================== */
svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
/* ========================================== */
/* 線 (LINE) の共通スタイル */
/* ========================================== */
.line {
fill: none;
transition: stroke 0.5s ease, stroke-width 0.3s ease;
}
/* 対角線は破線 */
.line-diag {
stroke-dasharray: 8, 4;
}
</style>
<!-- ========================================== -->
<!-- HTML構造 (トークンで色と太さを動的に変更) -->
<!-- ========================================== -->
<div class="container">
<!-- SVGで線を描画 -->
<svg>
<!-- 外枠の線 (4辺) -->
<!-- 上辺: BOX1中央 → BOX2中央 -->
<line id="line-outer-top" class="line" x1="80" y1="60" x2="520" y2="60" stroke="$line_outer_top_color$" stroke-width="$line_outer_top_width$"/>
<!-- 右辺: BOX2中央 → BOX4中央 -->
<line id="line-outer-right" class="line" x1="520" y1="60" x2="520" y2="340" stroke="$line_outer_right_color$" stroke-width="$line_outer_right_width$"/>
<!-- 下辺: BOX4中央 → BOX3中央 -->
<line id="line-outer-bottom" class="line" x1="520" y1="340" x2="80" y2="340" stroke="$line_outer_bottom_color$" stroke-width="$line_outer_bottom_width$"/>
<!-- 左辺: BOX3中央 → BOX1中央 -->
<line id="line-outer-left" class="line" x1="80" y1="340" x2="80" y2="60" stroke="$line_outer_left_color$" stroke-width="$line_outer_left_width$"/>
<!-- 対角線 (串刺し) -->
<!-- 左上 → 右下 -->
<line id="line-diag-1" class="line line-diag" x1="80" y1="60" x2="520" y2="340" stroke="$line_diag_1_color$" stroke-width="$line_diag_1_width$"/>
<!-- 右上 → 左下 -->
<line id="line-diag-2" class="line line-diag" x1="520" y1="60" x2="80" y2="340" stroke="$line_diag_2_color$" stroke-width="$line_diag_2_width$"/>
<!-- 中央十字 -->
<!-- 水平線: 左中央 → 右中央 -->
<line id="line-cross-h" class="line" x1="80" y1="200" x2="520" y2="200" stroke="$line_cross_h_color$" stroke-width="$line_cross_h_width$"/>
<!-- 垂直線: 上中央 → 下中央 -->
<line id="line-cross-v" class="line" x1="300" y1="60" x2="300" y2="340" stroke="$line_cross_v_color$" stroke-width="$line_cross_v_width$"/>
</svg>
<!-- 4つの四角形 -->
<div class="box box1">BOX1</div>
<div class="box box2">BOX2</div>
<div class="box box3">BOX3</div>
<div class="box box4">BOX4</div>
</div>
</html>
</panel>
</row>
<!-- ========================================== -->
<!-- データ監視パネル (デバッグ用) -->
<!-- ========================================== -->
<row>
<panel>
<title>📊 線の状態データ (5秒ごとに自動更新)</title>
<table>
<search base="line_data_search"></search>
<option name="drilldown">none</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
<row>
<panel>
<title>🎯 現在の線の状態</title>
<html>
<style>
.status-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 15px;
padding: 20px;
background: #f9f9f9;
}
.status-item {
background: white;
border-left: 4px solid #42A5F5;
padding: 12px;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.status-label {
font-size: 11px;
color: #666;
font-weight: bold;
margin-bottom: 5px;
}
.status-value {
font-size: 16px;
font-weight: bold;
color: #333;
}
.status-color {
display: inline-block;
width: 20px;
height: 20px;
border-radius: 3px;
vertical-align: middle;
margin-left: 8px;
border: 1px solid #ccc;
}
</style>
<div class="status-grid">
<div class="status-item">
<div class="status-label">🔵 上辺 (line-outer-top)</div>
<div class="status-value">
$line_outer_top_status$
<span class="status-color" style="background: $line_outer_top_color$;"/>
</div>
</div>
<div class="status-item">
<div class="status-label">🟢 右辺 (line-outer-right)</div>
<div class="status-value">
$line_outer_right_value$%
<span class="status-color" style="background: $line_outer_right_color$;"/>
</div>
</div>
<div class="status-item">
<div class="status-label">🟠 下辺 (line-outer-bottom)</div>
<div class="status-value">
Count: $line_outer_bottom_count$
<span class="status-color" style="background: $line_outer_bottom_color$;"/>
</div>
</div>
<div class="status-item">
<div class="status-label">🔴 左辺 (line-outer-left)</div>
<div class="status-value">
$line_outer_left_status$
<span class="status-color" style="background: $line_outer_left_color$;"/>
</div>
</div>
<div class="status-item">
<div class="status-label">💠 対角線1 (line-diag-1)</div>
<div class="status-value">
$line_diag_1_latency$ms
<span class="status-color" style="background: $line_diag_1_color$;"/>
</div>
</div>
<div class="status-item">
<div class="status-label">💠 対角線2 (line-diag-2)</div>
<div class="status-value">
$line_diag_2_bandwidth$ Mbps
<span class="status-color" style="background: $line_diag_2_color$;"/>
</div>
</div>
<div class="status-item">
<div class="status-label">➖ 水平線 (line-cross-h)</div>
<div class="status-value">
Traffic: $line_cross_h_traffic$
<span class="status-color" style="background: $line_cross_h_color$;"/>
</div>
</div>
<div class="status-item">
<div class="status-label">| 垂直線 (line-cross-v)</div>
<div class="status-value">
Load: $line_cross_v_load$
<span class="status-color" style="background: $line_cross_v_color$;"/>
</div>
</div>
</div>
</html>
</panel>
</row>
</dashboard><!--
==========================================
実際の使用例
==========================================
例1: ネットワーク回線監視
index=network sourcetype=cisco:ios
| stats latest(link_status) as line_outer_top_status,
avg(bandwidth_util) as line_outer_right_value,
count(errors) as line_outer_bottom_count,
latest(interface_status) as line_outer_left_status
| eval line_outer_top_color=if(line_outer_top_status=="down", "#FF0000", "#00FF00"),
line_outer_right_color=if(line_outer_right_value>80, "#FF0000", "#00FF00"),
line_outer_bottom_color=if(line_outer_bottom_count<10, "#FF0000", "#00FF00"),
line_outer_left_color=if(line_outer_left_status=="down", "#FF0000", "#00FF00")
例2: サーバー間通信監視
index=app sourcetype=api_logs
| stats avg(response_time) as line_diag_1_latency,
avg(throughput_mbps) as line_diag_2_bandwidth
| eval line_diag_1_color=if(line_diag_1_latency>100, "#FF0000", "#00FFFF"),
line_diag_2_color=if(line_diag_2_bandwidth<50, "#FF0000", "#00FFFF")
==========================================
-->