Promtail Pipeline for Caddy Logs

The following snippets show, how promtail can be used to configure reading of caddy web server log files with useful labels and messages.

I'm using caddy logs for access logging only - for PHP / application logging I am using a self-hosted sentry instance.

The following Caddy snippet is used to generate logs for all my configured vhosts:

(log) {
    log {
        output file /var/log/caddy/{args.0}.log
        level warn
        format json
        format filter {
            wrap json
            fields {
                common_log delete
                request>remote_addr ip_mask {
                    ipv4 24
                    ipv6 32
                }
            }
        }
    }
}

The promtail scrape configuration uses multiple pipeline stages to parse the json log file and generate labels.

scrape_configs:
  - job_name: webserver
    pipeline_stages:
      - json:
          expressions:
            level: level
            message: msg
            timestamp: ts
            logger_name: logger
            response_header: resp_header
            request: request
            size: size
            status: status
      - json:
          expressions:
            remote_addr: remote_addr
            proto: proto
            method: method
            host: host
            uri: uri
            headers: headers
          source: request
      - template:
          source: result
          template: "{{ .message }}: {{ .method }} {{ .uri }} - {{ .status }}"
      - output:
          source: result
      - labels:
          level:
          status:
          timestamp:
          logger_name:
          size:
          uri:
          method:
          host:
          headers:
          response_header:
    static_configs:
      - targets:
          - localhost
        labels:
          job: caddylogs
          __path__: /var/log/caddy/*log

The template line combines multiple fields into a single message line - this is what is displayed as "main log message".

The labels allow grouping, filtering and easy searching - so I added everything I could think of ever needing.

The output stage is necessary - if you forget it, your pipeline will not work.

Have fun logging everything that goes wrong.