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 |
累積・移動統計 |
重要ポイント
- **
stats**は最も基本的な集計コマンド - **
timechart**は時系列分析に必須 - **
eventstats**は元イベントと集計値を比較したい時に使う - **
streamstats**は移動平均や累積値に使う
練習問題
問題1: 基本
statsを使って、ソースタイプ別のイベント数、ユニークホスト数、最新のタイムスタンプを表示してください。
問題2: 応用
timechartを使って、15分間隔でステータスコード別のリクエスト数を時系列グラフ用に集計してください。
チャレンジ問題
eventstatsとwhereを組み合わせて、各ホストの平均レスポンスタイムの2倍以上遅いリクエストを抽出し、URI別にカウントしてください。
参考リンク
次回予告: Day 6では「データの可視化」について学びます。ダッシュボードとパネルの作成方法をマスターしましょう。