mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
feat(gateway/data): 新增 usage 关键词搜索、缓存命中摘要、结算成本摘要及 dashboard 聚合查询能力
- 新增 UsageAuditKeywordSearchQuery,支持多关键词、用户名、API Key 交叉过滤 - 新增 UsageCacheHitSummaryQuery/StoredUsageCacheHitSummary,统计请求缓存命中率 - 新增 UsageSettledCostSummaryQuery/StoredUsageSettledCostSummary,汇总结算成本 - 新增 UsageDashboardSummaryQuery、UsageBreakdownSummaryQuery 等 dashboard 聚合类型 - SQL 层实现对应查询方法,含 list_by_ids、list_usage_audits_by_keyword_search、count_usage_audits_by_keyword_search - 将上述能力通过 GatewayDataState / AdminAppState 暴露给 handler 层 - user_me_usage 及 dashboard_filters 切换为新查询接口,移除旧的内存过滤逻辑 - 同步更新 memory 层及测试
This commit is contained in:
@@ -2425,6 +2425,20 @@ impl GatewayDataState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_auth_api_key_export_records_by_name_search(
|
||||
&self,
|
||||
name_search: &str,
|
||||
) -> Result<Vec<StoredAuthApiKeyExportRecord>, DataLayerError> {
|
||||
match &self.auth_api_key_reader {
|
||||
Some(repository) => {
|
||||
repository
|
||||
.list_export_api_keys_by_name_search(name_search)
|
||||
.await
|
||||
}
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_auth_api_key_export_standalone_records_page(
|
||||
&self,
|
||||
query: &aether_data::repository::auth::StandaloneApiKeyExportListQuery,
|
||||
|
||||
@@ -646,6 +646,16 @@ impl GatewayDataState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_request_usage_by_ids(
|
||||
&self,
|
||||
usage_ids: &[String],
|
||||
) -> Result<Vec<StoredRequestUsageAudit>, DataLayerError> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.list_by_ids(usage_ids).await,
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn resolve_request_usage_body_ref(
|
||||
&self,
|
||||
body_ref: &str,
|
||||
@@ -676,6 +686,26 @@ impl GatewayDataState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_usage_audits_by_keyword_search(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageAuditKeywordSearchQuery,
|
||||
) -> Result<Vec<StoredRequestUsageAudit>, DataLayerError> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.list_usage_audits_by_keyword_search(query).await,
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn count_usage_audits_by_keyword_search(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageAuditKeywordSearchQuery,
|
||||
) -> Result<u64, DataLayerError> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.count_usage_audits_by_keyword_search(query).await,
|
||||
None => Ok(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn aggregate_usage_audits(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageAuditAggregationQuery,
|
||||
@@ -702,6 +732,181 @@ impl GatewayDataState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_cache_hit_summary(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageCacheHitSummaryQuery,
|
||||
) -> Result<aether_data_contracts::repository::usage::StoredUsageCacheHitSummary, DataLayerError>
|
||||
{
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.summarize_usage_cache_hit_summary(query).await,
|
||||
None => {
|
||||
Ok(aether_data_contracts::repository::usage::StoredUsageCacheHitSummary::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_settled_cost(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageSettledCostSummaryQuery,
|
||||
) -> Result<
|
||||
aether_data_contracts::repository::usage::StoredUsageSettledCostSummary,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.summarize_usage_settled_cost(query).await,
|
||||
None => Ok(
|
||||
aether_data_contracts::repository::usage::StoredUsageSettledCostSummary::default(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_cache_affinity_hit_summary(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageCacheAffinityHitSummaryQuery,
|
||||
) -> Result<
|
||||
aether_data_contracts::repository::usage::StoredUsageCacheAffinityHitSummary,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository
|
||||
.summarize_usage_cache_affinity_hit_summary(query)
|
||||
.await,
|
||||
None => Ok(
|
||||
aether_data_contracts::repository::usage::StoredUsageCacheAffinityHitSummary::default(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_usage_cache_affinity_intervals(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageCacheAffinityIntervalQuery,
|
||||
) -> Result<
|
||||
Vec<aether_data_contracts::repository::usage::StoredUsageCacheAffinityIntervalRow>,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.list_usage_cache_affinity_intervals(query).await,
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_dashboard_usage(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageDashboardSummaryQuery,
|
||||
) -> Result<aether_data_contracts::repository::usage::StoredUsageDashboardSummary, DataLayerError>
|
||||
{
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.summarize_dashboard_usage(query).await,
|
||||
None => Ok(
|
||||
aether_data_contracts::repository::usage::StoredUsageDashboardSummary::default(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_dashboard_daily_breakdown(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageDashboardDailyBreakdownQuery,
|
||||
) -> Result<
|
||||
Vec<aether_data_contracts::repository::usage::StoredUsageDashboardDailyBreakdownRow>,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.list_dashboard_daily_breakdown(query).await,
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_dashboard_provider_counts(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageDashboardProviderCountsQuery,
|
||||
) -> Result<
|
||||
Vec<aether_data_contracts::repository::usage::StoredUsageDashboardProviderCount>,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.summarize_dashboard_provider_counts(query).await,
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_breakdown(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageBreakdownSummaryQuery,
|
||||
) -> Result<
|
||||
Vec<aether_data_contracts::repository::usage::StoredUsageBreakdownSummaryRow>,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.summarize_usage_breakdown(query).await,
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn count_monitoring_usage_errors(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageMonitoringErrorCountQuery,
|
||||
) -> Result<u64, DataLayerError> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.count_monitoring_usage_errors(query).await,
|
||||
None => Ok(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_monitoring_usage_errors(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageMonitoringErrorListQuery,
|
||||
) -> Result<Vec<StoredRequestUsageAudit>, DataLayerError> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.list_monitoring_usage_errors(query).await,
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_error_distribution(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageErrorDistributionQuery,
|
||||
) -> Result<
|
||||
Vec<aether_data_contracts::repository::usage::StoredUsageErrorDistributionRow>,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.summarize_usage_error_distribution(query).await,
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_performance_percentiles(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsagePerformancePercentilesQuery,
|
||||
) -> Result<
|
||||
Vec<aether_data_contracts::repository::usage::StoredUsagePerformancePercentilesRow>,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => {
|
||||
repository
|
||||
.summarize_usage_performance_percentiles(query)
|
||||
.await
|
||||
}
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_cost_savings(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageCostSavingsSummaryQuery,
|
||||
) -> Result<
|
||||
aether_data_contracts::repository::usage::StoredUsageCostSavingsSummary,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.summarize_usage_cost_savings(query).await,
|
||||
None => Ok(
|
||||
aether_data_contracts::repository::usage::StoredUsageCostSavingsSummary::default(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_time_series(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageTimeSeriesQuery,
|
||||
@@ -793,6 +998,20 @@ impl GatewayDataState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_users_by_username_search(
|
||||
&self,
|
||||
username_search: &str,
|
||||
) -> Result<Vec<StoredUserSummary>, DataLayerError> {
|
||||
match &self.user_reader {
|
||||
Some(repository) => {
|
||||
repository
|
||||
.list_users_by_username_search(username_search)
|
||||
.await
|
||||
}
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_export_users(
|
||||
&self,
|
||||
) -> Result<Vec<StoredUserExportRow>, DataLayerError> {
|
||||
|
||||
Reference in New Issue
Block a user