关键是在每个server块中用$server_port变量定义独立日志格式并绑定专属access_log,确保请求端口信息精准写入对应日志文件,重载后可验证端口值是否正确捕获。

要在多端口监听环境中清晰区分各端口的业务流量,关键不是只配 log_format,而是让日志格式真正携带端口标识,并与每个服务实例精准绑定。Nginx 的 $server_port 变量能准确反映当前 server 块监听的实际端口,配合合理配置,就能直观看到哪个请求走了哪个端口。
定义含 $server_port 的自定义日志格式
在 http 块中声明一个新格式,显式包含 $server_port:
- 格式名不能和内置名(如
main、combined)重复,例如命名为port_detail - 推荐写法:
log_format port_detail '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $server_port'; -
$server_port是 Nginx 运行时变量,值来自当前匹配的server { listen X; }中的 X,不是硬编码,也不依赖 Host 头
为每个端口 server 块单独指定 access_log
仅定义格式还不够,必须在每个 server 块里调用它:
- 不要复用全局
access_log指令;每个server块内都写一行access_log /path/to/port8080.log port_detail; - 路径建议用绝对路径(如
/var/log/nginx/site-a-8080.log),避免权限或相对路径解析歧义 - 确保该路径所在目录存在,且 Nginx worker 进程有写入权限(Linux 下常为
nginx或www-data用户)
验证端口信息是否真实写入
改完配置后必须重载(nginx -s reload)才能生效,然后手动触发访问测试:
- 分别用
curl http://localhost:8080/和curl http://localhost:8081/各发一次请求 - 查看对应日志文件末尾字段:如果每行最后是
8080或8081,说明$server_port已正确捕获 - 若始终显示 80 或 443,常见原因是 server 块未正确匹配(比如 listen 写成
listen *:8080但实际请求带了 Host 头触发了其他 server 块)
结合日志分析快速定位业务分布
有了带端口的日志,后续分析就简单直接:
- 统计各端口请求数:
awk '{print $NF}' site-a-8080.log | sort | uniq -c - 查某端口下的高频 URL:
awk '$NF==8080 {print $7}' access.log | sort | uniq -c | sort -nr | head -10 - 用 ELK 或 Grafana Loki 导入时,可将
$server_port作为结构化字段,直接做端口维度下钻分析











