需分两层实现:一是配置含$upstream_addr、$upstream_status等变量的自定义日志格式记录转发详情;二是通过nginx-upstream-check-module主动健康检查,结合/status接口与error_log中的状态变更提示(如“is down”)捕获节点上下线事件。

要在 Nginx 负载均衡集群中同时记录请求转发详情和后端节点状态,需分两层处理:一是精准捕获每次请求实际发往哪个节点、耗时多少、返回码如何;二是感知节点健康变化(如从 up 切为 down),并留下可追溯的痕迹。纯开源 Nginx 不自带节点状态变更日志,但通过变量组合、模块扩展与日志解析,完全可以构建出实用可观测体系。
配置带上游信息的转发日志格式
这是记录请求分发行为的基础。在 http 块中定义专用日志格式,必须包含以下关键变量:
- $upstream_addr:实际转发的目标地址(IP:port),失败重试时会以逗号分隔多个地址
- $upstream_status:对应每个转发动作的 HTTP 状态码,顺序与 $upstream_addr 一致
- $upstream_response_time:各次转发耗时(秒,毫秒精度),同样按逗号分隔
- $request_time:客户端完整请求总耗时,用于对比识别慢节点或超时异常
示例配置:
log_format upstream_log '[$time_local] $remote_addr "$request" '
'upstream:$upstream_addr status:$upstream_status '
'rt:$upstream_response_time req:$request_time';
然后在 server 或 location 块中启用:
access_log /var/log/nginx/upstream.log upstream_log;
启用主动健康检查并暴露状态接口
仅靠访问日志无法得知节点是否被标记为不可用。需借助 nginx-upstream-check-module(需编译安装)实现周期性探测:
- 在 upstream 块中添加 check 指令,例如:
check interval=3 rise=2 fall=3 timeout=1 type=http; - 配合 check_http_send 和 check_http_expect_alive 自定义探测请求与成功条件(如期望返回 200)
- 添加 location /status { check_status; } 暴露 HTML 或 JSON 格式实时状态页
该接口输出可被脚本定时抓取、比对,发现 status 字段变化即写入独立状态日志文件,形成节点上下线时间线。
捕获节点状态变更事件到 error_log
部分健康检查模块(如 nginx-upstream-check-module 或 OpenResty 的 lua-resty-upstream-healthcheck)会在节点状态切换时自动输出提示行到 error_log:
- 确保 error_log 级别设为 notice 或更高
- 搜索类似 "upstream check: server 192.168.1.10:8000 is down" 的日志条目
- 可配合 grep -i "is down\|is up" 实时过滤,或用 Filebeat 等工具提取结构化事件
若需更灵活控制(如触发告警、写入数据库),推荐使用 OpenResty + Lua,在状态变化回调中调用 ngx.log 或执行外部命令。
补充建议:日志归集与分析
单机日志价值有限,集群场景下应考虑集中化处理:
- 用 syslog 协议将 access_log 和 error_log 实时转发至日志中心(如 ELK 或 Loki)
- 对 $upstream_addr 字段做聚合统计,可快速看出各节点请求数、错误率、平均响应时间
- 结合 Prometheus + nginx-vts-exporter 或 custom metrics,把节点状态、活跃连接数等指标纳入监控大盘
不复杂但容易忽略。











