1
2

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: 条件付きカウントの方法、またはcount関数内におけるevalの使用について

Posted at

時々使うのでメモ。

実施環境: Splunk Free 8.2.2
目的

Splunk の stats コマンドでは、 count 関数を使用することでデータの個数を集計することができます。
また、 BY 句を指定することによって指定のフィールドの値ごとに分けた個数を取得することもできます。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| stats count BY NUM

スクリーンショット 2021-12-12 22.02.12.png

では、「あるフィールドが特定の値であるデータの個数」が欲しい場合はどうすればよいでしょうか。
「特定の値」が単一の値である場合は、以下のように stats コマンドの前か後で where コマンドを使用して対象データを抜き出せば取得できます。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| where NUM = 0
| stats count BY NUM

スクリーンショット 2021-12-12 22.01.30.png

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| stats count BY NUM
| where NUM = 0

スクリーンショット 2021-12-12 21.43.37.png

ただ、少々冗長な気がしますし、何よりこれだと複雑な条件には対応できません。

基本

では、どうすればよいでしょうか。
実は、 stats コマンドの count 関数では、「eval(フィールド名=値)」という表現を用いることで、フィールドが特定の値であるデータのカウントを行うことが可能です。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| stats count(eval(NUM = 0)) AS NUM0

スクリーンショット 2021-12-12 21.45.48.png

なお、この条件付きカウントで得られる集計値は、必ず AS 句を用いてリネームする必要があります。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| stats count(eval(NUM = 0))

スクリーンショット 2021-12-12 21.46.51.png

応用

この条件付きカウントの条件には、 AND や OR も使用できます。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| stats count(eval(NUM = 1))            AS NUM1,
        count(eval(NUM = 2))            AS NUM2,
        count(eval(NUM = 1 OR NUM = 2)) AS NUM12

スクリーンショット 2021-12-12 21.48.24.png

また、 eval コマンドで使用できる様々な関数も使用可能です。

Splunk
| makeresults count=10000
| eval NUM = if(random() % 2 = 0, null(), 3)
| stats count(eval(isnull(NUM)))       AS NULL,
        count(eval(NUM = round(pi()))) AS NUM3

スクリーンショット 2021-12-12 21.54.32.png

複数のフィールドを使用した条件も作れます。

Splunk
| makeresults count=10000
| eval NUM1 = random() % 10,
       NUM2 = random() % 10
| stats count(eval(NUM1 = NUM2)) AS NUM12

スクリーンショット 2021-12-12 21.56.30.png

なお、あまり複雑な条件を入れてしまうと、非常に読みにくい SPL 文となる可能性があります。
そのような際は以下のように、 stats コマンドの前で条件が成立するなら 1 、それ以外は 0 を示すフラグフィールドを作り、その合計をとるようにすると整理しやすいです。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| eval FLG = if(NUM = 0, 1, 0)
| stats count(eval(NUM = 0)) AS NUM0,
        sum(FLG)             AS FLG0

スクリーンショット 2021-12-12 21.59.30.png

補足

この条件付きカウントの方法は、 stats コマンド以外でも使用できます。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| timechart span=1h count(eval(NUM = 0)) AS NUM0

スクリーンショット 2021-12-19 14.24.50.png

また、 count 以外の関数でも使用できます。
ただし、 count 以外の関数では eval 単体だとうまく動作しません。
eval は「新しいフィールドを作成するコマンド」のため、 if 等を使用して「新しいフィールドに格納する値」をしっかり定義する必要があります。
以下の例では、「3で割り切れる値=0,3,6,9」の時は元の値、それ以外では NULL を格納したフィールドの平均を取得しています。
0ではなく NULL なのは、平均計算時の総データ数を「3で割り切れる値=0,3,6,9」のデータのみに限定するためです。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| stats avg(eval(   NUM % 3 = 0              )) AS AVG,
        avg(eval(if(NUM % 3 = 0, NUM, 0     ))) AS AVG0,
        avg(eval(if(NUM % 3 = 0, NUM, null()))) AS AVGnull

スクリーンショット 2021-12-19 14.34.37.png

無論、先に記載したフラグフィールドを作成する方法を応用して使うことも可能です。
何なら、こちらのほうがわかりやすいかもしれません。

Splunk
| makeresults count=10000
| eval NUM = random() % 10
| eval FLG = if(NUM % 3 = 0, NUM, null())
| stats avg(FLG) AS AVG

スクリーンショット 2021-12-19 14.46.54.png

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?