Go: refactor system stats (#17089)

### Summary

Move stats to a specific service from system

---------

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
Jin Hai
2026-07-20 14:13:05 +08:00
committed by GitHub
parent 2e396629e3
commit 1fdf167f79
6 changed files with 38 additions and 6 deletions

View File

@@ -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,

View File

@@ -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)
}
}

View File

@@ -22,3 +22,6 @@ import (
func SetupEERouter(engine *gin.Engine) {
}
func RegisterEERouter(protected *gin.RouterGroup, r *Router) {
}

View File

@@ -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) {

View File

@@ -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")
{

View File

@@ -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
}