Caddy 日志配置指南:JSON 结构化、字段过滤与敏感信息保护
Caddy 默认输出 JSON 结构化日志,但访问日志默认关闭。本文讲解 Caddy log 指令的开启方法、output/format 配置、filter 编码器的字段删除/重命名/IP 脱敏、查询参数处理,以及接入观测云实现集中监控的路径。
Caddy 日志(Caddy Logging)是基于高性能 Zap 库实现的结构化日志体系,默认以 JSON 格式输出服务器运行事件;HTTP 访问日志(request log)默认关闭,需在 Caddyfile 中用 log 指令显式开启。 在主流 Web 服务器里,Caddy 是少有的"天生 JSON"选手——这让它与日志平台的对接格外顺畅。
核心要点速览
- Caddy 运行日志默认就是 JSON;访问日志需用
log指令手动开启,默认写到 stderr; output决定去向(stdout/stderr/file/net/discard),文件输出自带轮转参数;format filter编码器支持字段删除、重命名、正则替换、IP 掩码与哈希,是脱敏与降噪的利器;- Cookie、Authorization 等敏感请求头默认自动脱敏为 REDACTED,无需额外配置;
- 集中采集时要验证 JSON 字段提取,并区分 HTTP 状态码与日志级别。
开启访问日志:log 指令
Caddyfile 中最简配置——一行开启访问日志:
example.com {
log
}
默认输出到 stderr。用 output 子指令改变去向:
example.com {
log {
output file /var/log/caddy/access.log {
roll_size 10MB # 单文件超 10MB 轮转
roll_keep 5 # 保留 5 份
roll_keep_days 14 # 超 14 天删除
}
}
}
output 可选项:stdout、stderr、file(自带轮转,见上)、net(发到网络地址)、discard(彻底关闭)。Docker 部署建议输出到 stdout/stderr,交给容器日志链路;虚拟机直装可用内置文件轮转,省去 logrotate。
format:控制编码与字段命名
format json(默认)适合机器处理;format console 在时间戳与级别上更易读,但请求详情仍是 JSON。format 还支持字段级定制——对齐企业统一的日志规范时非常实用:
log {
output stdout
format json {
message_key msg
level_key severity
time_key timestamp
time_format "2006-01-02 15:04:05 MST"
level_format "upper"
duration_format "ms"
}
}
filter 编码器:删、改、脱敏
format filter 是 Caddy 日志的精华能力,嵌套路径用 > 表示:
删除冗余/敏感字段:
format filter {
request>headers>Authorization delete
resp_headers>Server delete
wrap json
}
注意:filter 不支持通配符(如 Sec-*),多个字段需逐行列出。
重命名以对齐规范:
format filter {
request>uri rename path
status rename status_code
wrap json
}
替换与正则脱敏:
format filter {
user_id replace [REDACTED]
request>uri regexp apikey=[A-Za-z0-9]+ apikey=[REDACTED]
wrap json
}
IP 匿名化(合规场景常用):
format filter {
request>client_ip ip_mask {
ipv4 24
ipv6 56
}
wrap json
}
或对 IP 做哈希(保留可关联性、隐藏明文):request>client_ip hash。
URL 查询参数处理——token、邮箱经常混在 query 里:
format filter {
request>uri query {
delete apikey
replace secret_code [REDACTED]
hash email_address
}
wrap json
}
值得一提的是,Caddy 默认就会抹除 Cookie、Set-Cookie、Authorization、Proxy-Authorization 四个头的值(显示为 REDACTED)——这一默认行为值得所有 Web 服务器学习。
反向场景:想要传统文本格式?
需要 Apache Common Log 这类纯文本格式时,可编译带 transform-encoder 插件的自定义镜像,然后 format transform "{common_log}"。但生产环境仍建议坚持 JSON——结构化是后续一切分析的前提。
采集并验证 Caddy 日志
文件部署可用 DataKit 的日志采集器读取 /var/log/caddy/access.log。先确认采集进程有读取权限,再配置 source、service 与 Pipeline;容器部署则沿用 stdout/stderr 的采集路径,避免同时采集同一份文件造成重复。
按 Pipeline 快速开始提取 JSON 字段。Caddy 的 status 是 HTTP 状态码,应提取为 http_status_code 等独立字段;将 level 映射为日志级别 status,并确认 ts 或自定义时间字段的格式和单位。发送一次正常请求和一次失败请求,核对时间、URI、状态码和耗时,再建立错误统计。
总结
Caddy 日志配置的主线:log 开启、output 定向、format 定形、filter 提纯。默认 JSON + 默认敏感头脱敏这两点,让它成为最容易接入现代化日志平台的 Web 服务器之一。
常见问题(FAQ)
Q:为什么我的 Caddy 容器里没有访问日志?
访问日志默认关闭,必须在站点的 log 块中显式开启;开启后 Docker 场景用 docker logs 即可看到 JSON 格式的请求记录。
Q:filter 能批量删除一类字段吗?
目前不支持通配符匹配,需逐字段列出 delete。用含敏感值的测试请求检查输出,确认需要删除的请求头和查询参数没有遗漏。
Q:ip_mask 和 hash 两种 IP 脱敏怎么选?
要做"同一访客"关联分析选 hash(相同 IP 哈希值恒定);只需按网段统计地理/运营商分布选 ip_mask。哈希和掩码不等于消除了重新识别风险,仍需评估其他字段能否关联到个人。
Q:Caddy 的 JSON 日志进观测云还要写 Pipeline 吗?
要按采集配置验证。JSON 便于用 Pipeline 提取字段,但时间、HTTP 状态码和日志级别仍需正确映射;Caddy 的 filter 负责输出前处理,不能替代采集端的解析验证。
系列阅读:Nginx 日志完全指南 | 日志格式化最佳实践