0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Splunk: 統計値が2倍になる?マルチバリューのカウントと検索に関する注意点

Posted at

たまたま発生したのでメモ。

実施環境: Splunk Free 8.2.2
発生した事象

以下のようなデータを考えます。

STR
AAA AAA
Splunk
| makeresults count=1
| eval STR = "AAA,AAA"
| makemv delim="," STR

スクリーンショット 2022-02-06 22.27.03.png

これについて stats コマンドの count 関数を使用して件数を集計すると、1という結果が出ます。

Splunk
| makeresults count=1
| eval STR = "AAA,AAA"
| makemv delim="," STR
| stats count

スクリーンショット 2022-02-06 22.27.36.png

では、以下のように BY で STR 毎の件数を集計するとどうなるでしょうか。
普通に考えれば、先ほどと同じく1となるように思われます。

Splunk
| makeresults count=1
| eval STR = "AAA,AAA"
| makemv delim="," STR
| stats count BY STR

ところが、実際に動かしてみると以下のようになります。

スクリーンショット 2022-02-06 22.28.11.png

先ほどと異なり、結果は__「2」__になります。
なぜこのようなことが起こるのでしょうか。

原因

原因は、「マルチバリュー」にあります。
stats コマンドで BY を指定した際、同コマンドは「個別の値ごとに1つの行を返す」のですが、マルチバリューは含まれる値全てセットで「個別の値」ではなく、含まれる値__それぞれが__「個別の値」として扱われます。
すなわち、上記の例を用いると、

STR = AAA, AAA

ではなく、

STR = AAA, STR = AAA

といった感じになるのです。

検索での動作を見るとわかりやすいです。
マルチバリューでない「 AAA , AAA 」は「 AAA 」とは異なるので検索でヒットしません。

Splunk
| makeresults count=1
| eval STR = "AAA,AAA"
| where STR = "AAA"

スクリーンショット 2022-02-13 13.53.39.png

しかしこれをマルチバリューにすると、「 AAA 」でヒットするようになります。
これは、「 STR 」の値が「 AAA , AAA 」ではなく「 AAA 」と「 AAA 」だからです。

Splunk
| makeresults count=1
| eval STR = "AAA,AAA"
| makemv delim="," STR
| where STR = "AAA"

スクリーンショット 2022-02-13 13.54.35.png

マルチバリューの値を異なるものにすると、もっとわかりやすくなります。
以下の例をご覧下さい。

Splunk
| makeresults count=1
| eval STR = "AAA,BBB"
| makemv delim="," STR
| where STR = "AAA" AND STR = "BBB"

スクリーンショット 2022-02-13 13.55.24.png

「 STR が AAA かつ STR が BBB 」は普通に考えれば矛盾した条件であり、1件もヒットするはずはありません。
ですが、マルチバリューにおいては

STR = AAA, STR = BBB

すなわち、「 STR が AAA という値と BBB という値を同時にとる」という状況が発生するため、検索にヒットしてしまいます。

対処方法

マルチバリューを使用しないのが一番の対処法ですが、 collect コマンドで重複するフィールドを定義してしまった場合など、実際は思わぬ動作でマルチバリューが発生してしまうことがあります。
そのような状況へのシンプルな対処法として、 stats コマンドや timechart コマンドの dedup_splitvals オプションを true にするというのがあります。
このオプションはデフォルトでは false なのですが、これを true にするとマルチバリュー内での重複を排除してくれます。

Splunk
| makeresults count=1
| eval STR = "AAA,AAA"
| makemv delim="," STR
| stats dedup_splitvals=true count BY STR

スクリーンショット 2022-02-13 14.04.11.png

または、 eval コマンドの mvdedup 関数を使用するという方法もあります。
こちらもマルチバリュー内部での重複を排除する効果があります。

Splunk
| makeresults count=1
| eval STR = "AAA,AAA"
| makemv delim="," STR
| eval STR_TMP = mvdedup(STR)
| stats count BY STR_TMP

スクリーンショット 2022-02-13 14.06.26.png

ただし、上記はあくまで重複の排除なので、異なる値がマルチバリューとして同時に入っている場合は対応できません。

Splunk
| makeresults count=1
| eval STR = "AAA,BBB"
| makemv delim="," STR
| stats dedup_splitvals=true count BY STR

スクリーンショット 2022-02-13 14.08.14.png

このような場合は、マルチバリューを nomv コマンドで結合して、全てセットで「個別の値」として扱うことで対応可能です。

Splunk
| makeresults count=1
| eval STR = "AAA,BBB"
| makemv delim="," STR
| nomv STR
| stats count BY STR

スクリーンショット 2022-02-13 14.09.46.png

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?