Nginx需通过ngx_http_geoip2_module模块结合GeoLite2数据库注入地理字段(国家、城市、经纬度)至日志,再用awk等工具统计或ELK/GoAccess可视化分析;精度依赖IP库,城市级识别率约50–80%。

要分析 Nginx 访问日志中的地理位置信息,核心是:先让 Nginx 在记录日志时包含 GeoIP 数据(如国家、城市、经纬度),再用日志分析工具提取和统计这些字段。
启用 Nginx 的 GeoIP 模块并注入地理字段
Nginx 本身不内置 GeoIP 功能,需依赖模块(旧版用 ngx_http_geoip_module,新版推荐 ngx_http_geoip2_module + MaxMind GeoLite2 数据库)。
- 安装 libmaxminddb 和 ngx_http_geoip2_module(编译进 Nginx 或作为动态模块加载)
- 下载 GeoLite2-Country.mmdb 和/或 GeoLite2-City.mmdb,放在安全路径(如
/usr/share/GeoIP/) - 在
http块中配置:
load_module modules/ngx_http_geoip2_module.so;
geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
$geoip2_data_country_code source=$remote_addr country iso_code;
$geoip2_data_city_name source=$remote_addr city name;
$geoip2_data_latitude source=$remote_addr location latitude;
$geoip2_data_longitude source=$remote_addr location longitude;
}然后在 log_format 中引用这些变量:
log_format geoip '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$geoip2_data_country_code "$geoip2_data_city_name" '
'$geoip2_data_latitude $geoip2_data_longitude';最后在 server 或 location 中启用该格式:access_log /var/log/nginx/access.log geoip;
验证日志是否写入地理字段
重启 Nginx 后,发起几个不同地区 IP 的请求(可用代理或 curl 指定 X-Forwarded-For),然后检查日志:
tail -n 5 /var/log/nginx/access.log
正常输出类似:
203.123.45.67 - - [10/Jul/2024:14:22:33 +0800] "GET / HTTP/1.1" 200 1234 "-" "curl/7.68.0" CN "Beijing" 39.9042 116.4074
若城市/经纬度为空,常见原因:IP 不在数据库中、$remote_addr 是内网地址(需配合 real_ip 模块还原真实客户端 IP)、路径权限错误或 mmdb 文件版本不匹配。
用命令行快速分析地理分布
利用 awk、sort、uniq 统计热门国家或城市:
- 按国家代码统计请求数:
awk '{print $13}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10 - 按城市名统计(注意字段位置可能因日志格式变化,建议用
awk -F'"' '{print $4}'提取双引号内城市名) - 导出为 CSV 供 Excel 或 Python 处理:
awk -F'"' '{printf "%s,%s,%s,%s\n", $1, $13, $15, $17}' /var/log/nginx/access.log > geo.csv
进阶:可视化与实时分析
单纯看文本效率低,可对接更强大的工具:
- ELK Stack(Elasticsearch + Logstash + Kibana):Logstash 用 geoip filter 自动解析 IP(无需 Nginx 预处理),Kibana 可直接画世界地图热力图
-
GoAccess:支持 GeoIP2,启动时加
--geoip-database=/path/GeoLite2-City.mmdb,终端内直接查看地理分布面板 -
Python + pandas + plotly:读取日志后用
geopandas渲染散点图,或调用高德/百度地图 API 补充行政区划层级
注意:所有方案都依赖 IP 库精度——GeoLite2 免费版对国家识别准确率约 99.8%,城市级通常在 50–80%(尤其国内小运营商出口 IP 归属常偏差)。


















