feat: add system instance info panel (#5716)

* feat: add system instance reporting

* feat: show system instance resources

* fix: update translations for heartbeat messages in Russian and Vietnamese
This commit is contained in:
Calcium-Ion
2026-06-24 19:16:56 +08:00
committed by GitHub
parent 5377192293
commit 2cbdfa0398
20 changed files with 1133 additions and 35 deletions
+130
View File
@@ -0,0 +1,130 @@
package service
import (
"context"
"fmt"
"os"
"runtime"
"strings"
"sync"
"time"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/logger"
"github.com/QuantumNous/new-api/model"
"github.com/bytedance/gopkg/util/gopool"
)
const systemInstanceReportInterval = 30 * time.Second
var systemInstanceReporterOnce sync.Once
type SystemInstanceInfo struct {
SchemaVersion int `json:"schema_version"`
Node common.NodeIdentity `json:"node"`
Role SystemInstanceRoleInfo `json:"role"`
Runtime SystemInstanceRuntimeInfo `json:"runtime"`
Host SystemInstanceHostInfo `json:"host"`
Resources SystemInstanceResources `json:"resources,omitempty"`
Extra map[string]any `json:"extra,omitempty"`
}
type SystemInstanceRoleInfo struct {
IsMaster bool `json:"is_master"`
}
type SystemInstanceRuntimeInfo struct {
Version string `json:"version"`
GOOS string `json:"goos"`
GOARCH string `json:"goarch"`
StartedAt int64 `json:"started_at"`
}
type SystemInstanceHostInfo struct {
Hostname string `json:"hostname"`
}
type SystemInstanceResources struct {
CPU SystemInstanceResourceUsage `json:"cpu"`
Memory SystemInstanceResourceUsage `json:"memory"`
Storage SystemInstanceStorageMetrics `json:"storage"`
}
type SystemInstanceResourceUsage struct {
UsagePercent float64 `json:"usage_percent"`
}
type SystemInstanceStorageMetrics struct {
TotalBytes uint64 `json:"total_bytes"`
UsedBytes uint64 `json:"used_bytes"`
FreeBytes uint64 `json:"free_bytes"`
UsedPercent float64 `json:"used_percent"`
}
func StartSystemInstanceReporter() {
systemInstanceReporterOnce.Do(func() {
gopool.Go(func() {
reportSystemInstanceWithLog()
ticker := time.NewTicker(systemInstanceReportInterval)
defer ticker.Stop()
for range ticker.C {
reportSystemInstanceWithLog()
}
})
})
}
func ReportCurrentSystemInstance() error {
identity := common.GetNodeIdentity()
hostname, hostnameErr := os.Hostname()
if strings.TrimSpace(identity.Name) == "" {
if hostnameErr != nil || strings.TrimSpace(hostname) == "" {
return fmt.Errorf("system instance node name is empty")
}
identity.Name = hostname
identity.Source = common.NodeNameSourceHostname
identity.ManuallyConfigured = false
identity.ShouldConfigureManually = true
}
systemStatus := common.GetSystemStatus()
diskInfo := common.GetDiskSpaceInfo()
info := SystemInstanceInfo{
SchemaVersion: 1,
Node: identity,
Role: SystemInstanceRoleInfo{
IsMaster: common.IsMasterNode,
},
Runtime: SystemInstanceRuntimeInfo{
Version: common.Version,
GOOS: runtime.GOOS,
GOARCH: runtime.GOARCH,
StartedAt: common.StartTime,
},
Host: SystemInstanceHostInfo{
Hostname: hostname,
},
Resources: SystemInstanceResources{
CPU: SystemInstanceResourceUsage{
UsagePercent: systemStatus.CPUUsage,
},
Memory: SystemInstanceResourceUsage{
UsagePercent: systemStatus.MemoryUsage,
},
Storage: SystemInstanceStorageMetrics{
TotalBytes: diskInfo.Total,
UsedBytes: diskInfo.Used,
FreeBytes: diskInfo.Free,
UsedPercent: diskInfo.UsedPercent,
},
},
}
return model.UpsertSystemInstance(identity.Name, info, common.StartTime, common.GetTimestamp())
}
func reportSystemInstanceWithLog() {
if err := ReportCurrentSystemInstance(); err != nil {
logger.LogWarn(context.Background(), fmt.Sprintf("system instance report failed: %v", err))
}
}