nginx可通过map指令解析$http_user_agent精准区分移动端与pc端并记录在日志中,再用awk实时统计占比;需注意ipad pro、微信桌面版等ua特殊性,优先匹配mobile标识,补充uc/qq等国产浏览器规则。

直接在 Nginx 日志中记录并区分移动端与 PC 端访问,核心是准确解析 $http_user_agent 字段,并通过自定义日志格式或后续分析实现比例统计——无需前端埋点,也不依赖第三方服务。
在 log_format 中加入设备类型标识
推荐在 nginx.conf 的 log_format 里定义一个变量 $ua_type,用 map 指令预先分类:
- 先在 http 块中声明映射规则(注意顺序和排除逻辑):
map $http_user_agent $ua_type {
default "pc";
~*[Mm]obile "mobile";
~*[Ii][Pp][Hh][Oo][Nn] "mobile";
~*[Ii][Pp][Aa][Dd] "mobile";
~*[Aa][Nn][Dd][Rr][Oo][Ii][Dd].*[Mm]obile "mobile";
~*[Mm]icro[Mm]essenger.*[Mm]obile "mobile";
~*[Ww]indows.*[Mm]obile "mobile";
~*[Mm]ac\s+[Oo][Ss]\s+[Xx].*[Mm]obile "mobile";
# 排除桌面特征(但保留含 Mobile 的 iPad Pro、Mac Catalyst 等)
~*[Ww]indows|*[Mm]ac\s+[Oo][Ss]\s+[Xx]|*[Ll]inux "pc";
~*[Aa][Nn][Dd][Rr][Oo][Ii][Dd].*(TV|Wear|Glass) "pc";
}- 然后在 log_format 中引用:
'$ua_type "$http_user_agent"' - 重启 Nginx 后,每条日志开头就会标记
mobile或pc,便于后续快速聚合
用 shell 命令实时统计今日占比
不需写脚本,一条命令链即可得出精确结果:
- 统计今日总请求数和移动端请求数:
total=$(grep "$(date +%d/%b/%Y)" /var/log/nginx/access.log | wc -l)
mobile=$(grep "$(date +%d/%b/%Y)" /var/log/nginx/access.log | grep -c "^\(mobile\|mobile\)" | awk '{print $1}')
# 更稳妥写法(若已用 $ua_type 记录):
mobile=$(awk -v d="$(date +%d/%b/%Y)" '$0 ~ d && $1 == "mobile" {c++} END{print c+0}' /var/log/nginx/access.log)
echo "移动端占比: $(awk "BEGIN{printf \"%.1f\", $mobile*100/$total}")%"- 该方式避开 UA 字符串重复扫描,效率高,且不受空 Referer、爬虫干扰(可配合
grep -v "bot\|crawler\|Go-http-client"过滤)
细化识别 iOS 与 Android 设备
若需拆解移动端内部结构,建议分两步提取,避免误判:
- iOS 设备(含 iPhone/iPad,不含 Mac):
grep -i "iphone\|ipad" access.log | grep -v "Mac OS X" | wc -l - Android 手机(排除 TV/Wear):
grep -i "android.*mobile" access.log | grep -v "TV\|Wear\|Glass" | wc -l - 微信内置浏览器单独计数:
grep -i "micromessenger.*mobile" access.log | wc -l
验证与避坑要点
实际分析中容易出错的几个关键细节:
-
iPad Pro 默认是桌面 UA:现代 iPad UA 同时含
Mac OS X和Mobile,必须保留Mobile判断优先级,不能简单排除Mac OS X -
微信浏览器属于移动端:UA 含
Micromessenger且含Mobile→ 应计入 mobile;仅含Micromessenger无Mobile→ 多为桌面版,归入 pc -
避免漏掉 UC、QQ 等国产浏览器:它们常带
UCBrowser、MQQBrowser,也应纳入 mobile 规则(加进 map 或 grep 条件)











