mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-14 02:37:52 +00:00
feat(api): add realtime stats endpoints for masters
Introduce StatsService integration to admin and master handlers, exposing realtime metrics (requests, tokens, QPS, rate limit status) via new endpoints: - GET /admin/masters/:id/realtime - GET /v1/realtime Also embed realtime stats in the existing GET /admin/masters/:id response and change GlobalQPS default to 0 with validation to reject negative values.
This commit is contained in:
@@ -17,14 +17,15 @@ type AdminHandler struct {
|
||||
logDB *gorm.DB
|
||||
masterService *service.MasterService
|
||||
syncService *service.SyncService
|
||||
statsService *service.StatsService
|
||||
logPartitioner *service.LogPartitioner
|
||||
}
|
||||
|
||||
func NewAdminHandler(db *gorm.DB, logDB *gorm.DB, masterService *service.MasterService, syncService *service.SyncService, partitioner *service.LogPartitioner) *AdminHandler {
|
||||
func NewAdminHandler(db *gorm.DB, logDB *gorm.DB, masterService *service.MasterService, syncService *service.SyncService, statsService *service.StatsService, partitioner *service.LogPartitioner) *AdminHandler {
|
||||
if logDB == nil {
|
||||
logDB = db
|
||||
}
|
||||
return &AdminHandler{db: db, logDB: logDB, masterService: masterService, syncService: syncService, logPartitioner: partitioner}
|
||||
return &AdminHandler{db: db, logDB: logDB, masterService: masterService, syncService: syncService, statsService: statsService, logPartitioner: partitioner}
|
||||
}
|
||||
|
||||
func (h *AdminHandler) logDBConn() *gorm.DB {
|
||||
@@ -68,8 +69,9 @@ func (h *AdminHandler) CreateMaster(c *gin.Context) {
|
||||
if req.MaxChildKeys == 0 {
|
||||
req.MaxChildKeys = 5
|
||||
}
|
||||
if req.GlobalQPS == 0 {
|
||||
req.GlobalQPS = 3
|
||||
if req.GlobalQPS < 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "global_qps must be >= 0"})
|
||||
return
|
||||
}
|
||||
|
||||
master, rawMasterKey, err := h.masterService.CreateMaster(req.Name, req.Group, req.MaxChildKeys, req.GlobalQPS)
|
||||
@@ -94,17 +96,18 @@ func (h *AdminHandler) CreateMaster(c *gin.Context) {
|
||||
}
|
||||
|
||||
type MasterView struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Group string `json:"group"`
|
||||
DefaultNamespace string `json:"default_namespace"`
|
||||
Namespaces string `json:"namespaces"`
|
||||
Epoch int64 `json:"epoch"`
|
||||
Status string `json:"status"`
|
||||
MaxChildKeys int `json:"max_child_keys"`
|
||||
GlobalQPS int `json:"global_qps"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Group string `json:"group"`
|
||||
DefaultNamespace string `json:"default_namespace"`
|
||||
Namespaces string `json:"namespaces"`
|
||||
Epoch int64 `json:"epoch"`
|
||||
Status string `json:"status"`
|
||||
MaxChildKeys int `json:"max_child_keys"`
|
||||
GlobalQPS int `json:"global_qps"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
Realtime *MasterRealtimeView `json:"realtime,omitempty"`
|
||||
}
|
||||
|
||||
func toMasterView(m model.Master) MasterView {
|
||||
@@ -176,7 +179,16 @@ func (h *AdminHandler) GetMaster(c *gin.Context) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "master not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, toMasterView(m))
|
||||
view := toMasterView(m)
|
||||
if h.statsService != nil {
|
||||
if stats, err := h.statsService.GetMasterRealtimeSnapshot(c.Request.Context(), m.ID); err == nil {
|
||||
if stats.QPSLimit == 0 && m.GlobalQPS > 0 {
|
||||
stats.QPSLimit = int64(m.GlobalQPS)
|
||||
}
|
||||
view.Realtime = toMasterRealtimeView(stats)
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, view)
|
||||
}
|
||||
|
||||
type UpdateMasterRequest struct {
|
||||
@@ -233,7 +245,11 @@ func (h *AdminHandler) UpdateMaster(c *gin.Context) {
|
||||
if req.MaxChildKeys != nil && *req.MaxChildKeys > 0 {
|
||||
update["max_child_keys"] = *req.MaxChildKeys
|
||||
}
|
||||
if req.GlobalQPS != nil && *req.GlobalQPS > 0 {
|
||||
if req.GlobalQPS != nil {
|
||||
if *req.GlobalQPS < 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "global_qps must be >= 0"})
|
||||
return
|
||||
}
|
||||
update["global_qps"] = *req.GlobalQPS
|
||||
}
|
||||
if len(update) == 0 && !req.PropagateToKeys {
|
||||
|
||||
Reference in New Issue
Block a user