10日で覚えるSplunkDay 5: 統計と集計

Day 5: 統計と集計

今日学ぶこと

  • stats コマンド
  • chart / timechart コマンド
  • top / rare コマンド
  • 統計関数(count, avg, sum, max, min, dc)
  • eventstats と streamstats

stats コマンド

データを集計する最も基本的なコマンドです。

# ステータスコード別のカウント
index=main sourcetype=access_combined
| stats count by status

# ホスト別の平均レスポンスタイム
index=main sourcetype=access_combined
| stats avg(response_time) AS avg_response by host

# 複数の集計を一度に
index=main sourcetype=access_combined
| stats count, avg(response_time) AS avg_rt, max(response_time) AS max_rt, min(response_time) AS min_rt by host

主要な統計関数

関数 説明
count イベント数 count
count(field) フィールドがある数 count(user)
dc(field) ユニークな値の数 dc(clientip)
avg(field) 平均 avg(response_time)
sum(field) 合計 sum(bytes)
max(field) 最大値 max(response_time)
min(field) 最小値 min(response_time)
median(field) 中央値 median(response_time)
mode(field) 最頻値 mode(status)
stdev(field) 標準偏差 stdev(response_time)
perc95(field) 95パーセンタイル perc95(response_time)
values(field) ユニーク値のリスト values(user)
list(field) 値のリスト(重複含む) list(status)
latest(field) 最新の値 latest(status)
earliest(field) 最古の値 earliest(status)

by句の複数フィールド

# ホストとステータスの組み合わせ
index=main sourcetype=access_combined
| stats count by host, status
| sort host, -count

chart コマンド

2次元のクロス集計表を作成します。

# ステータスコード別×ホスト別のカウント
index=main sourcetype=access_combined
| chart count by status, host

結果のイメージ:

status web-01 web-02 web-03
200 1500 1200 1800
404 50 30 45
500 10 15 5
# over と by の使い分け
index=main sourcetype=access_combined
| chart count over status by host

# 上位5ホストのみ
index=main sourcetype=access_combined
| chart count by host
| sort -count
| head 5
flowchart LR
    subgraph stats["stats count by A"]
        S1["A | count<br>---+------<br>x | 10<br>y | 20"]
    end
    subgraph chart["chart count by A, B"]
        C1["A | B1 | B2<br>---+----+----<br>x | 5 | 5<br>y | 12 | 8"]
    end
    style stats fill:#3b82f6,color:#fff
    style chart fill:#22c55e,color:#fff

timechart コマンド

時系列データのグラフ用の集計を行います。

# 1時間ごとのイベント数
index=main sourcetype=access_combined
| timechart span=1h count

# ステータス別の時系列カウント
index=main sourcetype=access_combined
| timechart span=1h count by status

# 平均レスポンスタイムの推移
index=main sourcetype=access_combined
| timechart span=15m avg(response_time) AS avg_response

span の指定

span 説明
span=1m 1分間隔
span=5m 5分間隔
span=15m 15分間隔
span=1h 1時間間隔
span=1d 1日間隔

ポイント: timechart_timeフィールドを自動的にX軸に使います。chartとの違いは、時間軸が固定されている点です。

chart vs timechart

比較 chart timechart
X軸 任意のフィールド _time固定
時間集計 手動(eval+strftime 自動(span指定)
用途 カテゴリ分析 時系列分析

top / rare コマンド

top

最も頻度の高い値を表示します。

# 上位10件のURI
index=main sourcetype=access_combined
| top limit=10 uri

# ホスト別の上位URI
index=main sourcetype=access_combined
| top limit=5 uri by host

# パーセント表示なし
index=main sourcetype=access_combined
| top limit=10 uri showperc=false

topの出力フィールド:

フィールド 説明
count 出現回数
percent 全体に対する割合

rare

最も頻度の低い値を表示します(topの逆)。

# 最も少ないステータスコード
index=main sourcetype=access_combined
| rare limit=5 status

eventstats コマンド

statsと同様に集計しますが、元のイベントに集計結果を追加します。

# 各イベントに全体平均を追加
index=main sourcetype=access_combined
| eventstats avg(response_time) AS overall_avg
| eval is_slow = if(response_time > overall_avg * 2, "Yes", "No")
| where is_slow="Yes"
| table _time, uri, response_time, overall_avg
flowchart TB
    subgraph Stats["stats: イベントが集計結果に置き換わる"]
        S1["host | count<br>web-01 | 100<br>web-02 | 200"]
    end
    subgraph EventStats["eventstats: 元イベント + 集計結果"]
        E1["_time | host | ... | total<br>10:00 | web-01 | ... | 300<br>10:01 | web-02 | ... | 300"]
    end
    style Stats fill:#3b82f6,color:#fff
    style EventStats fill:#22c55e,color:#fff
コマンド 元イベント 集計結果
stats 消える グループ別の集計行
eventstats 残る 各イベントに追加

streamstats コマンド

イベントを順に処理し、累積的な統計を計算します。

# 累積カウント
index=main sourcetype=access_combined
| streamstats count AS running_count
| table _time, uri, running_count

# 直前5件の移動平均
index=main sourcetype=access_combined
| streamstats avg(response_time) AS moving_avg window=5
| table _time, response_time, moving_avg

# ホスト別の累積エラー数
index=main sourcetype=access_combined status>=400
| streamstats count AS error_count by host
| table _time, host, status, error_count
パラメータ 説明
window=N 直近N件で計算
time_window=span 時間ウィンドウで計算
current=false 現在のイベントを除外

実践: パフォーマンス分析ダッシュボード用クエリ

# 1. 全体のKPI
index=main sourcetype=access_combined
| stats
    count AS total_requests,
    dc(clientip) AS unique_visitors,
    avg(response_time) AS avg_response_time,
    perc95(response_time) AS p95_response_time,
    sum(eval(if(status>=400,1,0))) AS error_count
| eval error_rate = round(error_count / total_requests * 100, 2)
| eval avg_response_time = round(avg_response_time, 3)
| eval p95_response_time = round(p95_response_time, 3)

# 2. 時間帯別トラフィック
index=main sourcetype=access_combined
| timechart span=1h count AS requests, avg(response_time) AS avg_rt

# 3. エンドポイント別パフォーマンス
index=main sourcetype=access_combined
| stats count, avg(response_time) AS avg_rt, perc95(response_time) AS p95_rt by uri
| sort -count
| head 20
| eval avg_rt = round(avg_rt, 3)
| eval p95_rt = round(p95_rt, 3)

# 4. エラー率の時系列推移
index=main sourcetype=access_combined
| timechart span=15m count(eval(status>=400)) AS errors, count AS total
| eval error_rate = round(errors / total * 100, 2)
| fields _time, error_rate

# 5. レスポンスタイムの分布
index=main sourcetype=access_combined
| eval rt_bucket = case(
    response_time < 0.1, "< 100ms",
    response_time < 0.5, "100-500ms",
    response_time < 1.0, "500ms-1s",
    response_time < 5.0, "1-5s",
    1=1, "> 5s"
)
| stats count by rt_bucket
| sort rt_bucket

まとめ

概念 説明
stats グループ別の集計
chart 2次元クロス集計
timechart 時系列集計
top / rare 頻度の高い/低い値
eventstats 元イベントに集計結果を追加
streamstats 累積・移動統計

重要ポイント

  1. **stats**は最も基本的な集計コマンド
  2. **timechart**は時系列分析に必須
  3. **eventstats**は元イベントと集計値を比較したい時に使う
  4. **streamstats**は移動平均や累積値に使う

練習問題

問題1: 基本

statsを使って、ソースタイプ別のイベント数、ユニークホスト数、最新のタイムスタンプを表示してください。

問題2: 応用

timechartを使って、15分間隔でステータスコード別のリクエスト数を時系列グラフ用に集計してください。

チャレンジ問題

eventstatswhereを組み合わせて、各ホストの平均レスポンスタイムの2倍以上遅いリクエストを抽出し、URI別にカウントしてください。


参考リンク


次回予告: Day 6では「データの可視化」について学びます。ダッシュボードとパネルの作成方法をマスターしましょう。