Refactor configuration and key management
- Removed key management configuration from .env.example and related code. - Updated Makefile to load environment variables for HOST and PORT. - Modified main.go to handle request logging with a wait group for graceful shutdown. - Simplified dashboard statistics handler to focus on key counts and request metrics. - Removed key manager implementation and related interfaces. - Updated proxy server to use atomic counters for round-robin key selection. - Cleaned up unused types and configurations in types.go. - Added package-lock.json for frontend dependencies.
This commit is contained in:
@@ -1,54 +1,39 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gpt-load/internal/db"
|
||||
"gpt-load/internal/models"
|
||||
"gpt-load/internal/response"
|
||||
)
|
||||
|
||||
// GetDashboardStats godoc
|
||||
// @Summary Get dashboard statistics
|
||||
// @Description Get statistics for the dashboard, including total requests, success rate, and group distribution.
|
||||
// @Description Get statistics for the dashboard, including key counts and request metrics.
|
||||
// @Tags Dashboard
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.DashboardStats
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/dashboard/stats [get]
|
||||
func GetDashboardStats(c *gin.Context) {
|
||||
func (s *Server) Stats(c *gin.Context) {
|
||||
var totalRequests, successRequests int64
|
||||
var groupStats []models.GroupRequestStat
|
||||
|
||||
// Get total requests
|
||||
if err := db.DB.Model(&models.RequestLog{}).Count(&totalRequests).Error; err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "Failed to get total requests")
|
||||
return
|
||||
}
|
||||
// 1. Get total and successful requests from the api_keys table
|
||||
s.DB.Model(&models.APIKey{}).Select("SUM(request_count)").Row().Scan(&totalRequests)
|
||||
s.DB.Model(&models.APIKey{}).Select("SUM(request_count) - SUM(failure_count)").Row().Scan(&successRequests)
|
||||
|
||||
// Get success requests (status code 2xx)
|
||||
if err := db.DB.Model(&models.RequestLog{}).Where("status_code >= ? AND status_code < ?", 200, 300).Count(&successRequests).Error; err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "Failed to get success requests")
|
||||
return
|
||||
}
|
||||
// 2. Get request counts per group
|
||||
s.DB.Table("api_keys").
|
||||
Select("groups.name as group_name, SUM(api_keys.request_count) as request_count").
|
||||
Joins("join groups on groups.id = api_keys.group_id").
|
||||
Group("groups.name").
|
||||
Order("request_count DESC").
|
||||
Scan(&groupStats)
|
||||
|
||||
// Calculate success rate
|
||||
// 3. Calculate success rate
|
||||
var successRate float64
|
||||
if totalRequests > 0 {
|
||||
successRate = float64(successRequests) / float64(totalRequests)
|
||||
}
|
||||
|
||||
// Get group stats
|
||||
err := db.DB.Table("request_logs").
|
||||
Select("groups.name as group_name, count(request_logs.id) as request_count").
|
||||
Joins("join groups on groups.id = request_logs.group_id").
|
||||
Group("groups.name").
|
||||
Order("request_count desc").
|
||||
Scan(&groupStats).Error
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "Failed to get group stats")
|
||||
return
|
||||
successRate = float64(successRequests) / float64(totalRequests) * 100
|
||||
}
|
||||
|
||||
stats := models.DashboardStats{
|
||||
|
@@ -3,7 +3,6 @@ package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"gpt-load/internal/models"
|
||||
@@ -53,7 +52,7 @@ func (s *Server) RegisterAPIRoutes(api *gin.RouterGroup) {
|
||||
// Dashboard and logs routes
|
||||
dashboard := api.Group("/dashboard")
|
||||
{
|
||||
dashboard.GET("/stats", GetDashboardStats)
|
||||
dashboard.GET("/stats", s.Stats)
|
||||
}
|
||||
|
||||
api.GET("/logs", GetLogs)
|
||||
@@ -101,53 +100,6 @@ func (s *Server) Health(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// Stats handles statistics requests
|
||||
func (s *Server) Stats(c *gin.Context) {
|
||||
var totalKeys, healthyKeys, disabledKeys int64
|
||||
s.DB.Model(&models.APIKey{}).Count(&totalKeys)
|
||||
s.DB.Model(&models.APIKey{}).Where("status = ?", "active").Count(&healthyKeys)
|
||||
s.DB.Model(&models.APIKey{}).Where("status != ?", "active").Count(&disabledKeys)
|
||||
|
||||
// TODO: Get request counts from the database
|
||||
var successCount, failureCount int64
|
||||
s.DB.Model(&models.RequestLog{}).Where("status_code = ?", http.StatusOK).Count(&successCount)
|
||||
s.DB.Model(&models.RequestLog{}).Where("status_code != ?", http.StatusOK).Count(&failureCount)
|
||||
|
||||
// Add additional system information
|
||||
var m runtime.MemStats
|
||||
runtime.ReadMemStats(&m)
|
||||
|
||||
response := gin.H{
|
||||
"keys": gin.H{
|
||||
"total": totalKeys,
|
||||
"healthy": healthyKeys,
|
||||
"disabled": disabledKeys,
|
||||
},
|
||||
"requests": gin.H{
|
||||
"success_count": successCount,
|
||||
"failure_count": failureCount,
|
||||
"total_count": successCount + failureCount,
|
||||
},
|
||||
"memory": gin.H{
|
||||
"alloc_mb": bToMb(m.Alloc),
|
||||
"total_alloc_mb": bToMb(m.TotalAlloc),
|
||||
"sys_mb": bToMb(m.Sys),
|
||||
"num_gc": m.NumGC,
|
||||
"last_gc": time.Unix(0, int64(m.LastGC)).Format("2006-01-02 15:04:05"),
|
||||
"next_gc_mb": bToMb(m.NextGC),
|
||||
},
|
||||
"system": gin.H{
|
||||
"goroutines": runtime.NumGoroutine(),
|
||||
"cpu_count": runtime.NumCPU(),
|
||||
"go_version": runtime.Version(),
|
||||
},
|
||||
"timestamp": time.Now().UTC().Format(time.RFC3339),
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
|
||||
// MethodNotAllowed handles 405 requests
|
||||
func (s *Server) MethodNotAllowed(c *gin.Context) {
|
||||
c.JSON(http.StatusMethodNotAllowed, gin.H{
|
||||
@@ -169,7 +121,6 @@ func (s *Server) GetConfig(c *gin.Context) {
|
||||
}
|
||||
|
||||
serverConfig := s.config.GetServerConfig()
|
||||
keysConfig := s.config.GetKeysConfig()
|
||||
openaiConfig := s.config.GetOpenAIConfig()
|
||||
authConfig := s.config.GetAuthConfig()
|
||||
corsConfig := s.config.GetCORSConfig()
|
||||
@@ -182,12 +133,6 @@ func (s *Server) GetConfig(c *gin.Context) {
|
||||
"host": serverConfig.Host,
|
||||
"port": serverConfig.Port,
|
||||
},
|
||||
"keys": gin.H{
|
||||
"file_path": keysConfig.FilePath,
|
||||
"start_index": keysConfig.StartIndex,
|
||||
"blacklist_threshold": keysConfig.BlacklistThreshold,
|
||||
"max_retries": keysConfig.MaxRetries,
|
||||
},
|
||||
"openai": gin.H{
|
||||
"base_url": openaiConfig.BaseURL,
|
||||
"request_timeout": openaiConfig.RequestTimeout,
|
||||
@@ -230,8 +175,3 @@ func (s *Server) GetConfig(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, sanitizedConfig)
|
||||
}
|
||||
|
||||
// Helper function to convert bytes to megabytes
|
||||
func bToMb(b uint64) uint64 {
|
||||
return b / 1024 / 1024
|
||||
}
|
||||
|
Reference in New Issue
Block a user