Analytics
Traffic and WAF events are written to a bundled ClickHouse instance and queried back as charts. It is optional - everything else works without it.
What you get
Section titled “What you get”- Request volume over a time range you pick, filterable by host.
- Protocol breakdown - the HTTP versions actually in use.
- A country map, from the same GeoIP databases geo blocking uses. Colour it by requests, blocked requests or unique IPs, and pick a country - on the map or in the table beside it - to see which hosts it reached, how they answered, and which user agents it sent.
- Top user agents, which is usually how you notice a scraper.
- Blocked requests, paginated, and the WAF rules that fired most often.
Turning it on
Section titled “Turning it on”Open Settings → Observability → Analytics, tick Collect analytics, and set a ClickHouse password. Saving
starts the container - nothing to change in .env, no compose profile to list, because the
agent runs the compose command for you with the saved credentials.
Three things to expect:
- The first start pulls the ClickHouse image, which takes a few minutes on a slow link. The save returns immediately, and the Analytics page fills in once ClickHouse is up.
- Turning it off stops the container but keeps the data. History survives, and turning it back on picks up where it left off.
- Pick one owner. Once credentials live in Settings, drop
clickhousefromCOMPOSE_PROFILESand deleteCLICKHOUSE_PASSWORDfrom.env. Leaving both means your owndocker compose up -dalso creates the container, from the now-stale.envvalues.
Without an agent, Docker is the only thing that can start ClickHouse, so use the profile:
COMPOSE_PROFILES=clickhouseCLICKHOUSE_PASSWORD=your-clickhouse-password # openssl rand -base64 32Retention
Section titled “Retention”30 days by default, enforced by ClickHouse’s own TTL. Change it under Settings → Observability →
Analytics (or CLICKHOUSE_RETENTION_DAYS until a value is stored). Saving it re-checks the schema
on the next write, which migrates the existing tables’ TTL and purges expired data - no restart.
Disk writes
Section titled “Disk writes”ClickHouse’s internal diagnostic log tables are turned off by a config override the stack mounts. Left on, they flush every few seconds whether or not anyone is using the proxy, which is several GB a day on an idle machine. CPM never queries them.
Logs in the sidebar tails the raw logs, read through an agent so a remote host’s are there too:
- Access - every request Caddy logged, one line each, when access logging is on (Settings → Observability → Logging). A proxy host’s Logs action opens this, filtered to its domain.
- WAF - the rules the WAF matched.
- Caddy - Caddy’s own output, straight from its container.
- Certificates - just the issuance and renewal lines from Caddy’s output, for when a certificate won’t come through.
It follows new lines as they arrive, pauses on request, and filters what it has on screen. It needs no ClickHouse: the agent reads Caddy’s log files and its container’s output. Only administrators can open it: access logs name every client and every path they asked for. An agent older than the log viewer can’t serve it; update it.