Files
GopherGate/internal/server/system.go
T
hobokenchicken e598150d90
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled
fix: trim imports per file — no unused imports in split files
2026-04-26 14:58:53 -04:00

159 lines
3.6 KiB
Go

package server
import (
"fmt"
"net/http"
"os"
"strings"
"time"
"log/slog"
"github.com/gin-gonic/gin"
"gophergate/internal/db"
"gophergate/internal/utils"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/disk"
"github.com/shirou/gopsutil/v3/load"
"github.com/shirou/gopsutil/v3/mem"
"github.com/shirou/gopsutil/v3/process"
)
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))
}