Nginx日志格式自定义,记录访客UA与IP

Nginx默认的combined日志格式虽然包含了$remote_addr$http_user_agent,但字段顺序固定、可读性一般,也不方便后续用脚本或日志系统提取分析。
通过log_format指令自定义格式,你可以把访客IP、UA、请求时间、状态码等关键信息按自己的需求排列,让日志更直观、更好用。
下面从配置到验证一步步说明。

先搞清楚要记录哪些字段

在动手改配置前,先确认你真正需要哪些变量。
Nginx内置了大量日志变量,常用的有:

  • $remote_addr:直接连接Nginx的客户端IP,存在CDN或反向代理时可能是代理IP
  • $http_x_forwarded_for:经过代理时,记录原始客户端IP的请求头
  • $http_user_agent:访客浏览器或客户端的User-Agent字符串
  • $time_local:本地时间,格式如10/Oct/2024:14:30:00 +0800
  • $request:完整的请求行,包含方法、URI和协议版本
  • $status:HTTP响应状态码
  • $body_bytes_sent:发送给客户端的响应体字节数
  • $request_time:Nginx处理请求的总耗时,单位秒

如果你的网站前面套了CDN或负载均衡,$remote_addr拿到的会是CDN节点IP,此时需要结合$http_x_forwarded_for使用,具体在避坑部分会展开。

编辑Nginx配置文件定义日志格式

log_format指令必须写在http块内,不能写在server块里。
下面是宝塔面板和手动编译安装两种环境的操作路径。

宝塔面板环境:

  1. 登录宝塔后台,左侧菜单点击“网站”
  2. 找到目标站点,点击“设置”
  3. 选择“配置文件”,在http段或server段之前插入log_format定义
  4. 修改access_log指令引用新格式名

手动编译或apt/yum安装环境:

打开主配置文件,通常路径是/etc/nginx/nginx.conf,在http {}块内添加:

log_format detailed '$remote_addr - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" '
                   'UA:"$http_user_agent" '
                   'XFF:"$http_x_forwarded_for"';

然后在站点的server块中,把原来的access_log改成引用这个格式:

server {
    listen 80;
    server_name example.com;

    access_log /www/wwwlogs/example.com.log detailed;

    location / {
        root /www/wwwroot/example.com;
        index index.html;
    }
}

注意格式名detailed可以自定义,但必须与log_format定义的名字完全一致,大小写敏感。

让配置生效并验证日志输出

改完配置后,先测试语法再重载:

nginx -t

如果输出syntax is oktest is successful,说明语法没问题,执行重载:

nginx -s reload
# 或使用 systemctl reload nginx

重载不会中断现有连接,可以放心操作。
随后触发一次访问,然后查看日志文件尾部:

tail -n 5 /www/wwwlogs/example.com.log

你应该能看到类似这样的记录:

203.0.113.45 - - [10/Oct/2024:15:20:31 +0800] "GET /index.html HTTP/1.1" 200 1024 "-" UA:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" XFF:"-"

如果UA:后面是-,说明请求头里没有User-Agent,常见于curl或脚本请求,属于正常现象。

几个容易踩的坑

坑一:log_format位置放错。 如果写在server块内,Nginx会报directive "log_format" is not allowed here
必须放在http块内,且要在使用它的server块之前定义。

坑二:CDN场景下IP记录不准。 当网站接入CDN后,$remote_addr记录的是CDN回源IP,不是访客真实IP。
此时应优先使用$http_x_forwarded_for,但要注意这个头可以被伪造。
更稳妥的做法是在Nginx中配置set_real_ip_fromreal_ip_header,让$remote_addr直接变成真实IP,具体以你使用的CDN厂商文档为准。

坑三:日志文件权限或路径问题。 如果重载后日志文件没有生成,检查access_log指定的目录是否存在、Nginx运行用户是否有写权限。
宝塔环境下日志目录通常是/www/wwwlogs/,手动安装可能是/var/log/nginx/

坑四:格式字符串中的引号转义。 在Nginx配置里,格式字符串用单引号包裹,内部如果要用双引号,直接写"即可,不需要额外转义。
写成\"反而会多出反斜杠。

日志量大了怎么处理

自定义格式增加了UA和XFF字段后,单行日志会变长,磁盘占用和IO压力会上升。
如果站点访问量大,建议配合日志切割策略,比如logrotate每天轮转并压缩历史文件,同时评估是否需要把UA字段拆到独立日志或采样记录。
对于绝大多数中小站点,直接使用上述格式不会有明显负担,但定期清理旧日志仍然是必要的运维习惯。

常见疑问

修改后需要重启Nginx吗?
不需要。nginx -s reload即可平滑重载,新配置对后续请求立即生效。

为什么日志里UA字段显示为-
说明该请求没有携带User-Agent头。用curl测试时默认会带UA,如果显示-,检查请求是否人为去掉了该头,或客户端本身是脚本工具。

可以在同一个server块里同时用两种日志格式吗?
可以。你可以在server块中写多条access_log指令,分别指向不同格式和不同文件,但要注意每条都会产生写入开销。

自定义格式会影响已有日志分析脚本吗?
会。字段顺序和内容变了,依赖固定列位置的awk或正则脚本需要同步调整。建议先在测试环境验证,再应用到生产。

分享到:
上一篇
Nginx代理到内网网站,反向代理实战案例
下一篇
Nginx限流漏桶令牌桶算法,网站防CC原理
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意