把 Nginx 换成 Caddy 2.8 之后,日志变成一行一个 JSON。统计脚本还按旧格式取第 12 列,蜘蛛抓取量直接变成 0,实际上日志里每条都有 UA。

原因不止一个,得分开看。Caddy 默认输出 JSON,UA 放在 request.headers.User-Agent 这个嵌套键下;脚本用空格切列,JSON 里的空格把一条记录切成了十几段;部分爬虫请求的 UA 键名被规范化成小写 user-agent;日志里 header 值是数组,取值时只拿到了第一个元素。

先看一条完整记录确认字段层级

tail -1 access.log | python -m json.tool | head -30

再往下用 jq 按 request.headers 取值统计

jq -r 'select(.request.headers."User-Agent"[0] | test("Baiduspider")) | .request.uri' access.log | wc -l

然后统计脚本改成读 JSON 而不是切列

python stat.py --format caddy-json --ua-field request.headers

保留一份原始日志便于回溯

zstd -19 access.log -o access-20261114.log.zst

别只看报错消失,验证要多做一步。jq 统计出的蜘蛛请求数与线上限流计数一致,报表恢复出量级正常的抓取曲线,脚本也不再因为解析失败中断。

这里还有个坑。换 Web 服务器时日志格式必须一起改,统计脚本里写死的列号是最容易忘的一处,建议先用一天日志跑通再切流量。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189