調べる機会があったのでメモ。
実施環境: Splunk Free 8.2.2
事象
Splunk の重複削除コマンドといえば、dedup コマンドをよく使用します。
では、 dedup コマンドは重複したイベントについて、どのイベントを残し、どのイベントを削除するのでしょうか。
以下の例を見ると、 dedup コマンドは「最新のログを残す」ように見えます。
Splunk
index="_internal" sourcetype="splunkd" source="*/splunkd.log" log_level="INFO"
event_message = "*tracker.log*"
| table _time, event_message
Splunk
index="_internal" sourcetype="splunkd" source="*/splunkd.log" log_level="INFO"
event_message = "*tracker.log*"
| dedup event_message
| table _time, event_message
ただ、ここに sort コマンドを入れると、少々事情が変わってきます。
Splunk
index="_internal" sourcetype="splunkd" source="*/splunkd.log" log_level="INFO"
event_message = "*tracker.log*"
| sort _time
| table _time, event_message
Splunk
index="_internal" sourcetype="splunkd" source="*/splunkd.log" log_level="INFO"
event_message = "*tracker.log*"
| sort _time
| dedup event_message
| table _time, event_message
なんと、動きが「最古のログを残す」に変わってしまいました。
原因
なぜこのようなことが起こるのか。
dedup コマンドが残すイベントは「最新のログ」ではなく、「一番先頭のログ」だからです。
例えば、以下のような並べ替えをすると、中途半端な時間のログを dedup の結果として抜き出すことも可能です。
Splunk
index="_internal" sourcetype="splunkd" source="*/splunkd.log" log_level="INFO"
event_message = "*tracker.log*"
| streamstats count AS CNT
| eval SORT = ( CNT + 5 ) % 10
| sort SORT
| table SORT, _time, event_message
Splunk
index="_internal" sourcetype="splunkd" source="*/splunkd.log" log_level="INFO"
event_message = "*tracker.log*"
| streamstats count AS CNT
| eval SORT = ( CNT + 5 ) % 10
| sort SORT
| dedup event_message
| table SORT, _time, event_message
特に、ログのリカバリや転送で同じ日時のイベントが複数存在しうる場合等は、インデックスへの格納時間等何らかの値で並び替えを行わないと思わぬログが残されてしまう可能性があるため、注意が必要です。