Skip to main content
This page ships Caddy’s JSON logs to Rootprint over OTLP with the OpenTelemetry Collector or Vector. Records land in otel-logs-v0_9 with service.name: caddy, and access-log fields arrive as OpenTelemetry HTTP attributes.

Prerequisites

  • A running Rootprint instance. Substitute its host for <your-rootprint>.
  • An ingest API key scoped to otel-logs-v0_9. Create one in Settings → API keys with Create ingest key, then substitute it for <your-ingest-api-key>. See API keys.
  • A host running Caddy.
  • The OpenTelemetry Collector or Vector installed on the Caddy host. The agent pages cover installation.
1

Enable Caddy file logging

Caddy’s systemd service logs to journald by default. Add these blocks to /etc/caddy/Caddyfile so Caddy writes JSON to files. Add a log block to every site whose access log you want to ship. Keep Caddy’s default JSON encoder: don’t add a format directive. mode 0640 lets the caddy group read the log files. It needs Caddy 2.9 or later.
2

Write the agent config

Replace <your-rootprint> and <your-ingest-api-key>.
Save this as /etc/otelcol-contrib/config.yaml.
The Collector config (start_at: end) reads only lines written after each start, so it skips lines written while it was stopped. Vector (read_from: end) skips existing lines on first start only, then resumes from its checkpoint.
3

Grant read access to /var/log/caddy

Let the caddy group enter the log directory, and add your agent’s user to that group:
4

Restart the agent

Run sudo systemctl restart otelcol-contrib or sudo systemctl restart vector. The agent’s log should show no config or exporter errors.
5

Send a test request

Hit a site that has a log block:
6

Verify in Rootprint

Open Logs, pick otel-logs-v0_9 from the index selector, and search for service_name:caddy. Records typically appear within 5–10 seconds.

What you get in Rootprint

Both agents produce the same attributes. Entries without a request object, such as Caddy’s runtime logs, carry only caddy.logger and log.file.path.
  • Log level: taken from Caddy’s level field. Caddy logs 5xx responses at error, and panic and fatal map to FATAL.
  • Timestamp: taken from Caddy’s ts field, with the agent’s read time as a fallback.

Useful searches

Troubleshooting

  • body is raw JSON and entries have no http.* attributes: the Caddyfile sets a format directive. The parsers expect Caddy’s default JSON encoder. Remove the format directive or extend the parser.
  • 401/403/413/415: see Response codes.