Add server time to usage responses

This commit is contained in:
Novick Yuan
2026-05-28 14:30:15 +08:00
parent bb2fc2ec00
commit 8aca1f8b93
3 changed files with 43 additions and 3 deletions
@@ -11,7 +11,7 @@ use aether_admin::observability::usage::{
admin_usage_parse_limit, admin_usage_parse_offset, admin_usage_provider_key_name,
admin_usage_record_json, build_admin_usage_active_requests_response,
build_admin_usage_records_response, build_admin_usage_summary_stats_response_from_summary,
ADMIN_USAGE_DATA_UNAVAILABLE_DETAIL,
usage_server_now_unix_ms, ADMIN_USAGE_DATA_UNAVAILABLE_DETAIL,
};
use aether_data::repository::users::StoredUserSummary;
use aether_data_contracts::repository::{
@@ -315,6 +315,7 @@ fn build_admin_usage_records_response_with_attempt_flags(
.collect();
Json(json!({
"server_now_unix_ms": usage_server_now_unix_ms(),
"records": records,
"total": total,
"limit": limit,
@@ -29,6 +29,10 @@ use super::{
const USERS_ME_USAGE_DATA_UNAVAILABLE_DETAIL: &str = "用户用量数据暂不可用";
fn users_me_usage_server_now_unix_ms() -> u64 {
u64::try_from(Utc::now().timestamp_millis()).unwrap_or_default()
}
fn build_users_me_usage_reader_unavailable_response() -> Response<Body> {
build_auth_error_response(
http::StatusCode::SERVICE_UNAVAILABLE,
@@ -1071,6 +1075,7 @@ pub(super) async fn handle_users_me_usage_get(
.flatten();
let mut payload = json!({
"server_now_unix_ms": users_me_usage_server_now_unix_ms(),
"total_requests": total_requests,
"total_input_tokens": total_input_tokens,
"total_output_tokens": total_output_tokens,
@@ -1170,6 +1175,7 @@ pub(super) async fn handle_users_me_usage_active_get(
};
Json(json!({
"server_now_unix_ms": users_me_usage_server_now_unix_ms(),
"requests": items
.iter()
.map(build_users_me_usage_active_payload)
@@ -1365,12 +1371,13 @@ mod tests {
use std::collections::BTreeMap;
use aether_data_contracts::repository::usage::StoredRequestUsageAudit;
use chrono::Utc;
use serde_json::json;
use super::{
build_users_me_usage_active_payload, build_users_me_usage_record_payload,
users_me_usage_client_is_stream, users_me_usage_is_failed,
users_me_usage_upstream_is_stream,
users_me_usage_server_now_unix_ms, users_me_usage_upstream_is_stream,
};
fn sample_usage(status: &str) -> StoredRequestUsageAudit {
@@ -1415,6 +1422,17 @@ mod tests {
.expect("usage should build")
}
#[test]
fn users_me_usage_server_now_unix_ms_uses_epoch_millis() {
let before = u64::try_from(Utc::now().timestamp_millis()).unwrap_or_default();
let value = users_me_usage_server_now_unix_ms();
let after = u64::try_from(Utc::now().timestamp_millis()).unwrap_or_default();
assert!(value >= before);
assert!(value <= after);
assert!(value > 1_000_000_000_000);
}
#[test]
fn user_usage_record_payload_rehydrates_cache_creation_total_from_classified_fields() {
let item = StoredRequestUsageAudit {
+22 -1
View File
@@ -21,6 +21,10 @@ use url::form_urlencoded;
pub const ADMIN_USAGE_DATA_UNAVAILABLE_DETAIL: &str = "Admin usage data unavailable";
pub fn usage_server_now_unix_ms() -> u64 {
u64::try_from(chrono::Utc::now().timestamp_millis()).unwrap_or_default()
}
pub fn admin_usage_data_unavailable_response(detail: &'static str) -> Response<Body> {
(
http::StatusCode::SERVICE_UNAVAILABLE,
@@ -2275,7 +2279,11 @@ pub fn build_admin_usage_active_requests_response(
})
.collect();
Json(json!({ "requests": payload })).into_response()
Json(json!({
"server_now_unix_ms": usage_server_now_unix_ms(),
"requests": payload,
}))
.into_response()
}
#[allow(clippy::too_many_arguments)]
@@ -2306,6 +2314,7 @@ pub fn build_admin_usage_records_response(
.collect();
Json(json!({
"server_now_unix_ms": usage_server_now_unix_ms(),
"records": records,
"total": total,
"limit": limit,
@@ -2511,6 +2520,7 @@ mod tests {
admin_usage_matches_search, admin_usage_matches_status, admin_usage_matches_username,
admin_usage_record_json, admin_usage_resolve_request_capture_body,
admin_usage_total_tokens, admin_usage_upstream_is_stream, build_admin_usage_detail_payload,
usage_server_now_unix_ms,
};
use aether_data_contracts::repository::usage::{StoredRequestUsageAudit, UsageBodyField};
@@ -2560,6 +2570,17 @@ mod tests {
.expect("usage should build")
}
#[test]
fn usage_server_now_unix_ms_uses_epoch_millis() {
let before = u64::try_from(chrono::Utc::now().timestamp_millis()).unwrap_or_default();
let value = usage_server_now_unix_ms();
let after = u64::try_from(chrono::Utc::now().timestamp_millis()).unwrap_or_default();
assert!(value >= before);
assert!(value <= after);
assert!(value > 1_000_000_000_000);
}
#[test]
fn explicit_completed_status_wins_over_legacy_failure_fields() {
let item = sample_usage(