fix: 修复手动代理节点请求不计数及延迟/心跳不显示的问题 (#368)

* fix: 修复手动代理节点请求不计数及延迟/心跳不显示的问题

问题描述:
- 手动添加的代理节点请求数始终为0,不会递增
- 手动代理节点的延迟和最后心跳时间不显示

根因:
Rust 重写版中缺失了 Python 版的手动代理节点请求计数逻辑。
隧道节点通过心跳上报计数,但手动节点没有心跳机制,
需要在 usage recording 路径中递增计数并更新延迟信息。

修复方案:
1. 在 ExecutionPlan 中提取 proxy 信息,注入到 request_metadata
2. 在 request_metadata 白名单中添加 proxy 字段
3. 新增 INCREMENT_MANUAL_PROXY_NODE_REQUESTS_SQL,
   递增 total_requests/failed_requests,
   同时更新 avg_latency_ms 和 last_heartbeat_at
4. 在 ProxyNodeWriteRepository trait 新增 increment_manual_node_requests 方法
5. 在 write_event_record 中解析 request_metadata 中的 proxy 信息,
   对非隧道模式的手动节点调用递增方法
6. 为 GatewayDataState 实现 ManualProxyNodeCounter trait

影响范围:
- 仅影响手动代理节点的统计数据
- 隧道节点不受影响(继续通过心跳计数)
- 不影响请求转发逻辑

* style: cargo fmt

---------

Co-authored-by: root <root@ser406777952330.local>
This commit is contained in:
jiuwovo-ai
2026-05-03 14:50:36 +08:00
committed by GitHub
parent c4ea042eb4
commit 3e2eca4fd0
9 changed files with 195 additions and 9 deletions

View File

@@ -1509,14 +1509,34 @@ fn build_runtime_request_metadata_seed(
let provider_request_has_inline_body =
context_has_inline_body(context, "provider_request_body")
|| plan_has_inline_json_body_for_usage(plan);
build_runtime_request_metadata_seed_from_parts(
let mut metadata = build_runtime_request_metadata_seed_from_parts(
context,
request_has_inline_body,
request_body_ref.as_deref(),
provider_request_has_inline_body,
provider_request_body_ref.as_deref(),
plan.body.body_bytes_b64.as_deref(),
)
);
if let Some(proxy) = plan.proxy.as_ref() {
if let Some(node_id) = proxy
.node_id
.as_deref()
.map(str::trim)
.filter(|v| !v.is_empty())
{
let mode = proxy.mode.as_deref().unwrap_or("").trim();
let mut proxy_obj = serde_json::Map::new();
proxy_obj.insert("node_id".to_string(), Value::String(node_id.to_string()));
if !mode.is_empty() {
proxy_obj.insert("mode".to_string(), Value::String(mode.to_string()));
}
let obj = metadata.get_or_insert_with(|| Value::Object(serde_json::Map::new()));
if let Value::Object(map) = obj {
map.insert("proxy".to_string(), Value::Object(proxy_obj));
}
}
}
metadata
}
fn build_runtime_request_metadata_seed_from_parts(