| | package controller
|
| |
|
| | import (
|
| | "net/http"
|
| | "os"
|
| | "path/filepath"
|
| | "runtime"
|
| |
|
| | "github.com/QuantumNous/new-api/common"
|
| | "github.com/gin-gonic/gin"
|
| | )
|
| |
|
| |
|
| | type PerformanceStats struct {
|
| |
|
| | CacheStats common.DiskCacheStats `json:"cache_stats"`
|
| |
|
| | MemoryStats MemoryStats `json:"memory_stats"`
|
| |
|
| | DiskCacheInfo DiskCacheInfo `json:"disk_cache_info"`
|
| |
|
| | DiskSpaceInfo DiskSpaceInfo `json:"disk_space_info"`
|
| |
|
| | Config PerformanceConfig `json:"config"`
|
| | }
|
| |
|
| |
|
| | type MemoryStats struct {
|
| |
|
| | Alloc uint64 `json:"alloc"`
|
| |
|
| | TotalAlloc uint64 `json:"total_alloc"`
|
| |
|
| | Sys uint64 `json:"sys"`
|
| |
|
| | NumGC uint32 `json:"num_gc"`
|
| |
|
| | NumGoroutine int `json:"num_goroutine"`
|
| | }
|
| |
|
| |
|
| | type DiskCacheInfo struct {
|
| |
|
| | Path string `json:"path"`
|
| |
|
| | Exists bool `json:"exists"`
|
| |
|
| | FileCount int `json:"file_count"`
|
| |
|
| | TotalSize int64 `json:"total_size"`
|
| | }
|
| |
|
| |
|
| | type DiskSpaceInfo struct {
|
| |
|
| | Total uint64 `json:"total"`
|
| |
|
| | Free uint64 `json:"free"`
|
| |
|
| | Used uint64 `json:"used"`
|
| |
|
| | UsedPercent float64 `json:"used_percent"`
|
| | }
|
| |
|
| |
|
| | type PerformanceConfig struct {
|
| |
|
| | DiskCacheEnabled bool `json:"disk_cache_enabled"`
|
| |
|
| | DiskCacheThresholdMB int `json:"disk_cache_threshold_mb"`
|
| |
|
| | DiskCacheMaxSizeMB int `json:"disk_cache_max_size_mb"`
|
| |
|
| | DiskCachePath string `json:"disk_cache_path"`
|
| |
|
| | IsRunningInContainer bool `json:"is_running_in_container"`
|
| | }
|
| |
|
| |
|
| | func GetPerformanceStats(c *gin.Context) {
|
| |
|
| | cacheStats := common.GetDiskCacheStats()
|
| |
|
| |
|
| | var memStats runtime.MemStats
|
| | runtime.ReadMemStats(&memStats)
|
| |
|
| |
|
| | diskCacheInfo := getDiskCacheInfo()
|
| |
|
| |
|
| | diskConfig := common.GetDiskCacheConfig()
|
| | config := PerformanceConfig{
|
| | DiskCacheEnabled: diskConfig.Enabled,
|
| | DiskCacheThresholdMB: diskConfig.ThresholdMB,
|
| | DiskCacheMaxSizeMB: diskConfig.MaxSizeMB,
|
| | DiskCachePath: diskConfig.Path,
|
| | IsRunningInContainer: common.IsRunningInContainer(),
|
| | }
|
| |
|
| |
|
| | diskSpaceInfo := getDiskSpaceInfo()
|
| |
|
| | stats := PerformanceStats{
|
| | CacheStats: cacheStats,
|
| | MemoryStats: MemoryStats{
|
| | Alloc: memStats.Alloc,
|
| | TotalAlloc: memStats.TotalAlloc,
|
| | Sys: memStats.Sys,
|
| | NumGC: memStats.NumGC,
|
| | NumGoroutine: runtime.NumGoroutine(),
|
| | },
|
| | DiskCacheInfo: diskCacheInfo,
|
| | DiskSpaceInfo: diskSpaceInfo,
|
| | Config: config,
|
| | }
|
| |
|
| | c.JSON(http.StatusOK, gin.H{
|
| | "success": true,
|
| | "data": stats,
|
| | })
|
| | }
|
| |
|
| |
|
| | func ClearDiskCache(c *gin.Context) {
|
| | cachePath := common.GetDiskCachePath()
|
| | if cachePath == "" {
|
| | cachePath = os.TempDir()
|
| | }
|
| | dir := filepath.Join(cachePath, "new-api-body-cache")
|
| |
|
| |
|
| | err := os.RemoveAll(dir)
|
| | if err != nil && !os.IsNotExist(err) {
|
| | common.ApiError(c, err)
|
| | return
|
| | }
|
| |
|
| |
|
| | common.ResetDiskCacheStats()
|
| |
|
| | c.JSON(http.StatusOK, gin.H{
|
| | "success": true,
|
| | "message": "磁盘缓存已清理",
|
| | })
|
| | }
|
| |
|
| |
|
| | func ResetPerformanceStats(c *gin.Context) {
|
| | common.ResetDiskCacheStats()
|
| |
|
| | c.JSON(http.StatusOK, gin.H{
|
| | "success": true,
|
| | "message": "统计信息已重置",
|
| | })
|
| | }
|
| |
|
| |
|
| | func ForceGC(c *gin.Context) {
|
| | runtime.GC()
|
| |
|
| | c.JSON(http.StatusOK, gin.H{
|
| | "success": true,
|
| | "message": "GC 已执行",
|
| | })
|
| | }
|
| |
|
| |
|
| | func getDiskCacheInfo() DiskCacheInfo {
|
| | cachePath := common.GetDiskCachePath()
|
| | if cachePath == "" {
|
| | cachePath = os.TempDir()
|
| | }
|
| | dir := filepath.Join(cachePath, "new-api-body-cache")
|
| |
|
| | info := DiskCacheInfo{
|
| | Path: dir,
|
| | Exists: false,
|
| | }
|
| |
|
| | entries, err := os.ReadDir(dir)
|
| | if err != nil {
|
| | return info
|
| | }
|
| |
|
| | info.Exists = true
|
| | info.FileCount = 0
|
| | info.TotalSize = 0
|
| |
|
| | for _, entry := range entries {
|
| | if entry.IsDir() {
|
| | continue
|
| | }
|
| | info.FileCount++
|
| | if fileInfo, err := entry.Info(); err == nil {
|
| | info.TotalSize += fileInfo.Size()
|
| | }
|
| | }
|
| |
|
| | return info
|
| | }
|
| |
|