Skip to content

Repository files navigation

IngestBench v2

A vendor-agnostic SIEM ingestion performance-testing CLI. Generates realistic security telemetry and pushes it to a SIEM collector (HEC/LPHC/syslog) at controlled rates to measure throughput, latency, and error rates.


Getting started

Install

Prerequisites: Go 1.23+.

go build -o ingestbench ./cmd/ingestbench

Quickstart

# 1. Secrets come from environment variables, never config files.
export IB_SMOKE_TOKEN=<your-api-token>

# 2. Validate the config.
ingestbench validate --config examples/steady-smoke.yaml

# 3. Preview events without sending anything.
ingestbench gen --source aws.cloudtrail -n 5 --format pretty

# 4. Run the load test.
ingestbench run --config examples/steady-smoke.yaml

Web UI

ingestbench serve starts a local control panel (embedded SPA, no Node) with 5 tabs: Run (start/stop, live metrics), Configs (build/validate/edit/delete), Source packs (browse catalog), Reports (browse run reports), and Scenarios (author multi-stage attack chains). Requires --configs-dir, --scenarios-dir, etc. to enable write operations.


Commands

Command Description
run --config <file> Run the load test against the configured target
validate --config <file> Validate a config file
probe Probe an endpoint: connectivity, auth, batch framing, rate ceiling
gen --source <id> Generate events to stdout (no network)
scenario --file <file> Play a multi-stage correlated scenario to stdout
serve Start the web control panel
init Interactive config builder (or --non-interactive for CI)
sources list|show|scaffold|validate Manage source packs
size --eps <n> --event-bytes <n> Compute sizing recommendations
secret set|list|rm Manage token files (0600, never echoed)
version Print version info

Key flags (run)

Flag Default Description
--config (required) YAML config file
--scenario Scenario file for correlated multi-stage runs
--duration config Override workload.stop.after
--total config Override workload.stop.total_events
--workers config or 4 Concurrent send workers
--output text text or json
--seed config Override RNG seed

Exit codes: 0 OK, 2 config invalid, 3 SLO breach, 4 auth failure, 6 run aborted.


Config

YAML-based. Run ingestbench validate to check, or ingestbench init to generate interactively.

schema_version: "1.0"
name: my-run
seed: 42
mode: realtime                    # or "deterministic"

target:
  adapter: lphc                   # lphc (default), generic-hec, or syslog
  url: https://collector.example.com/lphc/events/json
  auth:
    scheme: x-api-key             # x-api-key, basic, bearer, splunk, header
    token_env: MY_TOKEN_ENV_VAR   # env var holding the token (never in config)
  tls:
    verify: true
  batch:
    max_events: 500
    max_bytes: 512KB
  compression: none               # none or gzip (generic-hec only)
  limits:
    max_requests_per_sec: 190

source:
  id: aws.cloudtrail
  version: ">=1.0"
  entities: { host: 500, user: 100 }

workload:
  profile: steady                 # steady, burst, or ramp
  eps: 5000
  stop:
    after: 5m                     # or total_events: 1000000

observability:
  dashboard: true
  report: /tmp/report.json
  prometheus: "127.0.0.1:9090"    # optional

slo:                              # optional; breach -> exit code 3
  min_success_rate: 0.99
  max_p95_ms: 500

Timestamp shaping (source.timestamps) supports historical backfills with anchors, jitter, and business-hours weighting. See examples/timestamps-backfill.yaml.

Example configs

File Purpose
steady-smoke.yaml Quick first run: 200 events, low rate
lphc.yaml Guardsix HTTP collector
lphc-syslog.yaml Guardsix over syslog (TCP)
generic-hec.yaml Splunk-compatible HEC
steady-100k.yaml 1M-event sustained run
burst.yaml Square-wave burst profile
ramp.yaml Linear ramp 500 -> 10k EPS
timestamps-backfill.yaml 14-day historical backfill

Transport adapters

Adapter target.adapter Auth Use for
LPHC (default) lphc or omit x-api-key, basic Guardsix / Logpoint HTTP Collector (JSON packs)
Generic HEC generic-hec bearer, splunk, header Splunk-compatible HEC (Splunk, Cribl). framing: raw for non-JSON
Syslog syslog none (socket) TCP/UDP/TLS syslog. Native carrier for syslog/CEF packs

Adapter-specific knobs: target.hec.* (generic-hec) and target.syslog.* (syslog). See the example configs for annotated usage.


Source packs

ID Category Description
aws.cloudtrail cloud KMS Decrypt, Console Login, S3 GetObject
aws.guardduty cloud SSH brute force, port probe, DNS exfiltration
m365.audit cloud Entra sign-in, SharePoint file ops, Exchange mail
windows.security endpoint Logon 4624/4625, process creation 4688
linux.auditd endpoint execve, PAM auth, user login (JSON)
linux.syslog endpoint sshd logins, sudo commands (RFC 5424)
firewall.traffic network Allowed/denied/dropped connections (JSON)
firewall.cef network Same as above in ArcSight CEF format
firewall.cef.syslog network CEF wrapped in RFC 5424 syslog
paloalto.traffic network PAN-OS session end, deny, drop
identity.okta identity Sign-in, MFA, app SSO
crowdstrike.falcon edr Process exec, network connect, detection alert
ingestbench sources list
ingestbench sources show aws.cloudtrail
ingestbench gen --source aws.cloudtrail -n 3 --format pretty

Scenarios

Multi-stage, entity-correlated attack chains with MITRE ATT&CK tagging:

schema_version: "2.0"
seed: 12345
anchor: "2024-06-03T13:00:00Z"
correlation:
  shared: [user, host, source_ip]
stages:
  - { tactic: TA0006, technique: T1110, source: windows.security, count: 40, start_offset: 0s, duration: 4m }
  - { tactic: TA0001, technique: T1078, source: identity.okta,    count: 5,  start_offset: 4m, duration: 1m }
  - { tactic: TA0002, technique: T1059, source: windows.security, count: 25, start_offset: 5m, duration: 6m }

Preview with ingestbench scenario --file <f>, or push to a collector with ingestbench run --config <target> --scenario <file>.


Performance

Synthetic (in-process mock LPHC)

Measured on Apple M5 (arm64), Go 1.25.12.

Metric Value
Engine ceiling ~65 000 events/s
Allocs per event ~234
Mock LPHC sustained EPS ~65 500
Batch latency p95 ~33 ms
Event loss 0

Live endpoint (Guardsix LPHC)

Measured 2026-07-21, aws.cloudtrail, batch size 50, find_ceiling: true.

Workers EPS RPS p50 p99 Events Failures
4 380 7.6 370 ms 2 410 ms 70k 0
16 876 17.5 601 ms 4 223 ms 160k 0
114 4 758 95.2 342 ms 1 654 ms 860k 0

Throughput scales linearly with workers (Little's Law). At 114 workers the bottleneck flipped from endpoint-bound to sender-bound (rate limiter ceiling). Zero 429s across all runs.


Limitations

  • Success is per-batch HTTP. A 200 means the collector accepted the batch, not that every event was indexed.
  • Single-node only. No distributed load generation.
  • Laptop NIC-bound. Real throughput depends on your network and the target.

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.

About

A tool for simulating and testing data ingestion by sending payloads to SIEM systems for performance evaluation and testing.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages