Architecture
Single binary, zero CGO, bounded memory (LRU + histogram). For package signatures and import examples, see API / Packages. To add a feature, see Contributing.
Data flow
Sources Reader Parser
────────── ────── ──────
file / glob ─┐
stdin - ├─▶ reader.FromSource(follow) ─▶ parser.Parse(line) ─┐
docker:// ───┤ fan-in + rotation │
k8s:// ──────┤ stdout+stderr merge ▼
journalctl ──┘ ┌─────────────────┐
│ analysis.Engine │
│ ├─ MatchEntry() │◀── types.Filters (--from, --ip, --country, --grep, --level…)
│ ├─ Enrich ───────▶ enrich.GeoIP.Lookup(ip) → Country/ASN (LRU 50K, TTL 24h)
│ ├─ Detect ───────▶ analysis.Detector (26 cats, dual-pass, MITRE)
│ └─ Stats (TopN, histogram 1K buckets, human/bot) │
└────────┬────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
output.Report tui.Model (watch) guard.Guard
table/json/csv/html 8 tabs, 2s tick ├─ Evaluate(entry) ──▶ blocklist.Manager.Contains(ip) → immediate
├─ enrich.GeoIP ──▶ country-block → immediate
├─ sliding window (per-sec buckets) → Tick()
├─ firewall.Backend (auto → hybrid/iptables/docker/nftables)
└─ audit + state (JSONL + blocked.json)
Packages — where concepts land
| Concept you read elsewhere | Package | Link |
|---|---|---|
| “Caddy JSON → LogEntry” | pkg/parser | API → parser |
| “Top country/asn, GeoIP cache” | pkg/enrich | API → enrich |
| “26 categories, MITRE, Sigma” | pkg/analysis | API → analysis, Detection |
| “8 feeds, CIDR trie, 7d cache” | pkg/blocklist | API → blocklist |
| “sliding window, audit, state” | pkg/guard + guard/firewall | API → guard |
| “file/docker/k8s/journalctl” | pkg/reader | API → reader |
| “table/html/json” | pkg/output | API → output |
| “live dashboard” | pkg/tui | TUI & Reports |
Memory bounds
MaxCardinality 100k per counter, IPs LRU 100k, histogram 1000 buckets (log10, 1µs–10s), GeoIP LRU 50k. No unbounded maps.
Config flow
caddy-analyzer.json (local → global) → PersistentPreRunE applyTuning() → CLI flag overrides. Guard adds whitelist + --never-block union. See Configuration.
See also
API / Packages — import + usage per package. Contributing — where to add a detection (pkg/analysis/detect.go), a feed (pkg/blocklist), or a firewall backend (pkg/guard/firewall).