mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
fix(dashboard): 修复仪表盘与明细统计数值不一致并重建 cost_savings 聚合
- 统一 dashboard 聚合与 raw 查询的 token 计算,拆分今日节省和周期节省 - cache savings 改用 input price 估算未命中成本,修复历史 cost_savings 偏高 - raw 查询 total_tokens 改用 effective_input + output + cache_creation + cache_read 公式 - 新增独立 backfill 重建历史 cost_savings 聚合表,保留已发布 backfill 不变
This commit is contained in:
@@ -321,6 +321,7 @@ async fn gateway_handles_admin_dashboard_stats_locally_without_proxying_upstream
|
||||
openai_usage.cache_read_input_tokens = 800;
|
||||
openai_usage.cache_read_cost_usd = 0.01;
|
||||
openai_usage.output_price_per_1m = Some(100.0);
|
||||
openai_usage.request_metadata = Some(json!({ "input_price_per_1m": 20.0 }));
|
||||
|
||||
let mut claude_usage = sample_user_usage_audit(
|
||||
"usage-dashboard-admin-2",
|
||||
@@ -342,6 +343,27 @@ async fn gateway_handles_admin_dashboard_stats_locally_without_proxying_upstream
|
||||
claude_usage.cache_read_input_tokens = 200;
|
||||
claude_usage.cache_read_cost_usd = 0.005;
|
||||
claude_usage.output_price_per_1m = Some(100.0);
|
||||
claude_usage.request_metadata = Some(json!({ "input_price_per_1m": 20.0 }));
|
||||
|
||||
let mut prior_usage = sample_user_usage_audit(
|
||||
"usage-dashboard-admin-4",
|
||||
"req-dashboard-admin-4",
|
||||
"user-auth-1",
|
||||
"gpt-5",
|
||||
"openai",
|
||||
"completed",
|
||||
now - chrono::Duration::days(1),
|
||||
);
|
||||
prior_usage.input_tokens = 2_000;
|
||||
prior_usage.output_tokens = 500;
|
||||
prior_usage.total_tokens = 2_500;
|
||||
prior_usage.cache_creation_input_tokens = 0;
|
||||
prior_usage.cache_creation_ephemeral_5m_input_tokens = 0;
|
||||
prior_usage.cache_creation_ephemeral_1h_input_tokens = 0;
|
||||
prior_usage.cache_read_input_tokens = 1_000;
|
||||
prior_usage.cache_read_cost_usd = 0.01;
|
||||
prior_usage.output_price_per_1m = Some(100.0);
|
||||
prior_usage.request_metadata = Some(json!({ "input_price_per_1m": 30.0 }));
|
||||
|
||||
let mut streaming_usage = sample_user_usage_audit(
|
||||
"usage-dashboard-admin-3",
|
||||
@@ -358,6 +380,7 @@ async fn gateway_handles_admin_dashboard_stats_locally_without_proxying_upstream
|
||||
let usage_repository = Arc::new(InMemoryUsageReadRepository::seed(vec![
|
||||
openai_usage,
|
||||
claude_usage,
|
||||
prior_usage,
|
||||
streaming_usage,
|
||||
]));
|
||||
let user_repository = Arc::new(
|
||||
@@ -487,7 +510,11 @@ async fn gateway_handles_admin_dashboard_stats_locally_without_proxying_upstream
|
||||
.await;
|
||||
|
||||
let response = reqwest::Client::new()
|
||||
.get(format!("{gateway_url}/api/dashboard/stats"))
|
||||
.get(format!(
|
||||
"{gateway_url}/api/dashboard/stats?start_date={}&end_date={}",
|
||||
(now - chrono::Duration::days(1)).date_naive(),
|
||||
now.date_naive(),
|
||||
))
|
||||
.header("authorization", format!("Bearer {access_token}"))
|
||||
.header("x-client-device-id", "device-dashboard-stats-admin")
|
||||
.header("user-agent", "AetherTest/1.0")
|
||||
@@ -500,8 +527,8 @@ async fn gateway_handles_admin_dashboard_stats_locally_without_proxying_upstream
|
||||
assert_eq!(payload["today"]["requests"], 2);
|
||||
assert_eq!(payload["today"]["tokens"], 17_450);
|
||||
assert_eq!(payload["today"]["cost"], json!(2.5));
|
||||
assert_eq!(payload["cost_stats"]["cost_savings"], json!(0.085));
|
||||
assert_eq!(payload["stats"][2]["subValue"], json!("节省 $0.09"));
|
||||
assert_eq!(payload["cost_stats"]["cost_savings"], json!(0.025));
|
||||
assert_eq!(payload["stats"][2]["subValue"], json!("节省 $0.01"));
|
||||
assert_eq!(payload["stats"][0]["value"], json!("2"));
|
||||
assert_eq!(payload["stats"][1]["value"], json!("17.4K"));
|
||||
assert_eq!(
|
||||
@@ -561,34 +588,40 @@ async fn gateway_handles_dashboard_daily_stats_locally_without_proxying_upstream
|
||||
"refresh-dashboard-daily-stats",
|
||||
now,
|
||||
);
|
||||
let mut today_openai_usage = sample_user_usage_audit(
|
||||
"usage-dashboard-daily-1",
|
||||
"req-dashboard-daily-1",
|
||||
"user-auth-1",
|
||||
"gpt-5",
|
||||
"openai",
|
||||
"completed",
|
||||
now - chrono::Duration::hours(1),
|
||||
);
|
||||
today_openai_usage.total_tokens = 160;
|
||||
let mut today_claude_usage = sample_user_usage_audit(
|
||||
"usage-dashboard-daily-2",
|
||||
"req-dashboard-daily-2",
|
||||
"user-auth-2",
|
||||
"claude-3-7",
|
||||
"claude",
|
||||
"completed",
|
||||
now - chrono::Duration::hours(2),
|
||||
);
|
||||
today_claude_usage.total_tokens = 160;
|
||||
let mut prior_usage = sample_user_usage_audit(
|
||||
"usage-dashboard-daily-3",
|
||||
"req-dashboard-daily-3",
|
||||
"user-auth-3",
|
||||
"gpt-5",
|
||||
"openai",
|
||||
"completed",
|
||||
now - chrono::Duration::days(1) - chrono::Duration::hours(2),
|
||||
);
|
||||
prior_usage.total_tokens = 160;
|
||||
let usage_repository = Arc::new(InMemoryUsageReadRepository::seed(vec![
|
||||
sample_user_usage_audit(
|
||||
"usage-dashboard-daily-1",
|
||||
"req-dashboard-daily-1",
|
||||
"user-auth-1",
|
||||
"gpt-5",
|
||||
"openai",
|
||||
"completed",
|
||||
now - chrono::Duration::hours(1),
|
||||
),
|
||||
sample_user_usage_audit(
|
||||
"usage-dashboard-daily-2",
|
||||
"req-dashboard-daily-2",
|
||||
"user-auth-2",
|
||||
"claude-3-7",
|
||||
"claude",
|
||||
"completed",
|
||||
now - chrono::Duration::hours(2),
|
||||
),
|
||||
sample_user_usage_audit(
|
||||
"usage-dashboard-daily-3",
|
||||
"req-dashboard-daily-3",
|
||||
"user-auth-3",
|
||||
"gpt-5",
|
||||
"openai",
|
||||
"completed",
|
||||
now - chrono::Duration::days(1) - chrono::Duration::hours(2),
|
||||
),
|
||||
today_openai_usage,
|
||||
today_claude_usage,
|
||||
prior_usage,
|
||||
]));
|
||||
|
||||
let (gateway_url, upstream_hits, gateway_handle, upstream_handle) =
|
||||
@@ -636,6 +669,7 @@ async fn gateway_handles_dashboard_daily_stats_locally_without_proxying_upstream
|
||||
assert_eq!(daily_stats[0]["unique_providers"], 1);
|
||||
assert_eq!(daily_stats[1]["date"], json!(now.date_naive().to_string()));
|
||||
assert_eq!(daily_stats[1]["requests"], 2);
|
||||
assert_eq!(daily_stats[1]["tokens"], 320);
|
||||
assert_eq!(daily_stats[1]["unique_models"], 2);
|
||||
assert_eq!(daily_stats[1]["unique_providers"], 2);
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user