feat: Phase 3 - architecture & maintainability
- Split 1474-line dashboard.go into 5 domain files (clients, providers, users, system) - Unit tests for ModelRegistry.FindModel and CalculateCost - go mod tidy + verify (deps clean) - .gitignore excludes tool cache dirs (.pi-lens/, .opencode/)
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gophergate/internal/db"
|
||||
"gophergate/internal/models"
|
||||
"gophergate/internal/utils"
|
||||
"log/slog"
|
||||
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
|
||||
func (s *Server) handleSystemHealth(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, SuccessResponse(gin.H{
|
||||
"status": "ok",
|
||||
"components": gin.H{
|
||||
"database": "online",
|
||||
"proxy": "online",
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *Server) handleSystemMetrics(c *gin.Context) {
|
||||
v, _ := mem.VirtualMemory()
|
||||
c_usage, _ := cpu.Percent(time.Second, false)
|
||||
d, _ := disk.Usage("/")
|
||||
l, _ := load.Avg()
|
||||
p, _ := process.NewProcess(int32(os.Getpid()))
|
||||
rss, _ := p.MemoryInfo()
|
||||
|
||||
cpuPercent := 0.0
|
||||
if len(c_usage) > 0 {
|
||||
cpuPercent = c_usage[0]
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, SuccessResponse(gin.H{
|
||||
"cpu": gin.H{
|
||||
"usage_percent": fmt.Sprintf("%.1f", cpuPercent),
|
||||
"load_average": []float64{l.Load1, l.Load5, l.Load15},
|
||||
},
|
||||
"memory": gin.H{
|
||||
"used_mb": v.Used / 1024 / 1024,
|
||||
"total_mb": v.Total / 1024 / 1024,
|
||||
"usage_percent": fmt.Sprintf("%.1f", v.UsedPercent),
|
||||
"process_rss_mb": rss.RSS / 1024 / 1024,
|
||||
},
|
||||
"disk": gin.H{
|
||||
"used_gb": float64(d.Used) / 1024 / 1024 / 1024,
|
||||
"total_gb": float64(d.Total) / 1024 / 1024 / 1024,
|
||||
"usage_percent": fmt.Sprintf("%.1f", d.UsedPercent),
|
||||
},
|
||||
"connections": gin.H{
|
||||
"db_active": s.database.Stats().OpenConnections,
|
||||
"websocket_listeners": s.hub.GetClientCount(),
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *Server) handleGetSettings(c *gin.Context) {
|
||||
providerCount := 0
|
||||
modelCount := 0
|
||||
s.registryMu.RLock()
|
||||
if s.registry != nil {
|
||||
providerCount = len(s.registry.Providers)
|
||||
for _, p := range s.registry.Providers {
|
||||
modelCount += len(p.Models)
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, SuccessResponse(gin.H{
|
||||
"server": gin.H{
|
||||
"version": "1.0.0-go",
|
||||
"auth_tokens": s.cfg.Server.AuthTokens,
|
||||
},
|
||||
"database": gin.H{
|
||||
"type": "sqlite",
|
||||
"path": s.cfg.Database.Path,
|
||||
},
|
||||
"registry": gin.H{
|
||||
"provider_count": providerCount,
|
||||
"model_count": modelCount,
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *Server) handleCreateBackup(c *gin.Context) {
|
||||
// Simplified backup response
|
||||
c.JSON(http.StatusOK, SuccessResponse(gin.H{
|
||||
"backup_id": fmt.Sprintf("backup-%d.db", time.Now().Unix()),
|
||||
"status": "created",
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *Server) handleGetLogs(c *gin.Context) {
|
||||
var logs []db.LLMRequest
|
||||
err := s.database.Select(&logs, "SELECT * FROM llm_requests ORDER BY timestamp DESC LIMIT 100")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, ErrorResponse(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// Format for UI
|
||||
type UILog struct {
|
||||
Timestamp string `json:"timestamp"`
|
||||
ClientID string `json:"client_id"`
|
||||
Provider string `json:"provider"`
|
||||
Model string `json:"model"`
|
||||
Tokens int `json:"tokens"`
|
||||
Status string `json:"status"`
|
||||
Duration int `json:"duration"`
|
||||
}
|
||||
|
||||
uiLogs := make([]UILog, len(logs))
|
||||
for i, l := range logs {
|
||||
clientID := "unknown"
|
||||
if l.ClientID != nil {
|
||||
clientID = *l.ClientID
|
||||
}
|
||||
provider := "unknown"
|
||||
if l.Provider != nil {
|
||||
provider = *l.Provider
|
||||
}
|
||||
model := "unknown"
|
||||
if l.Model != nil {
|
||||
model = *l.Model
|
||||
}
|
||||
tokens := 0
|
||||
if l.TotalTokens != nil {
|
||||
tokens = *l.TotalTokens
|
||||
}
|
||||
duration := 0
|
||||
if l.DurationMS != nil {
|
||||
duration = *l.DurationMS
|
||||
}
|
||||
|
||||
uiLogs[i] = UILog{
|
||||
Timestamp: l.Timestamp.Format(time.RFC3339),
|
||||
ClientID: clientID,
|
||||
Provider: provider,
|
||||
Model: model,
|
||||
Tokens: tokens,
|
||||
Status: l.Status,
|
||||
Duration: duration,
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, SuccessResponse(uiLogs))
|
||||
}
|
||||
Reference in New Issue
Block a user