Skip to content

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.

Traffic analyticsChange the range, switch what the countries are ranked by, or pick a country to open its breakdown.DemoNothing you change here is saved
Time interval
Time interval
24h
7d
30d
Requests
Protocols
HTTP/2
62
HTTP/3
29
HTTP/1.1
9
Top countries
Colour the map by
Colour the map by
Requests
Blocked
Unique IPs
Top user agents
Chrome 141
18,200
Safari 19
9,700
Firefox 146
5,100
curl/8.9
2,400
Unknown scanner
890
  • 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.

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 clickhouse from COMPOSE_PROFILES and delete CLICKHOUSE_PASSWORD from .env. Leaving both means your own docker compose up -d also creates the container, from the now-stale .env values.

Without an agent, Docker is the only thing that can start ClickHouse, so use the profile:

COMPOSE_PROFILES=clickhouse
CLICKHOUSE_PASSWORD=your-clickhouse-password # openssl rand -base64 32

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.

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.

LogsSwitch the log or the agent, filter, or pause. The lines are made up in your browser.DemoNothing you change here is saved

Logs

Waiting for new lines…0 lines shown of 0 kept