应使用 $server_protocol 变量记录协议版本,它原生支持 nginx 1.11.6+,可准确输出 http/1.1、http/2.0 等协商结果;需在 log_format 中添加该变量,并在 server 块中启用对应 access_log。

要在 Nginx 的 access_log 中记录响应所用的协议版本(如 HTTP/1.1、HTTP/2 或 HTTP/3),关键不是“响应协议”,而是客户端与 Nginx 建立连接时协商使用的应用层协议。Nginx 提供了内置变量 $server_protocol 和更准确的 $http_upgrade 配合其他上下文判断,但真正能直接、可靠反映当前请求所用协议的是 $server_protocol ——它表示 Nginx 接收请求时解析出的协议字符串,例如 HTTP/1.1 或 HTTP/2.0。
确认 $server_protocol 可用性
该变量无需额外模块,Nginx 1.11.6+ 原生支持(主流发行版默认满足)。它在每个请求处理阶段都有效,且不依赖 SSL 终止或反向代理配置。
- 对普通 HTTP/1.1 请求,值为
HTTP/1.1 - 对启用了 HTTP/2 的 HTTPS 请求(
listen 443 ssl http2;),值为HTTP/2.0 - 对启用 gRPC 或 ALPN 协商的场景,仍以实际协商的 HTTP 版本为准
在 log_format 中加入协议字段
在 http{} 块中定义日志格式,插入 $server_protocol:
log_format proto_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$server_protocol $request_time';
注意:不要用 $scheme(只返回 http 或 https)或 $server_port(端口号),它们无法区分 HTTP/1.1 与 HTTP/2。
在对应 server 块中启用该日志
将 access_log 指令放在实际处理请求的 server{} 块内(而非 http 全局块),确保作用域匹配:
server {
listen 80;
listen 443 ssl http2;
server_name example.com;
<pre class="brush:php;toolbar:false;"># 其他 SSL 配置(证书等)
access_log /var/log/nginx/protocol.log proto_log;}
若只关心 HTTPS + HTTP/2 流量,可单独为 443 端口配置;若需全站协议分布统计,两个 listen 行共用同一行 access_log 即可。
验证是否生效
重启 Nginx 后,用不同协议发起请求:
-
curl -v http://example.com→ 日志中应出现HTTP/1.1 -
curl -v --http2 https://example.com→ 应出现HTTP/2.0
查看日志:tail -n 1 /var/log/nginx/protocol.log,确认末尾字段为预期协议版本。











