159 lines
3.6 KiB
Go
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))
|
|
}
|