$request_completion 是 Nginx 日志中标识请求是否完整结束的变量,值为“OK”表示正常完成,“”表示被客户端中断;需手动添加至 log_format 才可记录。

在 Web 服务器(尤其是 Nginx)日志中,$request_completion 是一个内置变量,用于标识当前 HTTP 请求是否**完整结束**。它本身不主动“导致”异常,但能帮你快速从日志里识别出那些**被客户端中断、超时或未完成的下载请求**——这正是排查大文件下载失败、断点续传异常、CDN 回源中断等问题的关键线索。
它是什么:一个仅含两个值的状态标记
$request_completion 不是时间戳、不是状态码,而是一个极简的字符串变量:
- “OK”:表示请求已正常走完整个生命周期(响应头已发送、响应体已全部发出、连接正常关闭);
-
空字符串(即
""):表示请求在完成前被中断——常见于用户关闭浏览器、网络闪断、手机切后台、curl 被 Ctrl+C、客户端主动断开 TCP 连接等场景。
注意:它和 $status(如 200/499/504)互补但不重复。例如,一个被用户中途取消的下载,$status 可能仍是 200(因为响应头已发),但 $request_completion 一定是空。
怎么用:把它加进你的 access_log 格式
默认日志不包含该变量。需手动修改 Nginx 配置,在 log_format 中加入:
log_format download_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_completion';然后在 server 或 location 块中启用:
access_log /var/log/nginx/download.log download_log;
重启 Nginx 后,日志行末尾就会多出一列:OK 或空白。对下载接口(如 /files/*)单独配置此日志格式,效果更聚焦。
怎么看:结合其他字段定位真实问题
单看 $request_completion 为空还不够,要联动分析:
-
查
$body_bytes_sent:若远小于文件总大小(比如下载 100MB 文件只发了 2MB 就中断),基本确认是客户端侧中断; -
查
$status:若为499(Client Closed Request),说明客户端在 Nginx 发送响应前就断开了,此时$request_completion必为空; -
查
$request_time:若耗时极短(如 0.001s)且$request_completion为空,大概率是探测性请求或爬虫试探; - 查 User-Agent:移动 App、wget、aria2 等工具中断行为模式不同,可辅助归因。
要注意:它的局限性
$request_completion 是 Nginx 的“主观判断”,依赖底层连接状态。以下情况它可能无法准确反映:
- 后端(如 FastCGI、proxy_pass)已崩溃,但 Nginx 还没检测到连接关闭,可能仍记为 “OK”;
- 使用了
sendfile on且内核直接传输,部分极端中断下 Nginx 可能来不及更新状态; - HTTP/2 流复用场景中,单个流中断不会关闭 TCP 连接,
$request_completion依然有效,但需结合$http2和$http2_stream_id分析。
它不是万能诊断器,而是帮你把“海量 200 日志”快速筛出“假成功真中断”的第一道过滤器。

















