【Splunk】statsは統計処理を行う

statsコマンドの説明を書きます。
以下の記事の派生記事です。
canada-lemon.hatenablog.com

statsは統計処理を行うコマンドです。

構文例
| stats (統計処理) by <集計単位のフィールド名>

使用例1:平均を計算する

具体例として、statsを使って数値の平均を計算してみます。

以下のSPLを実行してダミーデータを用意します。
4人の生徒の、英語数学国語の点数です。

makeresultsってなんぞや?という方は以下の記事をご参照ください。
canada-lemon.hatenablog.com

| makeresults format=csv 
data="Name,English,Math,Japanese
Alice,75,77,65
Bob,51,82,59
Carol,86,94,61
堂林,95,66,63"
| table Class Name English Math Japanese
Class Name English Math Japanese
2年1組 Alice 75 77 65
2年1組 Bob 51 82 59
2年2組 Carol 86 94 61
2年2組 堂林 95 66 63



このダミーデータに対し、| stats avg(フィールド名)で平均を計算できます。
試しにEnglishの平均を計算してみましょう。

| makeresults format=csv 
data="Class,Name,English,Math,Japanese
2年1組,Alice,75,77,65
2年1組,Bob,51,82,59
2年2組,Carol,86,94,61
2年2組,堂林,95,66,63"
| table Class Name English Math Japanese
| stats avg(English) by Class
| rename avg(English) as "英語の平均点"
Class 英語の平均点
2年1組 63
2年2組 90.5



統計処理は、一気に複数のフィールドに対して行うことが可能です。
次は英数国の平均を計算します。

| makeresults format=csv 
data="Class,Name,English,Math,Japanese
2年1組,Alice,75,77,65
2年1組,Bob,51,82,59
2年2組,Carol,86,94,61
2年2組,堂林,95,66,63"
| table Class Name English Math Japanese
| stats avg(English) avg(Math) avg(Japanese) by Class
| rename avg(English) as "英語の平均点" avg(Math) as "数学の平均点" avg(Japanese) as "国語の平均点"
Class 英語の平均点 数学の平均点 国語の平均点
2年1組 63 79.5 62
2年2組 90.5 80 62

数学と国語の平均点はほぼ同じ、英語は2年2組のほうが優秀なのがわかります。


byでフィールドを指定しないと、テーブル全体を対象に統計処理を行います。
今回の例だと、Aliceから堂林までの4人の生徒全体の平均点を計算します。

| makeresults format=csv 
data="Class,Name,English,Math,Japanese
2年1組,Alice,75,77,65
2年1組,Bob,51,82,59
2年2組,Carol,86,94,61
2年2組,堂林,95,66,63"
| table Class Name English Math Japanese
| stats avg(English) avg(Math) avg(Japanese)
| rename avg(English) as "英語の平均点" avg(Math) as "数学の平均点" avg(Japanese) as "国語の平均点"
英語の平均点 数学の平均点 国語の平均点
76.75 79.75 62

ここでは平均を計算しましたが、もちろん他にも様々な統計処理が可能です。
次の項目で一例を紹介します。

備考1:よく使う統計処理

  • count:ログの件数
  • sum:合計
  • avg:平均
  • values:ユニークな値の一覧
    • 同じ値が複数あっても1つしか表示されない
  • list:値の一覧
    • 同じ値が複数あると複数表示される

備考2:renameもできる

以下のSPLでは、statsで英語の平均点を計算した後、自動生成されたavg(English)フィールドをリネームしています。

| stats avg(English) by Class
| rename avg(English) as "英語の平均点"



このSPLは以下のように1行で書くこともできます。

| stats avg(English) as "英語の平均点" by Class

2行で書くと、統計処理で1行、リネームで1行と役割ごとに行を分割できます。
1行で書くと、すっきりします。

どちらでも大丈夫ですが、もし日本語にリネームするなら最後の行にしておきましょう。
こちらの記事もご参照ください。
canada-lemon.hatenablog.com

備考3:ログを加工するタイミング

statsで統計処理を行うと、処理に使ったデータは破棄して、新しいデータを作成します。*1
今回の記事でいうと、「処理に使ったデータ」は4人の生徒の点数、「新しいデータ」は英語の平均点などです。
統計処理の元となるデータの加工は、statsが実行される前に行う必要があります。

数学に出題ミスがあって、全生徒に5点プラスすすることになりました。
数学の点数を5点増やす処理は| eval Math = Math + 5です。

statsの前にこの処理を行います。

| makeresults format=csv 
data="Class,Name,English,Math,Japanese
2年1組,Alice,75,77,65
2年1組,Bob,51,82,59
2年2組,Carol,86,94,61
2年2組,堂林,95,66,63"
| table Class Name English Math Japanese
| eval Math = Math + 5
| stats avg(English) avg(Math) avg(Japanese) by Class
| rename avg(English) as "英語の平均点" avg(Math) as "数学の平均点" avg(Japanese) as "国語の平均点"
Class 英語の平均点 数学の平均点 国語の平均点
2年1組 63 84.5 62
2年2組 90.5 85 62

ちゃんと平均点が5点上がっていました。


それでは、statsの後でこの処理を行ってみましょう。

| makeresults format=csv 
data="Class,Name,English,Math,Japanese
2年1組,Alice,75,77,65
2年1組,Bob,51,82,59
2年2組,Carol,86,94,61
2年2組,堂林,95,66,63"
| table Class Name English Math Japanese
| stats avg(English) avg(Math) avg(Japanese) by Class
| rename avg(English) as "英語の平均点" avg(Math) as "数学の平均点" avg(Japanese) as "国語の平均点"
| eval Math = Math + 5
Class 英語の平均点 数学の平均点 国語の平均点
2年1組 63 79.5 62
2年2組 90.5 80 62

平均点はそのままでした。
statsが実行された時点で各生徒の点数データは破棄されているので、加算処理を行っても反映されません。
また、このときSplunk上でエラーは出ないので注意しましょう。

では、元のデータを破棄せず、統計処理を行うことは可能なのでしょうか?
そういう人のために、eventstatsというコマンドが用意されています。
このコマンドも別途紹介する予定です。

本記事ではstatsコマンドの説明をしました。
このコマンドも、evalと並んで用途が広いです。
statsとevalコマンドを使えるようになったら、だいたいのユースケースに対応できると言っても過言ではないです。

ここまで読んでいただき、ありがとうございました。

*1:元のデータやログが消失するわけではなく、SPLを実行する上で使えなくなるだけです