performance.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package controller
  2. import (
  3. "net/http"
  4. "os"
  5. "path/filepath"
  6. "runtime"
  7. "github.com/QuantumNous/new-api/common"
  8. "github.com/gin-gonic/gin"
  9. )
  10. // PerformanceStats 性能统计信息
  11. type PerformanceStats struct {
  12. // 缓存统计
  13. CacheStats common.DiskCacheStats `json:"cache_stats"`
  14. // 系统内存统计
  15. MemoryStats MemoryStats `json:"memory_stats"`
  16. // 磁盘缓存目录信息
  17. DiskCacheInfo DiskCacheInfo `json:"disk_cache_info"`
  18. // 磁盘空间信息
  19. DiskSpaceInfo DiskSpaceInfo `json:"disk_space_info"`
  20. // 配置信息
  21. Config PerformanceConfig `json:"config"`
  22. }
  23. // MemoryStats 内存统计
  24. type MemoryStats struct {
  25. // 已分配内存(字节)
  26. Alloc uint64 `json:"alloc"`
  27. // 总分配内存(字节)
  28. TotalAlloc uint64 `json:"total_alloc"`
  29. // 系统内存(字节)
  30. Sys uint64 `json:"sys"`
  31. // GC 次数
  32. NumGC uint32 `json:"num_gc"`
  33. // Goroutine 数量
  34. NumGoroutine int `json:"num_goroutine"`
  35. }
  36. // DiskCacheInfo 磁盘缓存目录信息
  37. type DiskCacheInfo struct {
  38. // 缓存目录路径
  39. Path string `json:"path"`
  40. // 目录是否存在
  41. Exists bool `json:"exists"`
  42. // 文件数量
  43. FileCount int `json:"file_count"`
  44. // 总大小(字节)
  45. TotalSize int64 `json:"total_size"`
  46. }
  47. // DiskSpaceInfo 磁盘空间信息
  48. type DiskSpaceInfo struct {
  49. // 总空间(字节)
  50. Total uint64 `json:"total"`
  51. // 可用空间(字节)
  52. Free uint64 `json:"free"`
  53. // 已用空间(字节)
  54. Used uint64 `json:"used"`
  55. // 使用百分比
  56. UsedPercent float64 `json:"used_percent"`
  57. }
  58. // PerformanceConfig 性能配置
  59. type PerformanceConfig struct {
  60. // 是否启用磁盘缓存
  61. DiskCacheEnabled bool `json:"disk_cache_enabled"`
  62. // 磁盘缓存阈值(MB)
  63. DiskCacheThresholdMB int `json:"disk_cache_threshold_mb"`
  64. // 磁盘缓存最大大小(MB)
  65. DiskCacheMaxSizeMB int `json:"disk_cache_max_size_mb"`
  66. // 磁盘缓存路径
  67. DiskCachePath string `json:"disk_cache_path"`
  68. // 是否在容器中运行
  69. IsRunningInContainer bool `json:"is_running_in_container"`
  70. }
  71. // GetPerformanceStats 获取性能统计信息
  72. func GetPerformanceStats(c *gin.Context) {
  73. // 获取缓存统计
  74. cacheStats := common.GetDiskCacheStats()
  75. // 获取内存统计
  76. var memStats runtime.MemStats
  77. runtime.ReadMemStats(&memStats)
  78. // 获取磁盘缓存目录信息
  79. diskCacheInfo := getDiskCacheInfo()
  80. // 获取配置信息
  81. diskConfig := common.GetDiskCacheConfig()
  82. config := PerformanceConfig{
  83. DiskCacheEnabled: diskConfig.Enabled,
  84. DiskCacheThresholdMB: diskConfig.ThresholdMB,
  85. DiskCacheMaxSizeMB: diskConfig.MaxSizeMB,
  86. DiskCachePath: diskConfig.Path,
  87. IsRunningInContainer: common.IsRunningInContainer(),
  88. }
  89. // 获取磁盘空间信息
  90. diskSpaceInfo := getDiskSpaceInfo()
  91. stats := PerformanceStats{
  92. CacheStats: cacheStats,
  93. MemoryStats: MemoryStats{
  94. Alloc: memStats.Alloc,
  95. TotalAlloc: memStats.TotalAlloc,
  96. Sys: memStats.Sys,
  97. NumGC: memStats.NumGC,
  98. NumGoroutine: runtime.NumGoroutine(),
  99. },
  100. DiskCacheInfo: diskCacheInfo,
  101. DiskSpaceInfo: diskSpaceInfo,
  102. Config: config,
  103. }
  104. c.JSON(http.StatusOK, gin.H{
  105. "success": true,
  106. "data": stats,
  107. })
  108. }
  109. // ClearDiskCache 清理磁盘缓存
  110. func ClearDiskCache(c *gin.Context) {
  111. cachePath := common.GetDiskCachePath()
  112. if cachePath == "" {
  113. cachePath = os.TempDir()
  114. }
  115. dir := filepath.Join(cachePath, "new-api-body-cache")
  116. // 删除缓存目录
  117. err := os.RemoveAll(dir)
  118. if err != nil && !os.IsNotExist(err) {
  119. common.ApiError(c, err)
  120. return
  121. }
  122. // 重置统计
  123. common.ResetDiskCacheStats()
  124. c.JSON(http.StatusOK, gin.H{
  125. "success": true,
  126. "message": "磁盘缓存已清理",
  127. })
  128. }
  129. // ResetPerformanceStats 重置性能统计
  130. func ResetPerformanceStats(c *gin.Context) {
  131. common.ResetDiskCacheStats()
  132. c.JSON(http.StatusOK, gin.H{
  133. "success": true,
  134. "message": "统计信息已重置",
  135. })
  136. }
  137. // ForceGC 强制执行 GC
  138. func ForceGC(c *gin.Context) {
  139. runtime.GC()
  140. c.JSON(http.StatusOK, gin.H{
  141. "success": true,
  142. "message": "GC 已执行",
  143. })
  144. }
  145. // getDiskCacheInfo 获取磁盘缓存目录信息
  146. func getDiskCacheInfo() DiskCacheInfo {
  147. cachePath := common.GetDiskCachePath()
  148. if cachePath == "" {
  149. cachePath = os.TempDir()
  150. }
  151. dir := filepath.Join(cachePath, "new-api-body-cache")
  152. info := DiskCacheInfo{
  153. Path: dir,
  154. Exists: false,
  155. }
  156. entries, err := os.ReadDir(dir)
  157. if err != nil {
  158. return info
  159. }
  160. info.Exists = true
  161. info.FileCount = 0
  162. info.TotalSize = 0
  163. for _, entry := range entries {
  164. if entry.IsDir() {
  165. continue
  166. }
  167. info.FileCount++
  168. if fileInfo, err := entry.Info(); err == nil {
  169. info.TotalSize += fileInfo.Size()
  170. }
  171. }
  172. return info
  173. }