Log Sources
Every command accepts one or more sources. If you pass none, the tool tries caddy-analyzer.json → pipe → auto-discovery. Below: how to connect to each source and what permission that source needs. For tool configuration (config file, tuning, env), see Guide → Configuration.
File & glob
caddy-analyze /var/log/caddy/access.log
caddy-analyze /var/log/caddy/*.log
caddy-analyze /var/log/caddy/access.log.1 /var/log/caddy/access.log.2.gz
# no args → tries ./access.log, ./caddy.log, ./caddy-access.log, /var/log/caddy/access.log, /var/log/caddy/caddy.log
caddy-analyze
Permissions for files
Caddy often writes as caddy:caddy 0600. You need read on the file and execute on the directory.
sudo caddy-analyze /var/log/caddy/access.log
# persistent — add yourself to the group then re-login:
sudo usermod -aG caddy $USER
zcat: zcat /var/log/caddy/*.gz | caddy-analyze -. Do not pass .gz directly.Stdin — -
cat /var/log/caddy/access.log | caddy-analyze -
zcat /var/log/caddy/access.log.*.gz | caddy-analyze - --detect -f json -o out.json
ssh app@prod "cat /var/log/caddy/access.log" | caddy-analyze - -t 25
Permissions for stdin
None on the local side. Remote side needs read as above, plus SSH access. Stdin is also auto-detected when data is piped and no source arg is given.
Docker — docker://<name|id>
caddy-analyze docker://caddy
caddy-analyze docker://a3f9c1e2d4b5
caddy-analyze tail docker://caddy # live
caddy-analyze --follow docker://caddy # same via root flag
Streams with docker logs -f <container> in an interactive terminal; non-interactive reads add --tail=all. Both merge stdout and stderr.
Permissions for Docker
# docker.sock is root:docker 0660 by default
sudo usermod -aG docker $USER # re-login
# or
sudo caddy-analyze docker://caddy
# if Caddy runs in Docker but guard must block host:
sudo caddy-analyze guard --firewall-backend hybrid docker://caddy
--firewall-backend hybrid or auto — it blocks both INPUT and DOCKER-USER.Kubernetes — k8s://<pod>
caddy-analyze k8s://caddy-7d9f8c9d4-abc12
caddy-analyze k8s://caddy-7d9f8c9d4-abc12 -n production
caddy-analyze tail k8s://caddy-7d9f8c9d4-abc12 -n prod --detect
Reads via kubectl logs --tail=-1 --follow -n <ns> <pod> using your active kubectl context.
Permissions for Kubernetes
kubectl auth can-i get pods/log -n production # should be yes
kubectl config current-context
kubectl get pods -n production | grep caddy
Namespace can also be persisted: caddy-analyze config k8s://caddy-xxx -n production (see Configuration).
journalctl — journalctl://<unit>
caddy-analyze journalctl://caddy.service
caddy-analyze tail journalctl://caddy.service
caddy-analyze journalctl://caddy.service --follow
Reads via journalctl -u <unit> --output=cat [--follow].
Permissions for journalctl
sudo usermod -aG systemd-journal $USER # re-login
# or
sudo caddy-analyze journalctl://caddy.service
Auto-discovery (no source arg)
When you run caddy-analyze with no file/URI and no pipe, it probes in order:
caddy-analyzer.json(local then global — Configuration)- stdin pipe if data is piped
- 5 candidates:
./access.log,./caddy.log,./caddy-access.log,/var/log/caddy/access.log,/var/log/caddy/caddy.log
caddy-analyze config /var/log/caddy/access.log # remember for next time
caddy-analyze --detect # now works with no arg
Fixtures — try without a server
Repo ships two deterministic fixtures under testdata/ (regenerate with python3 testdata/generate.py). All IPs are RFC 5737 TEST-NET.
| File | Lines | Use |
|---|---|---|
testdata/sample.log | 68 | One entry per category — verify all 26 fire |
testdata/large.log | ~50K | 24h mix (95% benign) — throughput demo |
caddy-analyze --detect testdata/sample.log
caddy-analyze tail -d testdata/sample.log
caddy-analyze -f html -o report.html --detect testdata/sample.log && open report.html
caddy-analyze diff testdata/sample.log testdata/large.log