##概要
サブサーチの結果を元に、時間を絞って検索したい時がままある。
サブサーチ結果をreturn
で返す時、書き換えてearliest
とlatest
を追記して検索させる。
(2019/12/26追記)あとはformat
を使用してearliest
とlatest
を返してやる方法もある。
(2020/01/22追記)format
を使用して文字列からearliest
とlatest
をつくる方法もある。
(2020/05/06追記)format
を使用したあと、earliest
とlatest
をくっつける方法もある。
(2020/05/18追記)単純にサブサーチのイベントの時間の前後10分間を検索を追記
(2021/01/17追記)サブサーチで値だけ戻してやるを追記
##構文
index=_internal
[search index=_internal name=management
| eval time_args="earliest=@m latest=-10s"
| return $time_args thread]
##解説
- 検索自体は適当
- _time_args_に時間指定を入力、今回は1分前から10秒前までにしてみた。
-
return
で時間および検索フィールドを指定 -
return
の結果は_search_フィールドに入っている - メインサーチに戻してあげる
searchの中身
search |
---|
earliest=@m latest=-10s thread="webui" |
過去60分で検索したが、サブサーチの結果を受け、サーチ期間が狭まっている。
Your timerange was substituted based on your search string
とジョブ結果にもでている。
##応用
今回は時間指定を固定値で実施したけど、
eval time_args="earliest=".<<検索時間フィールド>>." "."latest=".<<検索時間フィールド>>
と動的に作成してもいいと思う。earliestとlatestを参考に。
-1m_とかepoch時間でも渡せるので、
[06/Jun/2019:09:00:00 +0900]
とかをstrptime
の"%d/%b/%Y:%H:%M:%S"_でepoch時間に直して渡してあげてみるとか
relative_time
で1分前の時間を作ってみるとか
ログが入っていないので、具体例を作れない・・・
##formatを使用
format@splunk>docs
例文
format [mvsep="<mv separator>"] [maxresults=<int>] ["<row prefix>" "<column prefix>" "<column separator>" "<column end>" "<row separator>" "<row end>"]
###単純にサブサーチのイベントの時間の前後10分間を検索
index=_internal sourcetype=splunkd_ui_access
[ search index=_audit "_internal"
| eval earliest=relative_time(_time,"-5min@min"), latest=relative_time(_time,"+5min@min")
| streamstats count
| where count=1 OR count=100
| fields earliest latest
| format]
単純に時間だけ渡したい場合は、fields
とformat
で十分
###過去の検索期間の上位2つを10分前〜5分前の間で検索
index=_internal [search index=_internal name=management
| top 2 thread showcount=f showperc=f
| mvcombine thread
| eval earliest=relative_time(now(),"-10m@m") ,latest=relative_time(now(),"-5m@m")
| format "(" "" "" "" "" ")"]
####解説
今回は
|row prefix| column prefix|column separator|column end|row separator|row end|(参考)mvsep|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|(|||||)|OR|
- _row separator_は
thread |
---|
archivereader |
batchreader0 |
callbackrunnerthread |
の各項を何で繋いでやるか。defaultだとOR
なので
thread="archivereader" OR thread="batchreader0" OR thread="callbackrunnerthread"
となっているはず。
-
_column separator_は2つ以上のフィールドをメインサーチに渡す場合、各フィールドを何で繋いでやるかということ。
A NOT B
とか書くとき使う。 -
_column_prefix_はフィールドの頭につける文字列。これまた
NOT
とかで使えると思う
format
はmultivalueフィールドと通常のフィールドの接続子を別に設定できるので、メインサーチに戻してやるフィールドはマルチバリューにしてあげると今回のように接続子に悩まなくてよくなる。
##サブサーチで値だけ戻してやる
index=_internal splunkd component=*| head 20
| eval earliest=_time, latest=_time+60
| table component earliest latest
| rename component as search
| format "(" "" "" "" ") OR (" ")"
一つのフィールドの値と検索期間を戻す時は、table
でフィールドを限定して、rename
で_search_にしてあげて、format
してあげるといい感じになる。
rename
しないと、field名=値
でメインサーチに戻る。
##formatの後に検索期間をくっつける
index=_internal [ search index=_internal
| stats count by sourcetype
| dedup sourcetype
| fields - count
| format
| addinfo
| eval earliest=relative_time(info_min_time,"+5h"), latest=relative_time(info_max_time,"-4h")
| eval search=search." ( earliest=".earliest." latest=".latest.")"]
複数の列をメインサーチに戻してやる場合、format
の後に検索期間をくっつける方が楽なことに気がついた。
_epoch time_を作ってあげれば問題がないと思う。
####ダッシュボードむけ
index=hoge [| makeresults
| eval earliest="1/22/2020:08:00:00"
| eval earliest=strptime(earliest,"%m/%d/%Y:%T")
| eval latest=relative_time(earliest,"+10m")
| format "(" "" "" "" "" ")"]
earliest
のところに文字列を入れてあげると、そこから10分間のログを検索するクエリー。
どの道strptime
で変換してあげるので条件は適宜。
ダッシュボードだと<condition>
とかでeval
が使えるので、実際はクエリーにする必要はないかもしれないけど、クエリーにしておくと、パネルで修正ができるという利点がある。
<panel depends="$hide$">
にしておけば、使用する際は見えないし。
#横断検索
index=hoge [search index=hoge sourcetype=hogehoge BAD
| eval search="earliest=".relative_time(_time,"-5s")." latest=".relative_time(_time,"+5s")
| table search
| head 1]
例はないけど、検索期間ひろめでなんか悪いこと見つよう。
見つけたときはその付近のログを横断的にみましょうね〜というクエリ
複数のログが出そうなときは
eventstats earliest(_time) as earliest latest(_time) as latest
とかでつくった時間をもとに検索するといいと思います。
#まとめ
サブサーチは結局_search_フィールドの値をメインサーチに戻してやっている。
format
やreturn
を使えば値は確認できるので、うまく行かないなってときはサブサーチ自体の値を確認すればなんとかできると思います。
検索期間の変化は応用ですね。earliest=
やlatest=
の接続にAND
やOR
を使えないので。