Go CLI: add admin stats commands (#17090)

### Summary

```
RAGFlow(admin)> STATS USERS TOP 5 FROM '2026-01-01' TO '2026-02-01';
+-----------------------+----------------------------------------------+------------+---------------------+-----+
| command               | error                                        | from_date  | to_date             | top |
+-----------------------+----------------------------------------------+------------+---------------------+-----+
| get_token_users_stats | 'Get API token users stats' is not supported | 2026-01-01 | 2026-02-01 23:59:59 | 5   |
+-----------------------+----------------------------------------------+------------+---------------------+-----+
RAGFlow(admin)> STATS USER 'aaa@aaa.com' FROM '2026-01-01' TO '2026-02-01' MONTH;
+-----------------+----------------------------------------+------------+-------------+---------------------+-------------+
| command         | error                                  | from_date  | granularity | to_date             | user_name   |
+-----------------+----------------------------------------+------------+-------------+---------------------+-------------+
| get_token_stats | 'Get API token stats' is not supported | 2026-01-01 | month       | 2026-02-01 23:59:59 | aaa@aaa.com |
+-----------------+----------------------------------------+------------+-------------+---------------------+-------------+
RAGFlow(admin)> STATS SUMMARY FROM '2026-01-01' TO '2026-02-01' MONTH;
+-----------+------------------------------------------------+
| field     | value                                          |
+-----------+------------------------------------------------+
| to_date   | 2026-02-01 23:59:59                            |
| command   | get_token_stats_summary                        |
| error     | 'Get API token stats summary' is not supported |
| from_date | 2026-01-01                                     |
+-----------+------------------------------------------------+
```

---------

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
Jin Hai
2026-07-20 14:24:28 +08:00
committed by GitHub
parent 27b6cd1a65
commit 7ad27adecb
9 changed files with 383 additions and 0 deletions

View File

@@ -23,6 +23,7 @@ import (
"ragflow/internal/dao"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
)
@@ -1893,3 +1894,77 @@ func (h *Handler) BatchDeleteWhiteList(c *gin.Context) {
common.SuccessWithData(c, result, "Batch delete white list successfully")
}
// GetTokenStats returns API token statistics for the current user's tenant.
func (h *Handler) GetTokenStats(c *gin.Context) {
userName := c.Query("user_name")
if userName == "" {
common.ErrorWithCode(c, common.CodeBadRequest, "User name is required")
return
}
now := time.Now()
fromDate := c.DefaultQuery("from", now.AddDate(0, 0, -7).Format("2006-01-02 00:00:00"))
toDate := c.DefaultQuery("to", now.Format("2006-01-02 15:04:05"))
if len(toDate) == 10 {
toDate += " 23:59:59"
}
granularity := c.Query("granularity")
if granularity == "" {
granularity = "hour"
}
granularity = strings.ToLower(granularity)
stats, err := h.service.GetTokenStats(userName, fromDate, toDate, granularity)
if err != nil {
common.ErrorWithCode(c, common.CodeDataError, err.Error())
return
}
common.SuccessWithData(c, stats, "success")
}
// GetTokenUsersStats returns API token statistics summary for the current user's tenant.
func (h *Handler) GetTokenUsersStats(c *gin.Context) {
now := time.Now()
fromDate := c.DefaultQuery("from", now.AddDate(0, 0, -7).Format("2006-01-02 00:00:00"))
toDate := c.DefaultQuery("to", now.Format("2006-01-02 15:04:05"))
if len(toDate) == 10 {
toDate += " 23:59:59"
}
topStr := c.Query("top")
top, err := strconv.Atoi(topStr)
if err != nil {
common.ErrorWithCode(c, common.CodeBadRequest, "Invalid top")
return
}
stats, err := h.service.GetTokenUsersStats(fromDate, toDate, top)
if err != nil {
common.ErrorWithCode(c, common.CodeDataError, err.Error())
return
}
common.SuccessWithData(c, stats, "success")
}
// GetTokenStatsSummary returns API token statistics summary for the current user's tenant.
func (h *Handler) GetTokenStatsSummary(c *gin.Context) {
now := time.Now()
fromDate := c.DefaultQuery("from", now.AddDate(0, 0, -7).Format("2006-01-02 00:00:00"))
toDate := c.DefaultQuery("to", now.Format("2006-01-02 15:04:05"))
if len(toDate) == 10 {
toDate += " 23:59:59"
}
stats, err := h.service.GetTokenStatsSummary(fromDate, toDate)
if err != nil {
common.ErrorWithCode(c, common.CodeDataError, err.Error())
return
}
common.SuccessWithData(c, stats, "success")
}

View File

@@ -238,6 +238,11 @@ func (r *Router) Setup(engine *gin.Engine) {
protected.GET("/system/license", r.handler.ShowSystemLicense)
protected.PUT("/system/license/config", r.handler.UpdateSystemLicenseConfig)
// Token statistics
protected.GET("/stats/token", r.handler.GetTokenStats)
protected.GET("/stats/token/users", r.handler.GetTokenUsersStats)
protected.GET("/stats/token/summary", r.handler.GetTokenStatsSummary)
// Fingerprint
protected.GET("/fingerprint", r.handler.GetFingerprint)
// License

View File

@@ -1287,3 +1287,44 @@ func (s *Service) BatchDeleteWhiteList(ids []int) (map[string]interface{}, error
}
return result, nil
}
// GetTokenStats returns API token statistics for the user.
func (s *Service) GetTokenStats(userName, fromDate, toDate, granularity string) ([]map[string]interface{}, error) {
result := []map[string]interface{}{
{
"command": "get_token_stats",
"user_name": userName,
"from_date": fromDate,
"to_date": toDate,
"granularity": granularity,
"error": "'Get API token stats' is not supported",
},
}
return result, nil
}
// GetTokenUsersStats returns API token statistics for all users.
func (s *Service) GetTokenUsersStats(fromDate, toDate string, top int) ([]map[string]interface{}, error) {
result := []map[string]interface{}{
{
"command": "get_token_users_stats",
"from_date": fromDate,
"to_date": toDate,
"top": top,
"error": "'Get API token users stats' is not supported",
},
}
return result, nil
}
// GetTokenStatsSummary returns API token statistics summary for all users.
func (s *Service) GetTokenStatsSummary(fromDate, toDate string) (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "get_token_stats_summary",
"from_date": fromDate,
"to_date": toDate,
"error": "'Get API token stats summary' is not supported",
}
return result, nil
}