feat(api): add dashboard summary and system realtime endpoints

Add new admin API endpoints for dashboard metrics and system-wide
realtime statistics:

- Add /admin/dashboard/summary endpoint with aggregated metrics
  including requests, tokens, latency, masters, keys, and provider
  keys statistics with time period filtering
- Add /admin/realtime endpoint for system-level realtime stats
  aggregated across all masters
- Add status filter parameter to ListAPIKeys endpoint
- Add hour grouping option to log stats aggregation
- Update OpenAPI documentation with new endpoints and schemas
This commit is contained in:
zenfun
2025-12-31 13:17:23 +08:00
parent 1a2cc5b798
commit 53c18c3867
9 changed files with 1644 additions and 21 deletions

View File

@@ -51,7 +51,7 @@ const docTemplate = `{
"AdminAuth": []
}
],
"description": "List API keys",
"description": "List API keys with optional filters",
"produces": [
"application/json"
],
@@ -77,6 +77,12 @@ const docTemplate = `{
"description": "filter by group_id",
"name": "group_id",
"in": "query"
},
{
"type": "string",
"description": "filter by status (active, suspended, auto_disabled, manual_disabled)",
"name": "status",
"in": "query"
}
],
"responses": {
@@ -362,6 +368,37 @@ const docTemplate = `{
}
}
},
"/admin/apikey-stats/summary": {
"get": {
"security": [
{
"AdminAuth": []
}
],
"description": "Aggregate APIKey success/failure stats across all provider groups",
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "APIKey stats summary (admin)",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/internal_api.APIKeyStatsSummaryResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
}
}
}
}
},
"/admin/bindings": {
"get": {
"security": [
@@ -680,6 +717,63 @@ const docTemplate = `{
}
}
},
"/admin/dashboard/summary": {
"get": {
"security": [
{
"AdminAuth": []
}
],
"description": "Returns aggregated metrics for dashboard display including requests, tokens, latency, masters, keys, and provider keys statistics",
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Dashboard summary",
"parameters": [
{
"type": "string",
"description": "time period: today, week, month, all",
"name": "period",
"in": "query"
},
{
"type": "integer",
"description": "unix seconds",
"name": "since",
"in": "query"
},
{
"type": "integer",
"description": "unix seconds",
"name": "until",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/internal_api.DashboardSummaryResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/gin.H"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
}
}
}
}
},
"/admin/features": {
"get": {
"security": [
@@ -1011,7 +1105,7 @@ const docTemplate = `{
"AdminAuth": []
}
],
"description": "Aggregate log stats with basic filtering. Use group_by param for grouped statistics (model/day/month). Without group_by returns LogStatsResponse; with group_by returns GroupedStatsResponse.",
"description": "Aggregate log stats with basic filtering. Use group_by param for grouped statistics (model/day/month/hour). Without group_by returns LogStatsResponse; with group_by returns GroupedStatsResponse.",
"produces": [
"application/json"
],
@@ -1036,10 +1130,11 @@ const docTemplate = `{
"enum": [
"model",
"day",
"month"
"month",
"hour"
],
"type": "string",
"description": "group by dimension: model, day, month. Returns GroupedStatsResponse when specified.",
"description": "group by dimension: model, day, month, hour. Returns GroupedStatsResponse when specified.",
"name": "group_by",
"in": "query"
}
@@ -2776,6 +2871,37 @@ const docTemplate = `{
}
}
},
"/admin/realtime": {
"get": {
"security": [
{
"AdminAuth": []
}
],
"description": "Return aggregated realtime counters across all masters",
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "System-level realtime stats (admin)",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/internal_api.SystemRealtimeView"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
}
}
}
}
},
"/admin/stats": {
"get": {
"security": [
@@ -2898,6 +3024,52 @@ const docTemplate = `{
}
}
},
"/internal/apikey-stats/flush": {
"post": {
"description": "Internal endpoint for flushing accumulated APIKey stats from DP to CP database",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"internal"
],
"summary": "Flush API key stats",
"parameters": [
{
"description": "Stats to flush",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_api.apiKeyStatsFlushRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/gin.H"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/gin.H"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
}
}
}
}
},
"/internal/stats/flush": {
"post": {
"description": "Internal endpoint for flushing accumulated key usage stats from DP to CP database",
@@ -3573,6 +3745,12 @@ const docTemplate = `{
"github_com_ez-api_ez-api_internal_dto.APIKeyDTO": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"account_id": {
"type": "string"
},
"api_key": {
"type": "string"
},
@@ -3585,9 +3763,18 @@ const docTemplate = `{
"ban_until": {
"type": "string"
},
"expires_at": {
"type": "string"
},
"group_id": {
"type": "integer"
},
"project_id": {
"type": "string"
},
"refresh_token": {
"type": "string"
},
"status": {
"type": "string"
},
@@ -3666,6 +3853,9 @@ const docTemplate = `{
"google_project": {
"type": "string"
},
"headers_profile": {
"type": "string"
},
"models": {
"type": "array",
"items": {
@@ -3675,6 +3865,9 @@ const docTemplate = `{
"name": {
"type": "string"
},
"static_headers": {
"type": "string"
},
"status": {
"type": "string"
},
@@ -3686,6 +3879,12 @@ const docTemplate = `{
"github_com_ez-api_ez-api_internal_model.APIKey": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"account_id": {
"type": "string"
},
"api_key": {
"type": "string"
},
@@ -3704,15 +3903,36 @@ const docTemplate = `{
"deletedAt": {
"$ref": "#/definitions/gorm.DeletedAt"
},
"expires_at": {
"type": "string"
},
"failure_rate": {
"type": "number"
},
"failure_requests": {
"type": "integer"
},
"group_id": {
"type": "integer"
},
"id": {
"type": "integer"
},
"project_id": {
"type": "string"
},
"status": {
"type": "string"
},
"success_rate": {
"type": "number"
},
"success_requests": {
"type": "integer"
},
"total_requests": {
"type": "integer"
},
"updatedAt": {
"type": "string"
},
@@ -3911,12 +4131,21 @@ const docTemplate = `{
"deletedAt": {
"$ref": "#/definitions/gorm.DeletedAt"
},
"failure_rate": {
"type": "number"
},
"failure_requests": {
"type": "integer"
},
"google_location": {
"type": "string"
},
"google_project": {
"type": "string"
},
"headers_profile": {
"type": "string"
},
"id": {
"type": "integer"
},
@@ -3927,9 +4156,21 @@ const docTemplate = `{
"name": {
"type": "string"
},
"static_headers": {
"type": "string"
},
"status": {
"type": "string"
},
"success_rate": {
"type": "number"
},
"success_requests": {
"type": "integer"
},
"total_requests": {
"type": "integer"
},
"type": {
"description": "openai, anthropic, gemini",
"type": "string"
@@ -4046,6 +4287,26 @@ const docTemplate = `{
}
}
},
"internal_api.APIKeyStatsSummaryResponse": {
"type": "object",
"properties": {
"failure_rate": {
"type": "number"
},
"failure_requests": {
"type": "integer"
},
"success_rate": {
"type": "number"
},
"success_requests": {
"type": "integer"
},
"total_requests": {
"type": "integer"
}
}
},
"internal_api.AboutResponse": {
"type": "object",
"properties": {
@@ -4161,6 +4422,17 @@ const docTemplate = `{
}
}
},
"internal_api.CountStats": {
"type": "object",
"properties": {
"active": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
},
"internal_api.CreateMasterRequest": {
"type": "object",
"required": [
@@ -4182,6 +4454,41 @@ const docTemplate = `{
}
}
},
"internal_api.DashboardSummaryResponse": {
"type": "object",
"properties": {
"keys": {
"$ref": "#/definitions/internal_api.CountStats"
},
"latency": {
"$ref": "#/definitions/internal_api.LatencyStats"
},
"masters": {
"$ref": "#/definitions/internal_api.CountStats"
},
"period": {
"type": "string"
},
"provider_keys": {
"$ref": "#/definitions/internal_api.ProviderKeyStats"
},
"requests": {
"$ref": "#/definitions/internal_api.RequestStats"
},
"tokens": {
"$ref": "#/definitions/internal_api.TokenStats"
},
"top_models": {
"type": "array",
"items": {
"$ref": "#/definitions/internal_api.TopModelStat"
}
},
"updated_at": {
"type": "integer"
}
}
},
"internal_api.DeleteLogsRequest": {
"type": "object",
"properties": {
@@ -4217,6 +4524,10 @@ const docTemplate = `{
"description": "For group_by=day",
"type": "string"
},
"hour": {
"description": "For group_by=hour",
"type": "string"
},
"model": {
"description": "For group_by=model",
"type": "string"
@@ -4284,6 +4595,14 @@ const docTemplate = `{
}
}
},
"internal_api.LatencyStats": {
"type": "object",
"properties": {
"avg_ms": {
"type": "number"
}
}
},
"internal_api.ListLogsResponse": {
"type": "object",
"properties": {
@@ -4460,6 +4779,20 @@ const docTemplate = `{
}
}
},
"internal_api.MasterRealtimeSummaryView": {
"type": "object",
"properties": {
"master_id": {
"type": "integer"
},
"qps": {
"type": "integer"
},
"rate_limited": {
"type": "boolean"
}
}
},
"internal_api.MasterRealtimeView": {
"type": "object",
"properties": {
@@ -4633,6 +4966,23 @@ const docTemplate = `{
}
}
},
"internal_api.ProviderKeyStats": {
"type": "object",
"properties": {
"active": {
"type": "integer"
},
"auto_disabled": {
"type": "integer"
},
"suspended": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
},
"internal_api.ProviderUsageAgg": {
"type": "object",
"properties": {
@@ -4653,6 +5003,23 @@ const docTemplate = `{
}
}
},
"internal_api.RequestStats": {
"type": "object",
"properties": {
"error_rate": {
"type": "number"
},
"failed": {
"type": "integer"
},
"success": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
},
"internal_api.StatusResponse": {
"type": "object",
"properties": {
@@ -4670,6 +5037,43 @@ const docTemplate = `{
}
}
},
"internal_api.SystemRealtimeView": {
"type": "object",
"properties": {
"by_master": {
"type": "array",
"items": {
"$ref": "#/definitions/internal_api.MasterRealtimeSummaryView"
}
},
"qps": {
"type": "integer"
},
"rate_limited_count": {
"type": "integer"
},
"rpm": {
"type": "integer"
},
"updated_at": {
"type": "integer"
}
}
},
"internal_api.TokenStats": {
"type": "object",
"properties": {
"input": {
"type": "integer"
},
"output": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
},
"internal_api.TokenView": {
"type": "object",
"properties": {
@@ -4741,6 +5145,20 @@ const docTemplate = `{
}
}
},
"internal_api.TopModelStat": {
"type": "object",
"properties": {
"model": {
"type": "string"
},
"requests": {
"type": "integer"
},
"tokens": {
"type": "integer"
}
}
},
"internal_api.UpdateAccessRequest": {
"type": "object",
"properties": {
@@ -4896,6 +5314,31 @@ const docTemplate = `{
}
}
},
"internal_api.apiKeyStatsFlushEntry": {
"type": "object",
"properties": {
"api_key_id": {
"type": "integer"
},
"requests": {
"type": "integer"
},
"success_requests": {
"type": "integer"
}
}
},
"internal_api.apiKeyStatsFlushRequest": {
"type": "object",
"properties": {
"keys": {
"type": "array",
"items": {
"$ref": "#/definitions/internal_api.apiKeyStatsFlushEntry"
}
}
}
},
"internal_api.refreshModelRegistryRequest": {
"type": "object",
"properties": {