feat(路由): 集成运维监控路由到服务器
- 更新路由器注册 ops 监控路由 - 添加 ops 管理路由(dashboard, alerts, realtime, settings, ws) - 更新 gateway 路由支持请求追踪 - 集成 ops 服务到 HTTP 服务器
This commit is contained in:
@@ -30,6 +30,7 @@ func ProvideRouter(
|
|||||||
apiKeyAuth middleware2.APIKeyAuthMiddleware,
|
apiKeyAuth middleware2.APIKeyAuthMiddleware,
|
||||||
apiKeyService *service.APIKeyService,
|
apiKeyService *service.APIKeyService,
|
||||||
subscriptionService *service.SubscriptionService,
|
subscriptionService *service.SubscriptionService,
|
||||||
|
opsService *service.OpsService,
|
||||||
) *gin.Engine {
|
) *gin.Engine {
|
||||||
if cfg.Server.Mode == "release" {
|
if cfg.Server.Mode == "release" {
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
@@ -47,7 +48,7 @@ func ProvideRouter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SetupRouter(r, handlers, jwtAuth, adminAuth, apiKeyAuth, apiKeyService, subscriptionService, cfg)
|
return SetupRouter(r, handlers, jwtAuth, adminAuth, apiKeyAuth, apiKeyService, subscriptionService, opsService, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvideHTTPServer 提供 HTTP 服务器
|
// ProvideHTTPServer 提供 HTTP 服务器
|
||||||
|
|||||||
@@ -20,10 +20,13 @@ func SetupRouter(
|
|||||||
apiKeyAuth middleware2.APIKeyAuthMiddleware,
|
apiKeyAuth middleware2.APIKeyAuthMiddleware,
|
||||||
apiKeyService *service.APIKeyService,
|
apiKeyService *service.APIKeyService,
|
||||||
subscriptionService *service.SubscriptionService,
|
subscriptionService *service.SubscriptionService,
|
||||||
|
opsService *service.OpsService,
|
||||||
cfg *config.Config,
|
cfg *config.Config,
|
||||||
) *gin.Engine {
|
) *gin.Engine {
|
||||||
// 应用中间件
|
// 应用中间件
|
||||||
r.Use(middleware2.Logger())
|
r.Use(middleware2.Logger())
|
||||||
|
// WebSocket handshake auth helper (token via query param, WS endpoints only).
|
||||||
|
r.Use(middleware2.InjectBearerTokenFromQueryForWebSocket())
|
||||||
r.Use(middleware2.CORS(cfg.CORS))
|
r.Use(middleware2.CORS(cfg.CORS))
|
||||||
r.Use(middleware2.SecurityHeaders(cfg.Security.CSP))
|
r.Use(middleware2.SecurityHeaders(cfg.Security.CSP))
|
||||||
|
|
||||||
@@ -33,7 +36,7 @@ func SetupRouter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 注册路由
|
// 注册路由
|
||||||
registerRoutes(r, handlers, jwtAuth, adminAuth, apiKeyAuth, apiKeyService, subscriptionService, cfg)
|
registerRoutes(r, handlers, jwtAuth, adminAuth, apiKeyAuth, apiKeyService, subscriptionService, opsService, cfg)
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -47,6 +50,7 @@ func registerRoutes(
|
|||||||
apiKeyAuth middleware2.APIKeyAuthMiddleware,
|
apiKeyAuth middleware2.APIKeyAuthMiddleware,
|
||||||
apiKeyService *service.APIKeyService,
|
apiKeyService *service.APIKeyService,
|
||||||
subscriptionService *service.SubscriptionService,
|
subscriptionService *service.SubscriptionService,
|
||||||
|
opsService *service.OpsService,
|
||||||
cfg *config.Config,
|
cfg *config.Config,
|
||||||
) {
|
) {
|
||||||
// 通用路由(健康检查、状态等)
|
// 通用路由(健康检查、状态等)
|
||||||
@@ -59,5 +63,5 @@ func registerRoutes(
|
|||||||
routes.RegisterAuthRoutes(v1, h, jwtAuth)
|
routes.RegisterAuthRoutes(v1, h, jwtAuth)
|
||||||
routes.RegisterUserRoutes(v1, h, jwtAuth)
|
routes.RegisterUserRoutes(v1, h, jwtAuth)
|
||||||
routes.RegisterAdminRoutes(v1, h, adminAuth)
|
routes.RegisterAdminRoutes(v1, h, adminAuth)
|
||||||
routes.RegisterGatewayRoutes(r, h, apiKeyAuth, apiKeyService, subscriptionService, cfg)
|
routes.RegisterGatewayRoutes(r, h, apiKeyAuth, apiKeyService, subscriptionService, opsService, cfg)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ func RegisterAdminRoutes(
|
|||||||
// 系统设置
|
// 系统设置
|
||||||
registerSettingsRoutes(admin, h)
|
registerSettingsRoutes(admin, h)
|
||||||
|
|
||||||
|
// 运维监控(Ops)
|
||||||
|
registerOpsRoutes(admin, h)
|
||||||
|
|
||||||
// 系统管理
|
// 系统管理
|
||||||
registerSystemRoutes(admin, h)
|
registerSystemRoutes(admin, h)
|
||||||
|
|
||||||
@@ -61,6 +64,54 @@ func RegisterAdminRoutes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerOpsRoutes(admin *gin.RouterGroup, h *handler.Handlers) {
|
||||||
|
ops := admin.Group("/ops")
|
||||||
|
{
|
||||||
|
// Realtime ops signals
|
||||||
|
ops.GET("/concurrency", h.Admin.Ops.GetConcurrencyStats)
|
||||||
|
ops.GET("/account-availability", h.Admin.Ops.GetAccountAvailability)
|
||||||
|
|
||||||
|
// Alerts (rules + events)
|
||||||
|
ops.GET("/alert-rules", h.Admin.Ops.ListAlertRules)
|
||||||
|
ops.POST("/alert-rules", h.Admin.Ops.CreateAlertRule)
|
||||||
|
ops.PUT("/alert-rules/:id", h.Admin.Ops.UpdateAlertRule)
|
||||||
|
ops.DELETE("/alert-rules/:id", h.Admin.Ops.DeleteAlertRule)
|
||||||
|
ops.GET("/alert-events", h.Admin.Ops.ListAlertEvents)
|
||||||
|
|
||||||
|
// Email notification config (DB-backed)
|
||||||
|
ops.GET("/email-notification/config", h.Admin.Ops.GetEmailNotificationConfig)
|
||||||
|
ops.PUT("/email-notification/config", h.Admin.Ops.UpdateEmailNotificationConfig)
|
||||||
|
|
||||||
|
// Runtime settings (DB-backed)
|
||||||
|
runtime := ops.Group("/runtime")
|
||||||
|
{
|
||||||
|
runtime.GET("/alert", h.Admin.Ops.GetAlertRuntimeSettings)
|
||||||
|
runtime.PUT("/alert", h.Admin.Ops.UpdateAlertRuntimeSettings)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebSocket realtime (QPS/TPS)
|
||||||
|
ws := ops.Group("/ws")
|
||||||
|
{
|
||||||
|
ws.GET("/qps", h.Admin.Ops.QPSWSHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error logs (MVP-1)
|
||||||
|
ops.GET("/errors", h.Admin.Ops.GetErrorLogs)
|
||||||
|
ops.GET("/errors/:id", h.Admin.Ops.GetErrorLogByID)
|
||||||
|
ops.POST("/errors/:id/retry", h.Admin.Ops.RetryErrorRequest)
|
||||||
|
|
||||||
|
// Request drilldown (success + error)
|
||||||
|
ops.GET("/requests", h.Admin.Ops.ListRequestDetails)
|
||||||
|
|
||||||
|
// Dashboard (vNext - raw path for MVP)
|
||||||
|
ops.GET("/dashboard/overview", h.Admin.Ops.GetDashboardOverview)
|
||||||
|
ops.GET("/dashboard/throughput-trend", h.Admin.Ops.GetDashboardThroughputTrend)
|
||||||
|
ops.GET("/dashboard/latency-histogram", h.Admin.Ops.GetDashboardLatencyHistogram)
|
||||||
|
ops.GET("/dashboard/error-trend", h.Admin.Ops.GetDashboardErrorTrend)
|
||||||
|
ops.GET("/dashboard/error-distribution", h.Admin.Ops.GetDashboardErrorDistribution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func registerDashboardRoutes(admin *gin.RouterGroup, h *handler.Handlers) {
|
func registerDashboardRoutes(admin *gin.RouterGroup, h *handler.Handlers) {
|
||||||
dashboard := admin.Group("/dashboard")
|
dashboard := admin.Group("/dashboard")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,13 +16,18 @@ func RegisterGatewayRoutes(
|
|||||||
apiKeyAuth middleware.APIKeyAuthMiddleware,
|
apiKeyAuth middleware.APIKeyAuthMiddleware,
|
||||||
apiKeyService *service.APIKeyService,
|
apiKeyService *service.APIKeyService,
|
||||||
subscriptionService *service.SubscriptionService,
|
subscriptionService *service.SubscriptionService,
|
||||||
|
opsService *service.OpsService,
|
||||||
cfg *config.Config,
|
cfg *config.Config,
|
||||||
) {
|
) {
|
||||||
bodyLimit := middleware.RequestBodyLimit(cfg.Gateway.MaxBodySize)
|
bodyLimit := middleware.RequestBodyLimit(cfg.Gateway.MaxBodySize)
|
||||||
|
clientRequestID := middleware.ClientRequestID()
|
||||||
|
opsErrorLogger := handler.OpsErrorLoggerMiddleware(opsService)
|
||||||
|
|
||||||
// API网关(Claude API兼容)
|
// API网关(Claude API兼容)
|
||||||
gateway := r.Group("/v1")
|
gateway := r.Group("/v1")
|
||||||
gateway.Use(bodyLimit)
|
gateway.Use(bodyLimit)
|
||||||
|
gateway.Use(clientRequestID)
|
||||||
|
gateway.Use(opsErrorLogger)
|
||||||
gateway.Use(gin.HandlerFunc(apiKeyAuth))
|
gateway.Use(gin.HandlerFunc(apiKeyAuth))
|
||||||
{
|
{
|
||||||
gateway.POST("/messages", h.Gateway.Messages)
|
gateway.POST("/messages", h.Gateway.Messages)
|
||||||
@@ -36,6 +41,8 @@ func RegisterGatewayRoutes(
|
|||||||
// Gemini 原生 API 兼容层(Gemini SDK/CLI 直连)
|
// Gemini 原生 API 兼容层(Gemini SDK/CLI 直连)
|
||||||
gemini := r.Group("/v1beta")
|
gemini := r.Group("/v1beta")
|
||||||
gemini.Use(bodyLimit)
|
gemini.Use(bodyLimit)
|
||||||
|
gemini.Use(clientRequestID)
|
||||||
|
gemini.Use(opsErrorLogger)
|
||||||
gemini.Use(middleware.APIKeyAuthWithSubscriptionGoogle(apiKeyService, subscriptionService, cfg))
|
gemini.Use(middleware.APIKeyAuthWithSubscriptionGoogle(apiKeyService, subscriptionService, cfg))
|
||||||
{
|
{
|
||||||
gemini.GET("/models", h.Gateway.GeminiV1BetaListModels)
|
gemini.GET("/models", h.Gateway.GeminiV1BetaListModels)
|
||||||
@@ -45,7 +52,7 @@ func RegisterGatewayRoutes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpenAI Responses API(不带v1前缀的别名)
|
// OpenAI Responses API(不带v1前缀的别名)
|
||||||
r.POST("/responses", bodyLimit, gin.HandlerFunc(apiKeyAuth), h.OpenAIGateway.Responses)
|
r.POST("/responses", bodyLimit, clientRequestID, opsErrorLogger, gin.HandlerFunc(apiKeyAuth), h.OpenAIGateway.Responses)
|
||||||
|
|
||||||
// Antigravity 模型列表
|
// Antigravity 模型列表
|
||||||
r.GET("/antigravity/models", gin.HandlerFunc(apiKeyAuth), h.Gateway.AntigravityModels)
|
r.GET("/antigravity/models", gin.HandlerFunc(apiKeyAuth), h.Gateway.AntigravityModels)
|
||||||
@@ -53,6 +60,8 @@ func RegisterGatewayRoutes(
|
|||||||
// Antigravity 专用路由(仅使用 antigravity 账户,不混合调度)
|
// Antigravity 专用路由(仅使用 antigravity 账户,不混合调度)
|
||||||
antigravityV1 := r.Group("/antigravity/v1")
|
antigravityV1 := r.Group("/antigravity/v1")
|
||||||
antigravityV1.Use(bodyLimit)
|
antigravityV1.Use(bodyLimit)
|
||||||
|
antigravityV1.Use(clientRequestID)
|
||||||
|
antigravityV1.Use(opsErrorLogger)
|
||||||
antigravityV1.Use(middleware.ForcePlatform(service.PlatformAntigravity))
|
antigravityV1.Use(middleware.ForcePlatform(service.PlatformAntigravity))
|
||||||
antigravityV1.Use(gin.HandlerFunc(apiKeyAuth))
|
antigravityV1.Use(gin.HandlerFunc(apiKeyAuth))
|
||||||
{
|
{
|
||||||
@@ -64,6 +73,8 @@ func RegisterGatewayRoutes(
|
|||||||
|
|
||||||
antigravityV1Beta := r.Group("/antigravity/v1beta")
|
antigravityV1Beta := r.Group("/antigravity/v1beta")
|
||||||
antigravityV1Beta.Use(bodyLimit)
|
antigravityV1Beta.Use(bodyLimit)
|
||||||
|
antigravityV1Beta.Use(clientRequestID)
|
||||||
|
antigravityV1Beta.Use(opsErrorLogger)
|
||||||
antigravityV1Beta.Use(middleware.ForcePlatform(service.PlatformAntigravity))
|
antigravityV1Beta.Use(middleware.ForcePlatform(service.PlatformAntigravity))
|
||||||
antigravityV1Beta.Use(middleware.APIKeyAuthWithSubscriptionGoogle(apiKeyService, subscriptionService, cfg))
|
antigravityV1Beta.Use(middleware.APIKeyAuthWithSubscriptionGoogle(apiKeyService, subscriptionService, cfg))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user