v0.7.1 · updated · GitHub

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 elsewherePackageLink
“Caddy JSON → LogEntry”pkg/parserAPI → parser
“Top country/asn, GeoIP cache”pkg/enrichAPI → enrich
“26 categories, MITRE, Sigma”pkg/analysisAPI → analysis, Detection
“8 feeds, CIDR trie, 7d cache”pkg/blocklistAPI → blocklist
“sliding window, audit, state”pkg/guard + guard/firewallAPI → guard
“file/docker/k8s/journalctl”pkg/readerAPI → reader
“table/html/json”pkg/outputAPI → output
“live dashboard”pkg/tuiTUI & 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).