mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat: 请求候选记录中追踪代理节点信息并在前端 timeline 展示
This commit is contained in:
@@ -198,6 +198,19 @@
|
|||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="currentAttempt.extra_data?.proxy"
|
||||||
|
class="info-item"
|
||||||
|
>
|
||||||
|
<span class="info-label">代理</span>
|
||||||
|
<span class="info-value">
|
||||||
|
<span>{{ currentAttempt.extra_data.proxy.node_name || currentAttempt.extra_data.proxy.url || '未知' }}</span>
|
||||||
|
<span
|
||||||
|
v-if="currentAttempt.extra_data.proxy.source === 'system'"
|
||||||
|
class="text-xs text-muted-foreground ml-1"
|
||||||
|
>(系统)</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="mergedCapabilities.length > 0"
|
v-if="mergedCapabilities.length > 0"
|
||||||
class="info-item"
|
class="info-item"
|
||||||
|
|||||||
@@ -2654,6 +2654,8 @@ class CliMessageHandlerBase(BaseMessageHandler):
|
|||||||
"chunk_count": ctx.chunk_count,
|
"chunk_count": ctx.chunk_count,
|
||||||
"data_count": ctx.data_count,
|
"data_count": ctx.data_count,
|
||||||
}
|
}
|
||||||
|
if ctx.proxy_info:
|
||||||
|
extra_data["proxy"] = ctx.proxy_info
|
||||||
if candidate_first_byte_time_ms is not None:
|
if candidate_first_byte_time_ms is not None:
|
||||||
extra_data["first_byte_time_ms"] = candidate_first_byte_time_ms
|
extra_data["first_byte_time_ms"] = candidate_first_byte_time_ms
|
||||||
if ctx.is_client_disconnected():
|
if ctx.is_client_disconnected():
|
||||||
@@ -2680,6 +2682,8 @@ class CliMessageHandlerBase(BaseMessageHandler):
|
|||||||
"chunk_count": ctx.chunk_count,
|
"chunk_count": ctx.chunk_count,
|
||||||
"data_count": ctx.data_count,
|
"data_count": ctx.data_count,
|
||||||
}
|
}
|
||||||
|
if ctx.proxy_info:
|
||||||
|
extra_data["proxy"] = ctx.proxy_info
|
||||||
if ctx.rectified:
|
if ctx.rectified:
|
||||||
extra_data["rectified"] = True
|
extra_data["rectified"] = True
|
||||||
if candidate_first_byte_time_ms is not None:
|
if candidate_first_byte_time_ms is not None:
|
||||||
|
|||||||
@@ -351,6 +351,8 @@ class StreamTelemetryRecorder:
|
|||||||
}
|
}
|
||||||
if ctx.rectified:
|
if ctx.rectified:
|
||||||
extra_data["rectified"] = True
|
extra_data["rectified"] = True
|
||||||
|
if ctx.proxy_info:
|
||||||
|
extra_data["proxy"] = ctx.proxy_info
|
||||||
if ctx.first_byte_time_ms is not None:
|
if ctx.first_byte_time_ms is not None:
|
||||||
# 计算候选自身的 TTFB
|
# 计算候选自身的 TTFB
|
||||||
first_byte_time_ms = RequestCandidateService.calculate_candidate_ttfb(
|
first_byte_time_ms = RequestCandidateService.calculate_candidate_ttfb(
|
||||||
|
|||||||
@@ -180,17 +180,23 @@ class RequestExecutor:
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# 非流式请求:标记为 success 状态
|
# 非流式请求:标记为 success 状态
|
||||||
|
from src.clients.http_client import resolve_proxy_info
|
||||||
|
|
||||||
|
_extra: dict[str, Any] = {
|
||||||
|
"is_cached_user": is_cached_user,
|
||||||
|
"model_name": model_name,
|
||||||
|
"api_format": api_format,
|
||||||
|
}
|
||||||
|
_pi = resolve_proxy_info(getattr(provider, "proxy", None))
|
||||||
|
if _pi:
|
||||||
|
_extra["proxy"] = _pi
|
||||||
RequestCandidateService.mark_candidate_success(
|
RequestCandidateService.mark_candidate_success(
|
||||||
db=self.db,
|
db=self.db,
|
||||||
candidate_id=candidate_id,
|
candidate_id=candidate_id,
|
||||||
status_code=200,
|
status_code=200,
|
||||||
latency_ms=context.elapsed_ms,
|
latency_ms=context.elapsed_ms,
|
||||||
concurrent_requests=key_rpm_count,
|
concurrent_requests=key_rpm_count,
|
||||||
extra_data={
|
extra_data=_extra,
|
||||||
"is_cached_user": is_cached_user,
|
|
||||||
"model_name": model_name,
|
|
||||||
"api_format": api_format,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return ExecutionResult(response=response, context=context)
|
return ExecutionResult(response=response, context=context)
|
||||||
|
|||||||
@@ -699,6 +699,7 @@ class TaskService:
|
|||||||
"""
|
"""
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
|
from src.clients.http_client import resolve_proxy_info
|
||||||
from src.core.api_format.conversion.exceptions import FormatConversionError
|
from src.core.api_format.conversion.exceptions import FormatConversionError
|
||||||
from src.core.error_utils import extract_error_message
|
from src.core.error_utils import extract_error_message
|
||||||
from src.core.exceptions import (
|
from src.core.exceptions import (
|
||||||
@@ -710,12 +711,17 @@ class TaskService:
|
|||||||
)
|
)
|
||||||
from src.services.request.executor import ExecutionError
|
from src.services.request.executor import ExecutionError
|
||||||
|
|
||||||
|
# 提前解析代理信息,写入候选记录的 extra_data(用于链路追踪展示)
|
||||||
|
_proxy_info = resolve_proxy_info(getattr(candidate.provider, "proxy", None))
|
||||||
|
_proxy_extra: dict[str, Any] | None = {"proxy": _proxy_info} if _proxy_info else None
|
||||||
|
|
||||||
if not isinstance(exec_err, ExecutionError):
|
if not isinstance(exec_err, ExecutionError):
|
||||||
RequestCandidateService.mark_candidate_failed(
|
RequestCandidateService.mark_candidate_failed(
|
||||||
db=self.db,
|
db=self.db,
|
||||||
candidate_id=candidate_record_id,
|
candidate_id=candidate_record_id,
|
||||||
error_type=type(exec_err).__name__,
|
error_type=type(exec_err).__name__,
|
||||||
error_message=str(exec_err),
|
error_message=str(exec_err),
|
||||||
|
extra_data=_proxy_extra,
|
||||||
)
|
)
|
||||||
return "raise"
|
return "raise"
|
||||||
|
|
||||||
@@ -762,6 +768,7 @@ class TaskService:
|
|||||||
error_message=extract_error_message(cause),
|
error_message=extract_error_message(cause),
|
||||||
latency_ms=elapsed_ms,
|
latency_ms=elapsed_ms,
|
||||||
concurrent_requests=captured_key_concurrent,
|
concurrent_requests=captured_key_concurrent,
|
||||||
|
extra_data=_proxy_extra,
|
||||||
)
|
)
|
||||||
return "break"
|
return "break"
|
||||||
|
|
||||||
@@ -788,6 +795,7 @@ class TaskService:
|
|||||||
status_code=embedded_status,
|
status_code=embedded_status,
|
||||||
latency_ms=elapsed_ms,
|
latency_ms=elapsed_ms,
|
||||||
concurrent_requests=captured_key_concurrent,
|
concurrent_requests=captured_key_concurrent,
|
||||||
|
extra_data=_proxy_extra,
|
||||||
)
|
)
|
||||||
client_error.request_metadata = {
|
client_error.request_metadata = {
|
||||||
"provider": provider.name,
|
"provider": provider.name,
|
||||||
@@ -811,6 +819,7 @@ class TaskService:
|
|||||||
status_code=embedded_status,
|
status_code=embedded_status,
|
||||||
latency_ms=elapsed_ms,
|
latency_ms=elapsed_ms,
|
||||||
concurrent_requests=captured_key_concurrent,
|
concurrent_requests=captured_key_concurrent,
|
||||||
|
extra_data=_proxy_extra,
|
||||||
)
|
)
|
||||||
return "continue" if has_retry_left else "break"
|
return "continue" if has_retry_left else "break"
|
||||||
|
|
||||||
@@ -835,6 +844,8 @@ class TaskService:
|
|||||||
serializable_extra_data = {
|
serializable_extra_data = {
|
||||||
k: v for k, v in extra_data.items() if k != "converted_error"
|
k: v for k, v in extra_data.items() if k != "converted_error"
|
||||||
}
|
}
|
||||||
|
if _proxy_info:
|
||||||
|
serializable_extra_data["proxy"] = _proxy_info
|
||||||
|
|
||||||
if isinstance(converted_error, ThinkingSignatureException):
|
if isinstance(converted_error, ThinkingSignatureException):
|
||||||
action = self._handle_thinking_signature_error(
|
action = self._handle_thinking_signature_error(
|
||||||
@@ -910,6 +921,7 @@ class TaskService:
|
|||||||
error_message=extract_error_message(cause),
|
error_message=extract_error_message(cause),
|
||||||
latency_ms=elapsed_ms,
|
latency_ms=elapsed_ms,
|
||||||
concurrent_requests=captured_key_concurrent,
|
concurrent_requests=captured_key_concurrent,
|
||||||
|
extra_data=_proxy_extra,
|
||||||
)
|
)
|
||||||
return "continue" if has_retry_left else "break"
|
return "continue" if has_retry_left else "break"
|
||||||
|
|
||||||
@@ -922,6 +934,7 @@ class TaskService:
|
|||||||
error_message=str(cause),
|
error_message=str(cause),
|
||||||
latency_ms=elapsed_ms,
|
latency_ms=elapsed_ms,
|
||||||
concurrent_requests=captured_key_concurrent,
|
concurrent_requests=captured_key_concurrent,
|
||||||
|
extra_data=_proxy_extra,
|
||||||
)
|
)
|
||||||
return "break"
|
return "break"
|
||||||
|
|
||||||
@@ -932,6 +945,7 @@ class TaskService:
|
|||||||
error_message=extract_error_message(cause),
|
error_message=extract_error_message(cause),
|
||||||
latency_ms=elapsed_ms,
|
latency_ms=elapsed_ms,
|
||||||
concurrent_requests=captured_key_concurrent,
|
concurrent_requests=captured_key_concurrent,
|
||||||
|
extra_data=_proxy_extra,
|
||||||
)
|
)
|
||||||
return "raise"
|
return "raise"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user