mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-12 14:10:19 +08:00
feat(gateway): harden failover and payload handling
Retry pre-response transport failures across candidates with an explicit stop policy, and propagate end-to-end timing into usage records and UI diagnostics. Remove legacy body, import, cookie, PII, and tunnel replay caps while preserving optional operator-configured gateway limits.
This commit is contained in:
@@ -165,7 +165,7 @@ impl UsageBodyCaptureEngine {
|
||||
apply_usage_body_capture_limit(
|
||||
UsageBodyField::RequestBody,
|
||||
"request",
|
||||
self.policy.max_request_body_bytes,
|
||||
None,
|
||||
payload.request_body,
|
||||
payload.request_body_ref,
|
||||
payload.request_body_state,
|
||||
@@ -174,7 +174,7 @@ impl UsageBodyCaptureEngine {
|
||||
apply_usage_body_capture_limit(
|
||||
UsageBodyField::ProviderRequestBody,
|
||||
"provider_request",
|
||||
self.policy.max_request_body_bytes,
|
||||
None,
|
||||
payload.provider_request_body,
|
||||
payload.provider_request_body_ref,
|
||||
payload.provider_request_body_state,
|
||||
@@ -183,7 +183,7 @@ impl UsageBodyCaptureEngine {
|
||||
apply_usage_body_capture_limit(
|
||||
UsageBodyField::ResponseBody,
|
||||
"response",
|
||||
self.policy.max_response_body_bytes,
|
||||
None,
|
||||
payload.response_body,
|
||||
payload.response_body_ref,
|
||||
payload.response_body_state,
|
||||
@@ -192,7 +192,7 @@ impl UsageBodyCaptureEngine {
|
||||
apply_usage_body_capture_limit(
|
||||
UsageBodyField::ClientResponseBody,
|
||||
"client_response",
|
||||
self.policy.max_response_body_bytes,
|
||||
None,
|
||||
payload.client_response_body,
|
||||
payload.client_response_body_ref,
|
||||
payload.client_response_body_state,
|
||||
|
||||
@@ -360,6 +360,10 @@ fn copy_allowed_metadata_fields(source: &Map<String, Value>, target: &mut Map<St
|
||||
copy_number(source, target, "client_response_body_base64_bytes");
|
||||
copy_non_null_value(source, target, "body_size");
|
||||
copy_number(source, target, "client_response_status_code");
|
||||
copy_number(source, target, "end_to_end_time_ms");
|
||||
copy_number(source, target, "end_to_end_first_byte_time_ms");
|
||||
copy_bool(source, target, "transport_error");
|
||||
copy_non_empty_string(source, target, "transport_error_type");
|
||||
copy_non_null_value(source, target, "billing_snapshot");
|
||||
copy_non_empty_string(source, target, "billing_snapshot_schema_version");
|
||||
copy_non_empty_string(source, target, "billing_snapshot_status");
|
||||
@@ -412,6 +416,10 @@ fn move_allowed_metadata_fields(mut source: Map<String, Value>, target: &mut Map
|
||||
remove_number(&mut source, target, "client_response_body_base64_bytes");
|
||||
remove_non_null_value(&mut source, target, "body_size");
|
||||
remove_number(&mut source, target, "client_response_status_code");
|
||||
remove_number(&mut source, target, "end_to_end_time_ms");
|
||||
remove_number(&mut source, target, "end_to_end_first_byte_time_ms");
|
||||
remove_bool(&mut source, target, "transport_error");
|
||||
remove_non_empty_string(&mut source, target, "transport_error_type");
|
||||
remove_non_null_value(&mut source, target, "billing_snapshot");
|
||||
remove_non_empty_string(&mut source, target, "billing_snapshot_schema_version");
|
||||
remove_non_empty_string(&mut source, target, "billing_snapshot_status");
|
||||
@@ -776,6 +784,10 @@ mod tests {
|
||||
"provider_request_body_base64_bytes": 512,
|
||||
"provider_response_body_base64_bytes": 1024,
|
||||
"client_response_body_base64_bytes": 2048,
|
||||
"end_to_end_time_ms": 10626,
|
||||
"end_to_end_first_byte_time_ms": 10120,
|
||||
"transport_error": true,
|
||||
"transport_error_type": "connect_timeout",
|
||||
"body_size": {
|
||||
"client_request_body": "1 KB",
|
||||
"provider_request_body": "4 KB",
|
||||
@@ -816,6 +828,10 @@ mod tests {
|
||||
"provider_request_body_base64_bytes": 512,
|
||||
"provider_response_body_base64_bytes": 1024,
|
||||
"client_response_body_base64_bytes": 2048,
|
||||
"end_to_end_time_ms": 10626,
|
||||
"end_to_end_first_byte_time_ms": 10120,
|
||||
"transport_error": true,
|
||||
"transport_error_type": "connect_timeout",
|
||||
"body_size": {
|
||||
"client_request_body": "1 KB",
|
||||
"provider_request_body": "4 KB",
|
||||
@@ -965,6 +981,10 @@ mod tests {
|
||||
"client_requested_stream": false,
|
||||
"upstream_is_stream": true,
|
||||
"api_key_is_standalone": true,
|
||||
"end_to_end_time_ms": 10626,
|
||||
"end_to_end_first_byte_time_ms": 10120,
|
||||
"transport_error": true,
|
||||
"transport_error_type": "connect_timeout",
|
||||
"provider_id": "provider-1",
|
||||
"model_id": "model-1",
|
||||
"global_model_id": "global-model-1",
|
||||
@@ -998,6 +1018,10 @@ mod tests {
|
||||
"client_requested_stream": false,
|
||||
"upstream_is_stream": true,
|
||||
"api_key_is_standalone": true,
|
||||
"end_to_end_time_ms": 10626,
|
||||
"end_to_end_first_byte_time_ms": 10120,
|
||||
"transport_error": true,
|
||||
"transport_error_type": "connect_timeout",
|
||||
"model_id": "model-1",
|
||||
"global_model_id": "global-model-1",
|
||||
"global_model_name": "gpt-5",
|
||||
@@ -1142,8 +1166,6 @@ mod tests {
|
||||
apply_usage_body_capture_policy_to_event(
|
||||
UsageBodyCapturePolicy {
|
||||
record_level: UsageRequestRecordLevel::Basic,
|
||||
max_request_body_bytes: Some(1024),
|
||||
max_response_body_bytes: Some(1024),
|
||||
},
|
||||
&mut event,
|
||||
);
|
||||
|
||||
@@ -44,22 +44,18 @@ pub enum UsageRequestRecordLevel {
|
||||
Full,
|
||||
}
|
||||
|
||||
pub const DEFAULT_USAGE_REQUEST_BODY_CAPTURE_LIMIT_BYTES: usize = 5 * 1024 * 1024;
|
||||
pub const DEFAULT_USAGE_RESPONSE_BODY_CAPTURE_LIMIT_BYTES: usize = 5 * 1024 * 1024;
|
||||
pub const DEFAULT_USAGE_REQUEST_BODY_CAPTURE_LIMIT_BYTES: usize = usize::MAX;
|
||||
pub const DEFAULT_USAGE_RESPONSE_BODY_CAPTURE_LIMIT_BYTES: usize = usize::MAX;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct UsageBodyCapturePolicy {
|
||||
pub record_level: UsageRequestRecordLevel,
|
||||
pub max_request_body_bytes: Option<usize>,
|
||||
pub max_response_body_bytes: Option<usize>,
|
||||
}
|
||||
|
||||
impl Default for UsageBodyCapturePolicy {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
record_level: UsageRequestRecordLevel::Full,
|
||||
max_request_body_bytes: Some(DEFAULT_USAGE_REQUEST_BODY_CAPTURE_LIMIT_BYTES),
|
||||
max_response_body_bytes: Some(DEFAULT_USAGE_RESPONSE_BODY_CAPTURE_LIMIT_BYTES),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user