自定义 log_format 用了 $http_user_agent,日志里只剩 Mozilla/5.0 (compatible; 一截,Googlebot 和 bingbot 完全区分不出来,按爬虫拆的报表全废。

一开始怀疑是「UA 里的引号没转义,被日志解析器截在引号处」,查了一圈,方向不对。

真正麻烦的地方在于,几个原因的现象几乎一样。日志采集端对字段做了长度截断,源站记录其实完整。也可能是log_format 里用了旧变量名,取到的是空值。

还有一种情况,反向代理先改写了 UA,源站拿到的是缩短版本。

上来先确认源站日志里的 UA 是否完整

grep -m1 Googlebot access.log

再往下改用 escape=json 输出完整 UA

log_format json escape=json '{"ua":"$http_user_agent","ip":"$remote_addr"}';

随后按 UA 前缀分类统计

grep -oE 'compatible; [A-Za-z-]+bot' access.log | sort | uniq -c

剩下的就是验证代理层没有改写 UA

curl -s https://www.example.com/ -A "Mozilla/5.0 (compatible; Googlebot/2.1)" -o /dev/null -w "%{http_code}"

那几天正好在做别的变更,先把时间线对齐才敢动手。

恢复的判定其实很直接。日志里能完整看到 Googlebot/2.1 和 bingbot/2.0,按爬虫分类的占比与实际抓取量一致。

补一句。UA 一旦被截断,所有按爬虫拆分的报表都不可信,先把原始 UA 落全再谈分析。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189