Splunk Answersだと@niketnilayと@vnravikumarの記事を一通り読めばかなりのダッシュボードマスターになれる。
といいながらも、自分のダッシュボード関連の質問に答えることもあるので、そのために必要な情報をまとめておく
#HTML特殊文字列
http://www.eonet.ne.jp/~usakuma/hptec/hp_tec/hptec_style_41.htm
記述 | 表示 | 説明 |
---|---|---|
< |
< | 右大不等号 |
> |
> | 左大不等号 |
& |
& | アンドマーク(アンパサンド) |
" |
" | ダブルクォート(引用符) |
' |
' | シングルクォーテーション |
|
|
空白文字 |
tokenを使う時ってSimpleXMLのソースを書くことになるので、<eval token= が動かない時の理由はだいたいこれ。 |
||
SPLをただコピペするとこれに引っかかる。 | ||
eval の結果が出ない時ってnull やmultivalue だったりするけどSimpleXMLだとこれの時が多い。 |
||
#cssを簡単に | ||
splunk>answers |
<row depends="$hide$">
<panel>
<html>
<style>
#resized_input div[data-component="splunk-core:/splunkjs/mvc/components/Dropdown"]{
width: 500px !important;
}
</style>
</html>
</panel>
</row>
リンク先は各種inputがどのセパレーターで呼び出せるかがまとまっている。
#token
cf.[tokens@splunk>docs]
(https://docs.splunk.com/Documentation/Splunk/latest/Viz/tokens)
##finalized and done
Splunk Answersのテキサス親父@woodcockが最新版での挙動を調べてくれた。finalizeの挙動が変わって以前はdoneとほとんど一緒だったけど、ver8だと途中で結果が出るようになった。
#click.value
click.value一覧
普段使うのはクリックした時にそのフィールドの値をとる$click.name2$
や$click.value2$
が多いと思うけど自分の場合<field>
でよく限定するので別な方法を使うことが多い。
とりあえずは困ったら
Simple XML Reference
<dashboard>
<label>drilldowntime</label>
<init>
<unset token="epoch"></unset>
<unset token="human"></unset>
</init>
<row><panel><table>
<search>
<query>|makeresults|eval time=_time|table time</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
</search>
<drilldown>
<set token="epoch">$click.value2$</set>
<eval token="human">strftime($epoch$,"%F%T")</eval>
</drilldown>
</table></panel></row>
<row><panel><html>
<p><h2>$epoch$</h2></p>
<p><h2>$human$</h2></p>
</html></panel></row>
</dashboard>
これはdrilldownをそのままeval
で変換している。
複雑なことをするなら、隠しpanelを作ってそこでやればいいけど、単純なのはこのように変換。
#
https://www.atmarkit.co.jp/aig/01xml/cdata.html
<sample><![CDATA[x < 0の場合]]></sample>
<sample>x < 0の場合</sample>`
XMLの構文であることは初めて知りました。
XML内の構文には使えないのでHTML特殊文字列を使う必要がある。
#検索結果がない時の表示方法
<form>
<label>Single Value</label>
<fieldset submitButton="false">
<input type="radio" token="data" searchWhenChanged="true">
<label>Data</label>
<choice value="1">With Data</choice>
<choice value="0">Without Data</choice>
<initialValue>1</initialValue>
<default>1</default>
</input>
</fieldset>
<row>
<panel>
<single>
<search>
<done>
<condition match="'result.dummy' =="false"">
<set token="unit">GB</set>
</condition>
<condition>
<set token="unit"></set>
</condition>
</done>
<query>|makeresults |eval host="host1",FreeSpace=25|eval dummy="false"|where 1=$data$
|appendpipe
[| stats count
| eval FreeSpace="No event for this host"
| where count = 0
| eval dummy="true"
| table FreeSpace,dummy ]
</query>
<earliest>-15m</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
</search>
<option name="colorBy">value</option>
<option name="colorMode">block</option>
<option name="drilldown">none</option>
<option name="numberPrecision">0</option>
<option name="rangeColors">["0xdc4e41","0xf1813f","0xf8be34","0xdc4e41"]</option>
<option name="rangeValues">[0,30,70]</option>
<option name="refresh.display">progressbar</option>
<option name="showSparkline">0</option>
<option name="showTrendIndicator">1</option>
<option name="trendColorInterpretation">standard</option>
<option name="trendDisplayMode">absolute</option>
<option name="unit">$unit$</option>
<option name="unitPosition">after</option>
<option name="useColors">1</option>
<option name="useThousandSeparators">1</option>
</single>
</panel>
</row>
</form>
結果がない時appendpipe
の文字列を表示すると共に、そうじゃない時を<condition match=
で制御しているお手本のようなダッシュボード。
数値によって色も変えているし、いろいろと参考になる。
#loadjob
<dashboard>
<label>loadjob</label>
<row>
<panel>
<table>
<search>
<query>| makeresults | eval _raw="hi there"</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
<done><set token="sid">$job.sid$</set></done>
<done><set token="raw">$result._raw$</set></done>
</search>
<option name="drilldown">none</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<search>
<query>| loadjob $sid$ | eval message="loading the same results"</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
</search>
<option name="drilldown">none</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<search>
<query>| makeresults | eval message="get the info from the other panel via a token", _raw="$raw$"</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
</search>
<option name="drilldown">none</option>
</table>
</panel>
</row>
</dashboard>
一回検索しておいて、再活用したい時に使う。
summary indexみたいな使い方ができる。
loadjob
はsavedsearch=
の引数だとユーザとか指定できるので、ダッシュボードの閲覧権限を絞りたい時や集計結果からの再検索だと、このダッシュボードが参考になる。
#table width
https://community.splunk.com/t5/Dashboards-Visualizations/sparkline-length-width-out-of-control/m-p/514227/highlight/true#M34338
を参考に
<dashboard>
<label>Sparkline Width</label>
<row>
<panel>
<title>Sparkline Width with format option</title>
<table>
<search>
<query>index=_internal
| chart sparkline as trend count by sourcetype</query>
<earliest>-60m@m</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
</search>
<option name="count">100</option>
<option name="dataOverlayMode">none</option>
<option name="drilldown">none</option>
<option name="percentagesRow">false</option>
<option name="refresh.display">progressbar</option>
<option name="rowNumbers">false</option>
<option name="totalsRow">false</option>
<option name="wrap">true</option>
<!-- Set sparkline options here; make sure that field matches field name of the search results -->
<format type="sparkline" field="trend">
<option name="width">95%</option>
</format>
</table>
</panel>
</row>
<row>
<panel>
<title>CSS Overridden sparkline Width</title>
<html>
<style>
#tableWithSparklineWidth table thead th[data-sort-key="trend"]{
width: 75px !important;
}
</style>
</html>
<table id="tableWithSparklineWidth">
<search>
<query>index=_internal
| chart sparkline as trend count by sourcetype</query>
<earliest>-60m@m</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
</search>
<option name="count">100</option>
<option name="dataOverlayMode">none</option>
<option name="drilldown">none</option>
<option name="percentagesRow">false</option>
<option name="refresh.display">progressbar</option>
<option name="rowNumbers">false</option>
<option name="totalsRow">false</option>
<option name="wrap">true</option>
</table>
</panel>
</row>
</dashboard>
##解説
#tableWithSparklineWidth table thead th[data-sort-key="trend"]{
width: 75px !important;
}
theadはテーブルのヘッダー行
th[data-sort-key="<<Field名>>"]
で幅を指定できる。
sparkline
のオプションはここ
#table color
https://community.splunk.com/t5/Dashboards-Visualizations/Color-Code-Stats-table-by-row/m-p/514235/highlight/true#M34340
のまとめ
<dashboard>
<label>Table with color Based on Percent</label>
<row>
<panel>
<title>Color Ranges | 0-40: Red | 40-90: Yellow | 90+: Green</title>
<html depends="$alwaysHideHTMLCSSPanel$">
<style>
#tableColorFinalRowBasedOnData table tbody td div.multivalue-subcell[data-mv-index="1"]{
display: none;
}
</style>
</html>
<table id="tableColorFinalRowBasedOnData">
<search>
<query>| makeresults
| eval data="Total Stories,5,10,20;Stories Completed,5,0,10;% Completed,100%,0%,50%"
| makemv data delim=";"
| mvexpand data
| makemv data delim=","
| eval State=mvindex(data,0),Team1=mvindex(data,1),Team2=mvindex(data,2),Team3=mvindex(data,3)
| table State Team*
| foreach Team* [| eval "<<FIELD>>"=case(State="% Completed" AND
tonumber(substr('<<FIELD>>',1,len('<<FIELD>>')-1))>=0 AND
tonumber(substr('<<FIELD>>',1,len('<<FIELD>>')-1))<40 ,'<<FIELD>>'."|LOW",
State="% Completed" AND
tonumber(substr('<<FIELD>>',1,len('<<FIELD>>')-1))>=40 AND
tonumber(substr('<<FIELD>>',1,len('<<FIELD>>')-1))<90 ,'<<FIELD>>'."|MEDIUM",
State="% Completed" AND
tonumber(substr('<<FIELD>>',1,len('<<FIELD>>')-1))>=90,'<<FIELD>>'."|HIGH",
true(),'<<FIELD>>')]
| foreach Team* [| eval "<<FIELD>>"=split('<<FIELD>>',"|")]</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
</search>
<option name="count">100</option>
<option name="dataOverlayMode">none</option>
<option name="drilldown">none</option>
<option name="percentagesRow">false</option>
<option name="refresh.display">progressbar</option>
<option name="rowNumbers">false</option>
<option name="totalsRow">false</option>
<option name="wrap">true</option>
<format type="color" field="Team1">
<colorPalette type="expression">case (match(value,"LOW"), "#DC4E41",match(value,"MEDIUM"), "#F8BE34",match(value,"HIGH"),"#53A051")</colorPalette>
</format>
<format type="color" field="Team2">
<colorPalette type="expression">case (match(value,"LOW"), "#DC4E41",match(value,"MEDIUM"), "#F8BE34",match(value,"HIGH"),"#53A051")</colorPalette>
</format>
<format type="color" field="Team3">
<colorPalette type="expression">case (match(value,"LOW"), "#DC4E41",match(value,"MEDIUM"), "#F8BE34",match(value,"HIGH"),"#53A051")</colorPalette>
</format>
</table>
</panel>
</row>
</dashboard>
##解説
クエリーでHIGH``MEDIUM``LOW
の値をマルチバリューとして作っている。
Team1 |
---|
50 MEDIUM |
それをCSSのtable tbody td div.multivalue-subcell[data-mv-index="1"]{ display: none;}
で2番目を表示しないようにしている。
そして、
<format type="color" field="Team1">
<colorPalette type="expression">case (match(value,"LOW"), "#DC4E41",match(value,"MEDIUM"), "#F8BE34",match(value,"HIGH"),"#53A051")</colorPalette>
</format>
match()
を利用して、色を指定している。value
でフィールドの値を持ってこれる。
いや〜すごい
#Drilldown
<dashboard>
<label>drilldown_multi</label>
<init>
<unset token="url"></unset>
<unset token="url2"></unset>
</init>
<row>
<panel>
<table id="tableMulti">
<search>
<query>| makeresults
| eval A="someurl1",B="someurl2",C="someurl3",A_name="somename1",B_name="somename2",C_name="somename3"
| eval As = mvappend(A,A_name)
| eval Bs = mvappend(B,B_name)
| eval Cs = mvappend(C,C_name)
| table As Bs Cs
| nomv As | nomv Bs |nomv Cs</query>
<earliest>0</earliest>
<sampleRatio>1</sampleRatio>
</search>
<option name="count">50</option>
<option name="dataOverlayMode">none</option>
<option name="drilldown">cell</option>
<option name="percentagesRow">false</option>
<option name="rowNumbers">false</option>
<option name="totalsRow">false</option>
<option name="wrap">true</option>
<drilldown>
<eval token="url">$click.value2$</eval>
<eval token="url2">replace($url$,".*$","")</eval>
</drilldown>
</table>
</panel>
</row>
<row><panel><html><p>$url$</p><p>$url2$</p></html></panel></row>
</dashboard>
https://community.splunk.com/t5/Dashboards-Visualizations/How-can-I-parse-the-URL-from-cell-in-Drilldown/m-p/533634#M36346
用に作ってみた。
##解説
マルチバリューのセルの値の片方をDrilldownしたい場合、通常$clieck.value2$
だと、値をそのまま取ってしまうので、勝手が悪い。
このように|nomv XX
してあげると表示はきちんと2つ見えるけどDrilldownは2つの値が合わさった形で取れる。
それをreplace()
を利用して($token$,".*$","")
だと上の値、($url$,"^.*","")
だと下の値がDrilldownで持っていける。
nomv
がなんで文字列を区切ってシングルにしているかはよくわかりませんでした。
#トークンの初期化
<form>
<label>multi dynamic select</label>
<search id="base_csv">
<query>| inputlookup geo_attr_us_states.csv
| rex field=state_name "(?<Capital>\w)"
</query>
<earliest>0</earliest>
<latest></latest>
</search>
<fieldset submitButton="false">
<input type="dropdown" token="field1">
<label>field1</label>
<fieldForLabel>Capital_string</fieldForLabel>
<fieldForValue>Capital</fieldForValue>
<search base="base_csv">
<query>| stats values(Capital) as Capital |mvexpand Capital | eval Capital_string=Capital</query>
</search>
<change>
<condition>
<unset token="field3"></unset>
</condition>
</change>
</input>
<input type="dropdown" token="field2">
<label>field2</label>
<fieldForLabel>state_code_name</fieldForLabel>
<fieldForValue>state_code</fieldForValue>
<search base="base_csv">
<query>| search Capital="$field1$"
| table state_code
| eval state_code_name=state_code</query>
</search>
</input>
<input type="multiselect" token="field3" searchWhenChanged="true">
<label>field3</label>
<search base="base_csv">
<query>| search Capital="$field1$"
| table state_code
| eval state_code_name=state_code</query>
</search>
<valuePrefix>"</valuePrefix>
<valueSuffix>"</valueSuffix>
<delimiter>,</delimiter>
<fieldForLabel>state_code_name</fieldForLabel>
<fieldForValue>state_code</fieldForValue>
</input>
</fieldset>
<row>
<panel>
<table>
<search base="base_csv">
<query>| search state_code IN ($field3$)</query>
</search>
</table>
</panel>
</row>
</form>
##解説
<input>
のところで<condition>
が使えるとは知らなかった。
CSVの頭文字を選択したところで、トークンを初期化している。
マルチセレクトを全部削除するボタンはjavascriptが必要
https://community.splunk.com/t5/Dashboards-Visualizations/Remove-quot-All-quot-from-Multiselect-Input-in-Dashboard/m-p/301375
ということで、トークン初期化だけでいいかな〜としています。
| search state_code IN ($field3$)
も結構キモだったりする。
#タイムピッカーの値を変更する。
##検証
<label>timerange_check</label>
<fieldset submitButton="false" autoRun="false">
<input type="time" token="field1" searchWhenChanged="true">
<label></label>
<default>
<earliest>-24h@h</earliest>
<latest>now</latest>
</default>
</input>
</fieldset>
<row>
<panel>
<title>addinfo</title>
<table>
<search>
<query>| makeresults
| addinfo</query>
<earliest>$field1.earliest$</earliest>
<latest>$field1.latest$</latest>
<done>
<!-- set time tokens-->
<set token="time_min">$result.info_min_time$</set>
<set token="time_max">$result.info_max_time$</set>
</done>
</search>
<option name="drilldown">none</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
<row>
<panel>
<title>time_picker original</title>
<table>
<search>
<query>| makeresults | eval info_min_time="$time_min$"
| eval info_max_time="$time_max$" | convert ctime(info_min_time) as human_min ctime(info_max_time) as human_max
| table info_min_time human_min info_max_time human_max</query>
<earliest>0</earliest>
<latest></latest>
</search>
<option name="drilldown">none</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
<row>
<panel>
<title>-3h</title>
<table>
<search>
<query>| makeresults
| eval relative_min=if($time_min$=0,relative_time(now(),"-3h"),relative_time("$time_min$","-3h"))
| eval relative_max=if("$time_max$"="+Infinity",now(),relative_time("$time_max$","-3h"))
| convert ctime(relative_min) as human_r_min ctime(relative_max) as human_r_max
| table relative_min human_r_min relative_max human_r_max</query>
<earliest>0</earliest>
<latest></latest>
</search>
<option name="drilldown">none</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
</form>
このダッシュボードでいろいろとタイムピッカーを変更してみる。
すると、全時間のところを気をつけないとトークンで持っていくことが難しいことがわかる。
| eval relative_min=if($time_min$=0,relative_time(now(),"-3h"),relative_time("$time_min$","-3h"))
| eval relative_max=if("$time_max$"="+Infinity",now(),relative_time("$time_max$","-3h"))
このように、EpochTimeじゃない値が来た場合の条件を書いておく必要がある。
このパネルを非表示にして、作った値を他のパネルに持っていけばいい。
##参考ダッシュボード
<form>
<label>timerange_check</label>
<fieldset submitButton="false" autoRun="false">
<input type="time" token="field1" searchWhenChanged="true">
<label></label>
<default>
<earliest>-24h@h</earliest>
<latest>now</latest>
</default>
</input>
</fieldset>
<row>
<panel depends="$allwaysHide$">
<table>
<!-- make 3hours before time token -->
<search>
<query>| makeresults
| addinfo
| eval relative_min=if(info_min_time=0,relative_time(now(),"-3h"),relative_time(info_min_time,"-3h"))
| eval relative_max=if(info_max_time="+Infinity",now(),relative_time(info_max_time,"-3h"))
| convert ctime(relative_min) as human_r_min ctime(relative_max) as human_r_max
| table relative_min human_r_min relative_max human_r_max</query>
<earliest>$field1.earliest$</earliest>
<latest>$field1.latest$</latest>
<done>
<!-- set time tokens of 3hours before -->
<set token="time_min">$result.relative_min$</set>
<set token="time_max">$result.relative_max$</set>
</done>
</search>
</table>
</panel>
</row>
<row>
<panel>
<title>search -3h before</title>
<chart>
<!-- It displays the chart before 3hours -->
<search>
<query>| tstats count where index=_internal earliest=$time_min$ latest=$time_max$ by _time span=1h</query>
<earliest>0</earliest>
<latest></latest>
</search>
<option name="charting.chart">line</option>
<option name="charting.drilldown">none</option>
</chart>
</panel>
</row>
</form>
#panelのtitleを中央揃え
<dashboard>
<label>single_test</label>
<init>
<unset>$labels$</unset>
</init>
<row>
<panel id="tables2">
<title>$titles$</title>
<single>
<search>
<query>| tstats count where index=_internal sourcetype=splunkd by PREFIX("name=")
| sort 1 - count
| rename name= as name
| eval {name}=count
| table * name count
</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
<done>
<set token="titles">$result.name$</set>
</done>
</search>
<option name="drilldown">all</option>
<option name="refresh.display">progressbar</option>
<drilldown>
<set token="labels">$row.name$</set>
</drilldown>
</single>
</panel>
<panel id="tables1">
<html>
<style>
#tables1 {
width: 75% !important;
}
#tables2 {
width: 25% !important;
}
#tables2 .panel-title {
font-size: 32px !important;
padding: 12px 12px 7px 12px !important;
display: flex;
justify-content: center;
font-weight: bold !important;
}
</style>
<p>$labels$</p>
</html>
</panel>
</row>
</dashboard>
##解説
.panel-title {
font-size: 32px !important;
padding: 12px 12px 7px 12px !important;
display: flex;
justify-content: center;
font-weight: bold !important;
}
-
<title></title>
のクラス名は.panel-title
- フォントサイズはpx設定だといい感じになった。
-
padding
はデフォルトだと左に寄っているので変更必須。 -
display: flex;
とjustify-content: center;
で中央にそろってくれる。
#動的にパネルの幅を変える。
R3.2.23追記
CSSの値をtokenで変更してみる。
<form>
<label>hide_panel_width</label>
<init>
<set token="width_change">100</set>
<set token="Viz">0</set>
<set token="panel1">0</set>
</init>
<fieldset submitButton="false">
<input type="checkbox" token="width_change" searchWhenChanged="true">
<label>Width Change</label>
<choice value="85">width_change<set token="Viz">1</set>
<set token="pane1">15</set>
</choice>
<default>100</default>
</input>
</fieldset>
<row>
<panel depends="$alwaysHidePanel$">
<html>
<style>
#Table1{
width:$width_change$% !important;
}
#Panel1{
width:$panel1$% !important;
}
</style>
</html>
</panel>
</row>
<row>
<panel id="Table1">
<chart>
<search>
<query>| tstats count where index=_internal by _time span=1h</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
<sampleRatio>1</sampleRatio>
</search>
<option name="charting.chart">column</option>
<option name="charting.chart.stackMode">default</option>
<option name="charting.chart.style">shiny</option>
<option name="charting.drilldown">none</option>
</chart>
</panel>
<panel id="Panel1" depends="$Viz$">
<single>
<search>
<query>| tstats count where index=_internal by _time span=1h sourcetype
| rare 1 sourcetype</query>
<earliest>$earliest$</earliest>
<latest>$latest$</latest>
</search>
<option name="refresh.display">progressbar</option>
</single>
</panel>
</row>
</form>
init
とdefault
でチェックボックスを外すと、100%の表示になってくれる。
#まとめ
デザインのセンスが無いのであんまり気持ちが入っていかないダッシュボード周り。
今後もここで更新していきます。