Splunk SPL Commands

What Is the eventstats Command?

The eventstats command computes aggregate statistics — just like stats — but instead of collapsing events into summary rows, it appends the computed values back to every original event. This makes it indispensable for comparing individual events against group baselines.

Think of it as: “Give me the average, but keep every event so I can see which ones deviate.”

Core Syntax

| eventstats <function>(<field>) AS <alias> [BY <field-list>]

Key Difference: stats vs. eventstats

Feature stats eventstats
Preserves original events No — collapses to summary rows Yes — appends fields to each event
Output row count One per group Same as input
Use case Reports, dashboards Enrichment, anomaly detection

Security Operations Examples

1. Anomalous Login Volume Detection

Flag users whose login count significantly exceeds the organizational average — a key indicator for compromised accounts.

index=security sourcetype=WinEventLog:Security EventCode=4624
| stats count AS user_logins BY Account_Name
| eventstats avg(user_logins) AS org_avg stdev(user_logins) AS org_stdev
| eval threshold = org_avg + (2 * org_stdev)
| where user_logins > threshold
| table Account_Name user_logins org_avg threshold

2. Data Transfer Anomalies by Host

Identify hosts transferring significantly more data than their peer group.

index=network sourcetype=firewall
| stats sum(bytes_out) AS total_bytes BY src_ip
| eventstats avg(total_bytes) AS peer_avg median(total_bytes) AS peer_median BY src_zone
| eval deviation = round((total_bytes - peer_avg) / peer_avg * 100, 1)
| where deviation > 200
| sort - deviation

3. Response Time Baseline Comparison

index=web sourcetype=access_combined
| eventstats avg(response_time) AS avg_rt p95(response_time) AS p95_rt BY uri_path
| where response_time > p95_rt
| table _time uri_path response_time avg_rt p95_rt clientip

4. Audit Log Completeness Check (NIST AU-6)

Compare each system’s audit log count against the fleet average to find systems with potential logging gaps.

index=security sourcetype=WinEventLog:Security
| stats count AS event_count BY host
| eventstats avg(event_count) AS fleet_avg
| eval log_ratio = round(event_count / fleet_avg, 2)
| where log_ratio < 0.3
| table host event_count fleet_avg log_ratio

Advanced Patterns

Percentile-Based Anomaly Detection

index=proxy sourcetype=bluecoat
| stats sum(bytes) AS total_bytes BY user
| eventstats perc95(total_bytes) AS p95_bytes
| where total_bytes > p95_bytes

Rolling Group Context

index=endpoint sourcetype=sysmon EventCode=1
| eventstats dc(process_name) AS unique_processes count AS total_executions BY ComputerName
| where unique_processes > 50

Best Practices

  • Use eventstats for enrichment, stats for summarization — If you need to keep individual events visible, use eventstats.
  • Be mindful of performance — eventstats must process every event twice (once to compute, once to append). Pre-filter your data.
  • Combine with eval for thresholds — The power pattern is: eventstats → eval threshold → where deviation.
  • Use BY clauses for peer grouping — Compare hosts against their zone, users against their department, not the entire org.

Next in the series: The streamstats command — running totals, moving averages, and sequential analysis.


Next in the Rhombic SPL Series → Splunk streamstats Command