Splunk サマリーインデックス (summary index) の研究  collect vs si-commands (sistats)

# 伝えたいこと

Splunkにはサマリーインデックスへのデータ格納方法が（少なくとも）２通りあります。
- collectコマンドによる格納
- sistatsなどsummary index用の前処理を行ってくれるコマンドを併用しながら、summaryindexコマンドによる格納

※ collectの前にsistatsを利用することも可能です。

良し悪しを理解して、取捨選択をすればよいと考えています。

日本語の記事でこの違いを簡潔にまとめているものをパッと探せなかったので、自分の備忘録も兼ねてまとめます。


# collectコマンド

https://docs.splunk.com/Documentation/Splunk/9.0.4/SearchReference/Collect

このコマンドはSPLの末尾につけて利用されることが多いです。
直前の |(パイプ)までの処理結果にサマリーインデックスフィールドを追加しながら、指定したサマリーインデックスにデータを格納します。

sourcetype=stashであれば、Splunkライセンスはかかりません。sourcetype=stashはデフォルトです。
事前に作成しておいたindexに格納できます。

ポイントは時刻（タイムスタンプ）です。
デフォルトでは、そのcollectコマンドを実行した結果データ(`_raw`)から自動でタイムスタンプのフィールドを拾い、一番最初に見つかったタイムスタンプフィールドに`_time`を与えます。 `_time`とはSplunkにおいてログの検索時刻幅を指定する際に参照される時刻フィールド名です。

collectコマンドのオプション addinfo=true (デフォルト)の場合、以下の３つの時刻フィールドが付与されます。
info_min_time=　検索タイムレンジのearliest
info_max_time=　検索タイムレンジのlatest
info_search_time= サーチ実行時刻

そして、これらのinfo_フィールドは _rawの最初に付与されるため、多くの場合デフォルトでは、**info_min_timeを_timeとして拾ってしまいます。**
これを防ぐ解決策としては２通りあります。

### info_min_timeを_timeに拾わない解決策① addinfo=false

addinfo=falseにすると、上の3つのinfo_フィールドは_rawに出力されません。
その場合は、サーチ結果の_rawの中からepoc timeの時刻情報を持つフィールドを探し、最初に見つかったフィールドの値が_timeに代入されます。

以下のようにstatsなどで何も時刻情報を残さなければ、サーチ実行時間が _timeフィールドに格納されました。

```
| makeresults
| eval sample = "collect test (addinfo=false)"
| stats count by sample
| collect index=summary addinfo=false addtime=true testmode=false run_in_preview=true
```

Splunk Enterpriseで検証した際は、サーチ実行時間を参照してサマリインデックスデータの`_time`が生成されていましたが、Splunk Cloudで試すとaddinfo=falseにしたにも関わらず `info_min_time`を参照し`_time`が作成されていました。
Splunk Cloudの仕様は、ブラックボックスな部分も多く、よくわからないことが多いです。

### info_min_timeを_timeに拾わない解決策② _timeフィールドを残す

わかりやすいように addinfo=trueを残しています。
addinfoはtrueがデフォルトのため、指定しなくても同じ動作をします。

```
| makeresults
| eval sample = "collect test (_time is left) "
| stats count by sample
| eval _time = now()
| collect index=summary addinfo=true addtime=true testmode=false run_in_preview=true
```
この場合、evalで指定した `_time`のフィールドがaddtime=trueにより、サマリインデックスデータの`_raw`の先頭に追加されるため、 サマリインデックスデータの `_time`には元のクエリのnow()、つまりサーチ実行時間を渡せます。

次は sistatsなどsi-コマンドの説明です。

# sistatsなどsi-コマンド

https://docs.splunk.com/Documentation/Splunk/9.0.4/SearchReference/Sistats
https://docs.splunk.com/Documentation/Splunk/9.0.4/SearchReference/Sitimechart

サマリインデックスに格納されるデータを準備するためのコマンドとして
`sistats,sitimechart,sichart, sitop, sirare` があります。

collectはSPL実行のみでサマリインデックスへの格納ができました。
そしてcollectでサマリインデックスに格納する場合、stats max(*)などの処理をしてからcollectすると max(*)のフィールドが飛んでしまう時があります。
そのような場合、事前にsistats max(*)としておくとフィールドが保持されます。

通常、サマリインデックスに格納するには、レポート(saved search)を作成し、スケジュールサーチに登録します。savedsearches.confに最低限、以下のオプションを追加します。

```
action.summary_index = 1 (　yes,on　なども可。enableのシノニムであればOK)
action.summary_index._name=summary (サマリインデックス名。summaryというインデックス名の例)
```

http://docs.splunk.com/Documentation/Splunk/latest/Admin/Savedsearchesconf

すると、savedsearchにて実行される実際のコマンドには summaryindexへの格納を処理するsummaryindexコマンドが自動追加されています。
この場合もデフォルトではsourcetype=statshになるようです。

例
レポート保存したSPL
```
| makeresults
| eval sample = "sistats test"
| sistats count by sample 
```

savedsearchにて実際に処理されたSPL
```
| makeresults
| eval sample = "sistats test"
| sistats count by sample | summaryindex spool=t uselb=t addtime=t index="summary" file="RMD505cb2a7407d93fed_554869815.stash_new" name="sistats test" marker=""
```
ただ、Splunk Enterprise(9.0)では、このようなクエリ結果が確認できたのですが、
Splunk Cloudですと、summaryindexコマンドの記録を確認することができませんでした。

また、savedsearches.confへの登録はWebUIでも行えます。
https://docs.splunk.com/Documentation/Splunk/9.0.4/Knowledge/Setupsummaryindexes
Appsごとの「レポート」タブからではなく、全体のSplunk「設定」から以下の設定を行います。
```
Steps to enable a search for summary events indexing
1. Select Settings > Searches, Reports, and Alerts.
2. Locate the report that you created and scheduled. Select Edit > Edit Summary Indexing.
3. Select Enable Summary Indexing.
```
この場合、スケジュールサーチへの登録が必須になります。

sistatsの際のタイムスタンプですが、デフォルト処理は collectコマンドでいう
addinfo=true addtime=trueと同じです。追加で`search_now`というサーチ実行時間を指すフィールドが追加されます。
よって、上記②の方法でオリジナルイベントのタイムスタンプをサマリインデックスデータに残すことができました。

# まとめ

collectコマンドだとうっかり編集中に実行されてしまって、ノイズがサマリインデックスに格納されてしまったという方もいらっしゃるのではないでしょうか？

その場合は、si-commandしておいてsavedsearchのサマリインデックス機能で対応する方が安全かもしれません。

またcollectのtestmodeオプションをtrueに設定すれば、実行結果はサマリインデックスには登録されないため、それも利用してみるとよいでしょう。
collectのtestmodeオプションはデフォルトはfalseです。


# 参考

https://blog.avotrix.com/sistats-sichart-and-sirare-splunk-commands/

https://community.splunk.com/t5/Knowledge-Management/Confused-with-the-usage-of-si-commands/m-p/242001

https://qiita.com/toshikawa/items/44f5903cafff5645e087

以上です。ご一読ありがとうございました。