mod_log_config仅记录最终响应码%>s,不区分代理或应用错误;需结合X-Upstream-Error等自定义响应头、环境变量或mod_lua注入notes来标识代理层5xx错误。

Apache 的 mod_log_config 不支持直接记录代理状态码(如 502、503、504)的来源或类型,因为它本身不区分“是后端返回的代理错误”还是“Apache 自身生成的状态码”。它只记录最终响应的 HTTP 状态码(用 %>s),而这个值已经是合并后的结果——无论请求是否经过反向代理(如 mod_proxy),只要 Apache 最终返回了 502,%>s 就会记为 502。
但如果你的目标是:识别并单独标记那些由代理层(如 mod_proxy)触发的上游错误状态码(尤其是 5xx 类),就需要结合代理行为特征和日志字段做间接判断。以下是几种实用、可落地的方式:
明确记录最终响应状态码(基础但必要)
%>s 是唯一能准确反映客户端实际收到的状态码的字段,必须保留:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy_access
CustomLog logs/proxy_access.log proxy_access
-
%>s记录的是发送给客户端的状态码,对代理场景完全适用。 - 如果后端挂了,
mod_proxy通常返回502 Bad Gateway、503 Service Unavailable或504 Gateway Timeout,这些都会如实出现在%>s中。
区分代理错误与应用错误(靠响应头线索)
Apache 在代理出错时,有时会添加特定响应头(取决于配置),例如:
-
mod_proxy默认会在 502/503/504 响应中设置X-Proxy-Error: 502或类似自定义头; - 或你主动在
ProxyErrorOverride on+ErrorDocument配合下注入标识头。
✅ 可行做法:让 mod_proxy 或后端 Java 应用统一注入一个标识头,比如:
# 在 Proxy 配置段中(如 <proxy>)
Header always set X-Proxy-Status "true" env=proxy_error
# 或更精细地:仅当 upstream 失败时设
SetEnvIf expr "%{REQUEST_STATUS} >= 500 && %{REQUEST_STATUS} <p>然后在日志中捕获:</p><pre class="brush:apache;toolbar:false;">LogFormat "%h %t \"%r\" %>s %b %{X-Proxy-Status}o" proxy_debug
CustomLog logs/proxy_debug.log proxy_debug
这样日志里就能看到 "upstream-failed" 标记,配合 %>s 即可确认是代理层问题。
利用 %{BALANCER_NAME}e 或 %{proxy-status}n 辅助定位(需 mod_proxy_balancer)
如果你用了负载均衡(如 mod_proxy_balancer),Apache 会在内部设置环境变量或 notes:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
-
%{BALANCER_NAME}e:记录当前选中的后端 balancer 名称; -
%{proxy-status}n:某些版本中mod_proxy会写入 note 表示代理状态(需 Lua 或自定义模块读取)。
⚠️ 注意:%{proxy-status}n 不是标准字段,原生不支持;但可通过 mod_lua 拦截响应并提取:
-- log_proxy_status.lua
function log_proxy_status(r)
local status = r.headers_out["X-Proxy-Status"] or r.env["proxy_status"] or "-"
r:note("proxy_status", status)
end
再配合:
LuaHookLog log_proxy_status.lua log_proxy_status
LogFormat "%h %t \"%r\" %>s %b %{proxy_status}n" with_proxy_note
推荐组合方案(Java + Apache 协同)
最可靠的方式是:由 Java 后端明确告知本次响应是否来自代理异常。
-
Spring Boot Filter 中检测
response.getStatus()属于502/503/504,且请求路径经过代理(如/api/**),则添加响应头:if (status >= 500 && status
-
Apache 日志中直接捕获:
LogFormat "%h %t \"%r\" %>s %b %{X-Upstream-Error}o" java_proxy_error
这样每条日志末尾出现 502 或 -,就清晰对应上游故障与否。
本质上,mod_log_config 不区分状态码来源,但你可以通过约定响应头 + 合理环境变量 + 后端协同,把“代理状态码数据”变成可过滤、可统计的结构化字段。










