refactor(proxy): simplify logging for better readability

- Delete 17 verbose debug logs from handlers, streaming, and response_processor
- Convert excessive INFO logs to DEBUG level for internal processing details
- Add 2 critical INFO logs in forwarder.rs for failover scenarios:
  - Log when switching to next provider after failure
  - Log when all providers have been exhausted
- Fix clippy uninlined_format_args warning

This reduces log noise while maintaining visibility into key user-facing decisions.
This commit is contained in:
YoVinchen
2026-01-10 16:07:53 +08:00
parent 6021274b82
commit 753190a879
5 changed files with 23 additions and 79 deletions
+12
View File
@@ -305,6 +305,14 @@ impl RequestForwarder {
Some(format!("Provider {} 失败: {}", provider.name, e));
}
log::info!(
"[{}] Provider {} 请求失败,切换到下一个 (已尝试 {}/{})",
app_type_str,
provider.name,
attempted_providers,
providers.len()
);
last_error = Some(e);
last_provider = Some(provider.clone());
// 继续尝试下一个供应商
@@ -360,6 +368,10 @@ impl RequestForwarder {
}
}
log::info!(
"[{app_type_str}] 所有 {attempted_providers} 个 Provider 均已尝试失败"
);
Err(ForwardError {
error: last_error.unwrap_or(ProxyError::MaxRetriesExceeded),
provider: last_provider,
+2 -3
View File
@@ -127,7 +127,7 @@ impl RequestContext {
.cloned()
.ok_or(ProxyError::NoAvailableProvider)?;
log::info!(
log::debug!(
"[{}] Provider: {}, model: {}, failover chain: {} providers, session: {}",
tag,
provider.name,
@@ -168,7 +168,6 @@ impl RequestContext {
.unwrap_or("unknown")
.to_string();
log::info!("[{}] 从 URI 提取模型: {}", self.tag, self.request_model);
self
}
@@ -190,7 +189,7 @@ impl RequestContext {
)
} else {
// 故障转移关闭:不启用超时配置
log::info!(
log::debug!(
"[{}] Failover disabled, timeout configs are bypassed",
self.tag
);
-52
View File
@@ -98,16 +98,6 @@ pub async fn handle_messages(
let adapter = get_adapter(&AppType::Claude);
let needs_transform = adapter.needs_transform(&ctx.provider);
log::info!(
"[Claude] Provider: {}, needs_transform: {}, is_stream: {}",
ctx.provider.name,
needs_transform,
is_stream
);
let status = response.status();
log::info!("[Claude] 上游响应状态: {status}");
// Claude 特有:格式转换处理
if needs_transform {
return handle_claude_transform(response, &ctx, &state, &body, is_stream).await;
@@ -131,8 +121,6 @@ async fn handle_claude_transform(
if is_stream {
// 流式响应转换 (OpenAI SSE → Anthropic SSE)
log::info!("[Claude] 开始流式响应转换 (OpenAI SSE → Anthropic SSE)");
let stream = response.bytes_stream();
let sse_stream = create_anthropic_sse_stream(stream);
@@ -196,13 +184,10 @@ async fn handle_claude_transform(
);
let body = axum::body::Body::from_stream(logged_stream);
log::info!("[Claude] ====== 请求结束 (流式转换) ======");
return Ok((headers, body).into_response());
}
// 非流式响应转换 (OpenAI → Anthropic)
log::info!("[Claude] 开始转换响应 (OpenAI → Anthropic)");
let response_headers = response.headers().clone();
let body_bytes = response.bytes().await.map_err(|e| {
@@ -211,31 +196,17 @@ async fn handle_claude_transform(
})?;
let body_str = String::from_utf8_lossy(&body_bytes);
log::info!("[Claude] OpenAI 响应长度: {} bytes", body_bytes.len());
log::debug!("[Claude] OpenAI 原始响应: {body_str}");
let openai_response: Value = serde_json::from_slice(&body_bytes).map_err(|e| {
log::error!("[Claude] 解析 OpenAI 响应失败: {e}, body: {body_str}");
ProxyError::TransformError(format!("Failed to parse OpenAI response: {e}"))
})?;
log::info!("[Claude] 解析 OpenAI 响应成功");
log::info!(
"[Claude] <<< OpenAI 响应 JSON:\n{}",
serde_json::to_string_pretty(&openai_response).unwrap_or_default()
);
let anthropic_response = transform::openai_to_anthropic(openai_response).map_err(|e| {
log::error!("[Claude] 转换响应失败: {e}");
e
})?;
log::info!("[Claude] 转换响应成功");
log::info!(
"[Claude] <<< Anthropic 响应 JSON:\n{}",
serde_json::to_string_pretty(&anthropic_response).unwrap_or_default()
);
// 记录使用量
if let Some(usage) = TokenUsage::from_claude_response(&anthropic_response) {
let model = anthropic_response
@@ -265,8 +236,6 @@ async fn handle_claude_transform(
});
}
log::info!("[Claude] ====== 请求结束 ======");
// 构建响应
let mut builder = axum::response::Response::builder().status(status);
@@ -285,11 +254,6 @@ async fn handle_claude_transform(
ProxyError::TransformError(format!("Failed to serialize response: {e}"))
})?;
log::info!(
"[Claude] 返回转换后的响应, 长度: {} bytes",
response_body.len()
);
let body = axum::body::Body::from(response_body);
builder.body(body).map_err(|e| {
log::error!("[Claude] 构建响应失败: {e}");
@@ -307,8 +271,6 @@ pub async fn handle_chat_completions(
headers: axum::http::HeaderMap,
Json(body): Json<Value>,
) -> Result<axum::response::Response, ProxyError> {
log::info!("[Codex] ====== /v1/chat/completions 请求开始 ======");
let mut ctx =
RequestContext::new(&state, &body, &headers, AppType::Codex, "Codex", "codex").await?;
@@ -317,12 +279,6 @@ pub async fn handle_chat_completions(
.and_then(|v| v.as_bool())
.unwrap_or(false);
log::info!(
"[Codex] 请求模型: {}, 流式: {}",
ctx.request_model,
is_stream
);
let forwarder = ctx.create_forwarder(&state);
let result = match forwarder
.forward_with_retry(
@@ -347,8 +303,6 @@ pub async fn handle_chat_completions(
ctx.provider = result.provider;
let response = result.response;
log::info!("[Codex] 上游响应状态: {}", response.status());
process_response(response, &ctx, &state, &OPENAI_PARSER_CONFIG).await
}
@@ -390,8 +344,6 @@ pub async fn handle_responses(
ctx.provider = result.provider;
let response = result.response;
log::info!("[Codex] 上游响应状态: {}", response.status());
process_response(response, &ctx, &state, &CODEX_PARSER_CONFIG).await
}
@@ -417,8 +369,6 @@ pub async fn handle_gemini(
.map(|pq| pq.as_str())
.unwrap_or(uri.path());
log::info!("[Gemini] 请求端点: {endpoint}");
let is_stream = body
.get("stream")
.and_then(|v| v.as_bool())
@@ -448,8 +398,6 @@ pub async fn handle_gemini(
ctx.provider = result.provider;
let response = result.response;
log::info!("[Gemini] 上游响应状态: {}", response.status());
process_response(response, &ctx, &state, &GEMINI_PARSER_CONFIG).await
}
+4 -13
View File
@@ -75,8 +75,6 @@ pub fn create_anthropic_sse_stream(
let mut current_block_type: Option<String> = None;
let mut tool_call_id = None;
log::info!("[Claude/OpenRouter] ====== 开始流式响应转换 ======");
tokio::pin!(stream);
while let Some(chunk) = stream.next().await {
@@ -96,25 +94,18 @@ pub fn create_anthropic_sse_stream(
for l in line.lines() {
if let Some(data) = l.strip_prefix("data: ") {
if data.trim() == "[DONE]" {
log::info!("[Claude/OpenRouter] <<< OpenAI SSE: [DONE]");
log::debug!("[Claude/OpenRouter] <<< OpenAI SSE: [DONE]");
let event = json!({"type": "message_stop"});
let sse_data = format!("event: message_stop\ndata: {}\n\n",
serde_json::to_string(&event).unwrap_or_default());
log::info!("[Claude/OpenRouter] >>> Anthropic SSE: message_stop");
log::debug!("[Claude/OpenRouter] >>> Anthropic SSE: message_stop");
yield Ok(Bytes::from(sse_data));
continue;
}
if let Ok(chunk) = serde_json::from_str::<OpenAIStreamChunk>(data) {
// 记录原始 OpenAI 事件(格式化显示)
if let Ok(json_value) = serde_json::from_str::<serde_json::Value>(data) {
log::info!(
"[Claude/OpenRouter] <<< OpenAI SSE 事件:\n{}",
serde_json::to_string_pretty(&json_value).unwrap_or_else(|_| data.to_string())
);
} else {
log::info!("[Claude/OpenRouter] <<< OpenAI SSE 数据: {data}");
}
// 仅在 DEBUG 级别简短记录 SSE 事件
log::debug!("[Claude/OpenRouter] <<< SSE chunk received");
if message_id.is_none() {
message_id = Some(chunk.id.clone());
+5 -11
View File
@@ -46,8 +46,6 @@ pub async fn handle_streaming(
state: &ProxyState,
parser_config: &UsageParserConfig,
) -> Response {
log::info!("[{}] 流式透传响应 (SSE)", ctx.tag);
let status = response.status();
let mut builder = axum::response::Response::builder().status(status);
@@ -152,8 +150,6 @@ pub async fn handle_non_streaming(
);
}
log::info!("[{}] ====== 请求结束 ======", ctx.tag);
// 构建响应
let mut builder = axum::response::Response::builder().status(status);
for (key, value) in response_headers.iter() {
@@ -493,16 +489,16 @@ pub fn create_logged_passthrough_stream(
if let Some(c) = &collector {
c.push(json_value.clone()).await;
}
log::info!(
"[{}] <<< SSE 事件:\n{}",
log::debug!(
"[{}] <<< SSE 事件: {}",
tag,
serde_json::to_string_pretty(&json_value).unwrap_or_else(|_| data.to_string())
data.chars().take(100).collect::<String>()
);
} else {
log::info!("[{tag}] <<< SSE 数据: {data}");
log::debug!("[{tag}] <<< SSE 数据: {}", data.chars().take(100).collect::<String>());
}
} else {
log::info!("[{tag}] <<< SSE: [DONE]");
log::debug!("[{tag}] <<< SSE: [DONE]");
}
}
}
@@ -523,8 +519,6 @@ pub fn create_logged_passthrough_stream(
}
}
log::info!("[{}] ====== 流结束 ======", tag);
if let Some(c) = collector.take() {
c.finish().await;
}