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 日志接入观测云后免切割直接检索,配合监控器即可对异常状态码告警。
开启访问日志: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——结构化是后续一切分析的前提。
接入观测云:天生 JSON 的红利
观测云落地:Caddy 的 JSON 输出与观测云天然契合。Docker 场景用 DataKit 容器 stdout 采集,直装场景用磁盘文件采集指向 /var/log/caddy/access.log ;JSON 日志自动解析出字段,Pipeline 只需做少量标准化(如把 status 映射为观测云标准状态字段、确认 time 提取)。之后在日志查看器中按 status、uri 分组统计、对异常请求做聚类分析 ;在监控器(日志检测)中配置"5xx 比例超阈值""特定路径访问量突增"等规则,经告警策略推送钉钉/企业微信/飞书 。若 Caddy 侧 filter 有遗漏的敏感字段,还可用观测云敏感数据扫描(70+ 预定义规则)在写入存储引擎前做二次脱敏,双保险不落盘 。
总结
Caddy 日志配置的主线:log 开启、output 定向、format 定形、filter 提纯。默认 JSON + 默认敏感头脱敏这两点,让它成为最容易接入现代化日志平台的 Web 服务器之一。
常见问题(FAQ)
Q:为什么我的 Caddy 容器里没有访问日志?
访问日志默认关闭,必须在站点的 log 块中显式开启;开启后 Docker 场景用 docker logs 即可看到 JSON 格式的请求记录。
Q:filter 能批量删除一类字段吗?
目前不支持通配符匹配,需逐字段列出 delete。字段很多时的替代思路是反向保留:只保留需要的字段(fields 白名单思路),或把精细清洗放到观测云 Pipeline 侧集中完成。
Q:ip_mask 和 hash 两种 IP 脱敏怎么选?
要做"同一访客"关联分析选 hash(相同 IP 哈希值恒定);只需按网段统计地理/运营商分布选 ip_mask。GDPR/个保法场景两者都可满足匿名化要求。
Q:Caddy 的 JSON 日志进观测云还要写 Pipeline 吗?
字段层面不需要——JSON 自动解析。Pipeline 只用于标准化(time/status 映射)或补脱敏;若 Caddy filter 已配置完善,可直接采集使用。
系列阅读:Nginx 日志完全指南 | 日志格式化最佳实践