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 字段提取,并区分 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 日志完全指南 | 日志格式化最佳实践

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台