Open-Source Wikis

/

Caddy

/

Systems

/

Logging system

caddyserver/caddy

Logging system

Caddy uses go.uber.org/zap for structured logging. Configuration lives in logging.go (~25 KB) and bundled encoders/writers in modules/logging/.

Purpose

Build a tree of named loggers from JSON config. Each module gets a child logger named after its module ID; user-defined loggers can split off subsets by name pattern (e.g. an access log scoped to http.log.access).

Directory layout

Path Role
logging.go Logging config type, BaseLog, CustomLog, log-tree provisioning
logging_test.go Logger-tree tests
modules/logging/ Encoders and writers
modules/logging/encoders.go Console/JSON encoders
modules/logging/appendencoder.go Append-key encoder
modules/logging/filterencoder.go Filter encoder (cookie, header, IP-mask redaction) (~15 KB)
modules/logging/filters.go Field filter modules (~24 KB)
modules/logging/journaldencoder.go systemd journal encoder
modules/logging/filewriter.go Rotating file writer
modules/logging/netwriter.go TCP/UDP writer

Key abstractions

Type Where Description
Logging logging.go Top-level config: a default log + named custom logs
BaseLog logging.go Encoder + writer + level + sampling
CustomLog logging.go A BaseLog plus name include/exclude rules
Encoder (zap) Output formatter (caddy.logging.encoders.*)
WriterOpener logging.go Module that returns an io.WriteCloser (caddy.logging.writers.*)
Filter modules modules/logging/filters.go Hash, replace, delete, mask, regexp redaction for individual log fields

How it works

graph TD
    Config[Logging config] --> Provision[Logging.openLogs]
    Provision --> Default[default zap logger]
    Provision --> CustomLogs[named loggers]
    CustomLogs -->|filter by include/exclude| Tree[zap logger tree]
    Module -->|ctx.Logger| Tree
    Tree --> Encoder
    Encoder --> Writer
    Writer --> Sink[stdout/stderr/file/network/journald]

Logger tree

Logging.openLogs (in logging.go) walks the configuration and builds zap Cores for every distinct (encoder, writer, level) combination. Loggers are then named: ctx.Logger() looks up the deepest matching name in the tree, so http.handlers.file_server will route through any logger whose include list contains http.handlers.file_server or any of its prefixes (http, http.handlers, …).

Bundled encoders

Module ID Source
caddy.logging.encoders.json zap default JSON encoder
caddy.logging.encoders.console zap console encoder
caddy.logging.encoders.append appendencoder.go — adds static fields
caddy.logging.encoders.filter filterencoder.go — applies field filters
caddy.logging.encoders.journald journaldencoder.go

Field filters

The filter encoder lets you redact or transform individual fields:

Module ID Source Effect
caddy.logging.encoders.filter.hash filters.go Replace value with a SHA-256 hash
caddy.logging.encoders.filter.replace filters.go Replace value with a constant string
caddy.logging.encoders.filter.delete filters.go Remove the field
caddy.logging.encoders.filter.ip_mask filters.go Mask an IP address to a configurable prefix length
caddy.logging.encoders.filter.cookie filters.go Filter values inside a Cookie header
caddy.logging.encoders.filter.query filters.go Filter URL query parameters
caddy.logging.encoders.filter.regexp filters.go Substitute by regex
caddy.logging.encoders.filter.multi_regexp filters.go Multi-pattern variant
caddy.logging.encoders.filter.rename filters.go Rename the field

Writers

Module ID Source
caddy.logging.writers.stdout logging.go
caddy.logging.writers.stderr logging.go
caddy.logging.writers.discard logging.go
caddy.logging.writers.file modules/logging/filewriter.go (uses timberjack for rotation)
caddy.logging.writers.net modules/logging/netwriter.go

Access logs

Access logs are not a special path. They are zap log entries from the HTTP server (modules/caddyhttp/server.go and modules/caddyhttp/logging.go) under the logger name http.log.access.<server-id>. To send them to a separate file, configure a CustomLog whose include pattern matches http.log.access.

Integration points

  • ctx.Logger: the universal entry point for module log output (context.go).
  • HTTP server logs: access logs are produced by modules/caddyhttp/server.go and shaped by modules/caddyhttp/logging.go.
  • Caddyfile global options: log directives in the Caddyfile compile to Logging JSON.

Entry points for modification

  • Add an encoder? Implement zapcore.Encoder and register caddy.logging.encoders.<name>.
  • Add a writer? Implement caddy.WriterOpener and register caddy.logging.writers.<name>.
  • Add a filter? Implement caddy.LogFieldFilter and register caddy.logging.encoders.filter.<name>.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Logging system – Caddy wiki | Factory