From 1fdf167f79289a4585ca7527a701f49d4919fd6c Mon Sep 17 00:00:00 2001 From: Jin Hai Date: Mon, 20 Jul 2026 14:13:05 +0800 Subject: [PATCH] Go: refactor system stats (#17089) ### Summary Move stats to a specific service from system --------- Signed-off-by: Jin Hai --- cmd/ragflow_server.go | 3 +++ internal/admin/router.go | 2 ++ internal/admin/router_ee.go | 3 +++ internal/handler/stats.go | 15 +++++++++++++-- internal/router/router.go | 5 ++++- internal/service/stats.go | 16 +++++++++++++--- 6 files changed, 38 insertions(+), 6 deletions(-) diff --git a/cmd/ragflow_server.go b/cmd/ragflow_server.go index a5e0e3c983..6c4476cea1 100644 --- a/cmd/ragflow_server.go +++ b/cmd/ragflow_server.go @@ -696,6 +696,7 @@ func startServer(config *server.Config) { chatSessionService := service.NewChatSessionService() openaiChatService := service.NewOpenAIChatService() systemService := service.NewSystemService() + statsService := service.NewStatsService() connectorService := service.NewConnectorService() searchService := service.NewSearchService() searchService.SetTenantService(tenantService) @@ -717,6 +718,7 @@ func startServer(config *server.Config) { documentHandler := handler.NewDocumentHandler(documentService, datasetsService, fileService) datasetsHandler := handler.NewDatasetsHandler(datasetsService, metadataService) systemHandler := handler.NewSystemHandler(systemService) + statsHandler := handler.NewStatsHandler(statsService) chunkHandler := handler.NewChunkHandler(chunkService, userService) llmHandler := handler.NewLLMHandler(llmService, userService) chatHandler := handler.NewChatHandler(chatService, userService) @@ -816,6 +818,7 @@ func startServer(config *server.Config) { documentHandler, datasetsHandler, systemHandler, + statsHandler, chunkHandler, llmHandler, chatHandler, diff --git a/internal/admin/router.go b/internal/admin/router.go index e6fac7e3dc..3ab5155725 100644 --- a/internal/admin/router.go +++ b/internal/admin/router.go @@ -244,6 +244,8 @@ func (r *Router) Setup(engine *gin.Engine) { protected.POST("/license", r.handler.SetLicense) protected.POST("/license/config", r.handler.UpdateLicenseConfig) protected.GET("/license", r.handler.ShowLicense) + + RegisterEERouter(protected, r) } } diff --git a/internal/admin/router_ee.go b/internal/admin/router_ee.go index 3dabbc52ac..28a14f1fdb 100644 --- a/internal/admin/router_ee.go +++ b/internal/admin/router_ee.go @@ -22,3 +22,6 @@ import ( func SetupEERouter(engine *gin.Engine) { } + +func RegisterEERouter(protected *gin.RouterGroup, r *Router) { +} diff --git a/internal/handler/stats.go b/internal/handler/stats.go index 0d6b30898f..a02f9f17a1 100644 --- a/internal/handler/stats.go +++ b/internal/handler/stats.go @@ -26,8 +26,19 @@ import ( "github.com/gin-gonic/gin" ) +type StatsHandler struct { + statsService *service.StatsService +} + +// NewStatsHandler create stats handler +func NewStatsHandler(statsService *service.StatsService) *StatsHandler { + return &StatsHandler{ + statsService: statsService, + } +} + // GetStats returns API conversation statistics for the current user's tenant. -func (h *SystemHandler) GetStats(c *gin.Context) { +func (h *StatsHandler) GetStats(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { common.ErrorWithCode(c, errorCode, errorMessage) @@ -47,7 +58,7 @@ func (h *SystemHandler) GetStats(c *gin.Context) { source = &agentSource } - stats, err := h.systemService.GetStats(user.ID, fromDate, toDate, source) + stats, err := h.statsService.GetStats(user.ID, fromDate, toDate, source) if err != nil { code := common.CodeExceptionError if errors.Is(err, service.ErrTenantNotFound) { diff --git a/internal/router/router.go b/internal/router/router.go index 08f722d08a..3b7440a74b 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -30,6 +30,7 @@ type Router struct { documentHandler *handler.DocumentHandler datasetsHandler *handler.DatasetsHandler systemHandler *handler.SystemHandler + statsHandler *handler.StatsHandler chunkHandler *handler.ChunkHandler llmHandler *handler.LLMHandler chatHandler *handler.ChatHandler @@ -64,6 +65,7 @@ func NewRouter( documentHandler *handler.DocumentHandler, datasetsHandler *handler.DatasetsHandler, systemHandler *handler.SystemHandler, + statsHandler *handler.StatsHandler, chunkHandler *handler.ChunkHandler, llmHandler *handler.LLMHandler, chatHandler *handler.ChatHandler, @@ -96,6 +98,7 @@ func NewRouter( documentHandler: documentHandler, datasetsHandler: datasetsHandler, systemHandler: systemHandler, + statsHandler: statsHandler, chunkHandler: chunkHandler, llmHandler: llmHandler, chatHandler: chatHandler, @@ -644,7 +647,7 @@ func (r *Router) Setup(engine *gin.Engine) { { system.GET("/configs", r.systemHandler.GetConfigs) system.GET("/status", r.systemHandler.GetStatus) - system.GET("/stats", r.systemHandler.GetStats) + system.GET("/stats", r.statsHandler.GetStats) // TODO: need to reconsider this endpoint and function config := system.Group("/config") { diff --git a/internal/service/stats.go b/internal/service/stats.go index 39227cf7ab..9553c5864a 100644 --- a/internal/service/stats.go +++ b/internal/service/stats.go @@ -28,6 +28,17 @@ var ErrTenantNotFound = errors.New("Tenant not found!") // StatPoint matches the frontend [date, value] tuple shape. type StatPoint [2]interface{} +type StatsService struct { + userTenantDAO *dao.UserTenantDAO +} + +// NewStatsService create stats service +func NewStatsService() *StatsService { + return &StatsService{ + userTenantDAO: dao.NewUserTenantDAO(), + } +} + // StatsResponse matches Python GET /api/v1/system/stats response data. type StatsResponse struct { PV []StatPoint `json:"pv"` @@ -39,9 +50,8 @@ type StatsResponse struct { } // GetStats returns daily API conversation statistics for the first tenant of a user. -func (s *SystemService) GetStats(userID, fromDate, toDate string, source *string) (*StatsResponse, error) { - userTenantDAO := dao.NewUserTenantDAO() - tenants, err := userTenantDAO.GetByUserID(userID) +func (s *StatsService) GetStats(userID, fromDate, toDate string, source *string) (*StatsResponse, error) { + tenants, err := s.userTenantDAO.GetByUserID(userID) if err != nil || len(tenants) == 0 { return nil, ErrTenantNotFound }