Caddy 日志配置指南:JSON 结构化、字段过滤与敏感信息保护

Caddy 默认输出 JSON 结构化日志,但访问日志默认关闭。本文讲解 Caddy log 指令的开启方法、output/format 配置、filter 编码器的字段删除/重命名/IP 脱敏、查询参数处理,以及接入观测云实现集中监控的路径。

最佳实践
Caddy 日志配置指南:JSON 结构化、字段过滤与敏感信息保护技术指南封面

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 可选项:stdoutstderrfile(自带轮转,见上)、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 默认就会抹除 CookieSet-CookieAuthorizationProxy-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 提取)。之后在日志查看器中按 statusuri 分组统计、对异常请求做聚类分析 ;在监控器(日志检测)中配置"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 日志完全指南日志格式化最佳实践

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台