Nginx日志自定义格式分析海外访客来源

为什么要自定义Nginx日志格式

默认的 Nginx 日志只记录最简单的访问行(请求地址、状态码、大小等),但如果你想搞清楚访问你网站的人是来自国内还是海外,甚至具体是哪个国家,默认格式就完全不够用了。
通过自定义日志格式,你可以加入 $remote_addr(客户端IP)、$http_user_agent(浏览器特征)、$http_x_forwarded_for(真实IP,如有代理)、以及 $geoip_country_code(如果安装了 GeoIP 模块)等变量。
有了这些,再用几行命令就能统计出海外访客的来源分布。

第一步:找到并修改 Nginx 配置文件

Nginx 的日志格式定义在 log_format 指令中,通常放在 http 块或某个 server 块里。
如果你用的是宝塔面板,配置文件路径一般是 /www/server/nginx/conf/nginx.conf
手动编译的话在 /etc/nginx/nginx.conf

打开配置文件,找到 http 段,在 access_log 指令之前加入或修改 log_format 段。
例如:

http {
    log_format  custom '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $body_bytes_sent '
                       '"$http_referer" "$http_user_agent" '
                       '$http_x_forwarded_for';
    access_log  /var/log/nginx/access.log  custom;
}

这里我们用 custom 作为格式名,然后在 access_log 中引用它。$http_x_forwarded_for 可以记录透传的真实IP(如果你使用了 CDN 或反向代理)。
如果你安装了 ngx_http_geoip_module,还可以加上 $geoip_country_code$geoip_country_name 直接得到国家代码及名称:

log_format  geoip '$remote_addr - $remote_user [$time_local] '
                  '"$request" $status $body_bytes_sent '
                  '"$http_referer" "$http_user_agent" '
                  '$geoip_country_code $geoip_country_name';

保存配置后执行 nginx -t 测试语法,然后 systemctl reload nginxnginx -s reload 使之生效。

第二步:用命令快速分析海外来源

即使没有 GeoIP 模块,你也可以通过日志中的 IP 地址来初步判断。
下面这个命令可以提取所有访问者的 IP 并统计出现次数:

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20

如果自定义格式里第一列是 IP,则 $1 就是 IP 地址。
拿到 IP 列表后,你可以直接去 ipip.netip-api.com 批量查询归属地。
更省事的方法是写一个简单的 Shell 脚本循环调用免费 API:

for ip in $(awk '{print $1}' access.log | sort -u); do
  curl -s "http://ip-api.com/json/$ip?fields=country" | grep -o '"country":"[^"]*"' | cut -d'"' -f4
done | sort | uniq -c | sort -nr

注意:免费 API 有频率限制(通常每分钟 45 次),建议先取一小部分样本试跑。

如果你已安装 ngx_http_geoip_module,上述日志格式直接记录了国家代码,可以这样统计:

awk '{print $NF}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

(假设国家代码是日志的最后一个字段)

避坑提醒

  • 日志格式长度log_format 换行时末尾不要漏掉单引号,否则 Nginx 会报错。
  • 字段顺序:如果你在格式中加入了 $http_x_forwarded_for,请确保它放在最后,否则可能因为存在空值而打乱后续字段解析。
  • GeoIP 模块ngx_http_geoip_module 需要编译时加入 --with-http_geoip_module,或者通过包管理器安装(如 nginx-extras),不是默认就有的。不确定的话先用 nginx -V 2>&1 | grep geoip 检查。
  • 日志轮转:修改格式后只会影响新写入的日志,历史日志保持不变。如果需要回溯,可以用 sed 重写旧日志,但更推荐直接用新的格式继续采集。

验证效果

执行以下命令实时查看最新日志:

tail -f /var/log/nginx/access.log

模拟一次海外访问(比如用在线代理打开你的网站),终端应显示类似:

123.45.67.89 - - [08/Apr/2025:14:30:00 +0000] "GET / HTTP/1.1" 200 1234 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" -

如果格式中包含 $geoip_country_code,则最后会显示例如 US United States

常见问题

Q:不想装 GeoIP 模块,有没有更简单的方式?
A:直接用 $remote_addr 记录 IP,然后使用离线 IP 数据库(如 GeoLite2)结合 awk 或 Python 脚本分析,或者直接复制 IP 到在线查询工具中手动验证。

Q:我的网站使用了 CDN,日志里都是 CDN 节点的 IP,怎么办?
A:在日志格式中加入 $http_x_forwarded_for(通常由 CDN 传过来),并在 Nginx 的 set_real_ip_fromreal_ip_header 指令中配置信任的 CDN IP 段,这样 $remote_addr 才会变成真实用户 IP。但要注意,$http_x_forwarded_for 可能包含多个 IP,需要解析第一个。

Q:修改日志格式会影响日志分析工具吗?
A:会的。如果你在用 Awstats、GoAccess 等工具,它们有各自的解析规则,修改格式后需要在工具配置中同步调整日志格式字符串。建议先备份旧格式,或者新建一个独立的 log_format 专门用于分析海外来源,不影响原有日志服务。

如果你正在处理 Nginx日志自定义格式分析海外访客来源,建议先按本文步骤完整执行,再根据自己的环境做微调;
遇到异常时优先回看避坑和高频问题部分。

分享到:
上一篇
宝塔面板批量清理网站垃圾缓存与日志
下一篇
数据库连接池耗尽参数优化外贸站点
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意