diff --git a/common/performance_config.go b/common/performance_config.go new file mode 100644 index 000000000..941d9eab8 --- /dev/null +++ b/common/performance_config.go @@ -0,0 +1,33 @@ +package common + +import "sync/atomic" + +// PerformanceMonitorConfig 性能监控配置 +type PerformanceMonitorConfig struct { + Enabled bool + CPUThreshold int + MemoryThreshold int + DiskThreshold int +} + +var performanceMonitorConfig atomic.Value + +func init() { + // 初始化默认配置 + performanceMonitorConfig.Store(PerformanceMonitorConfig{ + Enabled: true, + CPUThreshold: 90, + MemoryThreshold: 90, + DiskThreshold: 90, + }) +} + +// GetPerformanceMonitorConfig 获取性能监控配置 +func GetPerformanceMonitorConfig() PerformanceMonitorConfig { + return performanceMonitorConfig.Load().(PerformanceMonitorConfig) +} + +// SetPerformanceMonitorConfig 设置性能监控配置 +func SetPerformanceMonitorConfig(config PerformanceMonitorConfig) { + performanceMonitorConfig.Store(config) +} diff --git a/common/system_monitor.go b/common/system_monitor.go new file mode 100644 index 000000000..26710faed --- /dev/null +++ b/common/system_monitor.go @@ -0,0 +1,81 @@ +package common + +import ( + "sync/atomic" + "time" + + "github.com/shirou/gopsutil/cpu" + "github.com/shirou/gopsutil/mem" +) + +// DiskSpaceInfo 磁盘空间信息 +type DiskSpaceInfo struct { + // 总空间(字节) + Total uint64 `json:"total"` + // 可用空间(字节) + Free uint64 `json:"free"` + // 已用空间(字节) + Used uint64 `json:"used"` + // 使用百分比 + UsedPercent float64 `json:"used_percent"` +} + +// SystemStatus 系统状态信息 +type SystemStatus struct { + CPUUsage float64 + MemoryUsage float64 + DiskUsage float64 +} + +var latestSystemStatus atomic.Value + +func init() { + latestSystemStatus.Store(SystemStatus{}) +} + +// StartSystemMonitor 启动系统监控 +func StartSystemMonitor() { + go func() { + for { + config := GetPerformanceMonitorConfig() + if !config.Enabled { + time.Sleep(30 * time.Second) + continue + } + + updateSystemStatus() + time.Sleep(5 * time.Second) + } + }() +} + +func updateSystemStatus() { + var status SystemStatus + + // CPU + // 注意:cpu.Percent(0, false) 返回自上次调用以来的 CPU 使用率 + // 如果是第一次调用,可能会返回错误或不准确的值,但在循环中会逐渐正常 + percents, err := cpu.Percent(0, false) + if err == nil && len(percents) > 0 { + status.CPUUsage = percents[0] + } + + // Memory + memInfo, err := mem.VirtualMemory() + if err == nil { + status.MemoryUsage = memInfo.UsedPercent + } + + // Disk + diskInfo := GetDiskSpaceInfo() + if diskInfo.Total > 0 { + status.DiskUsage = diskInfo.UsedPercent + } + + latestSystemStatus.Store(status) +} + +// GetSystemStatus 获取当前系统状态 +func GetSystemStatus() SystemStatus { + return latestSystemStatus.Load().(SystemStatus) +} diff --git a/controller/performance_unix.go b/common/system_monitor_unix.go similarity index 75% rename from controller/performance_unix.go rename to common/system_monitor_unix.go index b6ff62d2a..673b964d2 100644 --- a/controller/performance_unix.go +++ b/common/system_monitor_unix.go @@ -1,17 +1,16 @@ //go:build !windows -package controller +package common import ( "os" - "github.com/QuantumNous/new-api/common" "golang.org/x/sys/unix" ) -// getDiskSpaceInfo 获取缓存目录所在磁盘的空间信息 (Unix/Linux/macOS) -func getDiskSpaceInfo() DiskSpaceInfo { - cachePath := common.GetDiskCachePath() +// GetDiskSpaceInfo 获取缓存目录所在磁盘的空间信息 (Unix/Linux/macOS) +func GetDiskSpaceInfo() DiskSpaceInfo { + cachePath := GetDiskCachePath() if cachePath == "" { cachePath = os.TempDir() } diff --git a/controller/performance_windows.go b/common/system_monitor_windows.go similarity index 80% rename from controller/performance_windows.go rename to common/system_monitor_windows.go index d4c4b6e9c..7db766731 100644 --- a/controller/performance_windows.go +++ b/common/system_monitor_windows.go @@ -1,18 +1,16 @@ //go:build windows -package controller +package common import ( "os" "syscall" "unsafe" - - "github.com/QuantumNous/new-api/common" ) -// getDiskSpaceInfo 获取缓存目录所在磁盘的空间信息 (Windows) -func getDiskSpaceInfo() DiskSpaceInfo { - cachePath := common.GetDiskCachePath() +// GetDiskSpaceInfo 获取缓存目录所在磁盘的空间信息 (Windows) +func GetDiskSpaceInfo() DiskSpaceInfo { + cachePath := GetDiskCachePath() if cachePath == "" { cachePath = os.TempDir() } diff --git a/controller/performance.go b/controller/performance.go index 44887c2db..8e5281e99 100644 --- a/controller/performance.go +++ b/controller/performance.go @@ -19,7 +19,7 @@ type PerformanceStats struct { // 磁盘缓存目录信息 DiskCacheInfo DiskCacheInfo `json:"disk_cache_info"` // 磁盘空间信息 - DiskSpaceInfo DiskSpaceInfo `json:"disk_space_info"` + DiskSpaceInfo common.DiskSpaceInfo `json:"disk_space_info"` // 配置信息 Config PerformanceConfig `json:"config"` } @@ -50,18 +50,6 @@ type DiskCacheInfo struct { TotalSize int64 `json:"total_size"` } -// DiskSpaceInfo 磁盘空间信息 -type DiskSpaceInfo struct { - // 总空间(字节) - Total uint64 `json:"total"` - // 可用空间(字节) - Free uint64 `json:"free"` - // 已用空间(字节) - Used uint64 `json:"used"` - // 使用百分比 - UsedPercent float64 `json:"used_percent"` -} - // PerformanceConfig 性能配置 type PerformanceConfig struct { // 是否启用磁盘缓存 @@ -74,6 +62,15 @@ type PerformanceConfig struct { DiskCachePath string `json:"disk_cache_path"` // 是否在容器中运行 IsRunningInContainer bool `json:"is_running_in_container"` + + // MonitorEnabled 是否启用性能监控 + MonitorEnabled bool `json:"monitor_enabled"` + // MonitorCPUThreshold CPU 使用率阈值(%) + MonitorCPUThreshold int `json:"monitor_cpu_threshold"` + // MonitorMemoryThreshold 内存使用率阈值(%) + MonitorMemoryThreshold int `json:"monitor_memory_threshold"` + // MonitorDiskThreshold 磁盘使用率阈值(%) + MonitorDiskThreshold int `json:"monitor_disk_threshold"` } // GetPerformanceStats 获取性能统计信息 @@ -91,16 +88,30 @@ func GetPerformanceStats(c *gin.Context) { // 获取配置信息 diskConfig := common.GetDiskCacheConfig() + monitorConfig := common.GetPerformanceMonitorConfig() config := PerformanceConfig{ - DiskCacheEnabled: diskConfig.Enabled, - DiskCacheThresholdMB: diskConfig.ThresholdMB, - DiskCacheMaxSizeMB: diskConfig.MaxSizeMB, - DiskCachePath: diskConfig.Path, - IsRunningInContainer: common.IsRunningInContainer(), + DiskCacheEnabled: diskConfig.Enabled, + DiskCacheThresholdMB: diskConfig.ThresholdMB, + DiskCacheMaxSizeMB: diskConfig.MaxSizeMB, + DiskCachePath: diskConfig.Path, + IsRunningInContainer: common.IsRunningInContainer(), + MonitorEnabled: monitorConfig.Enabled, + MonitorCPUThreshold: monitorConfig.CPUThreshold, + MonitorMemoryThreshold: monitorConfig.MemoryThreshold, + MonitorDiskThreshold: monitorConfig.DiskThreshold, } // 获取磁盘空间信息 - diskSpaceInfo := getDiskSpaceInfo() + // 使用缓存的系统状态,避免频繁调用系统 API + systemStatus := common.GetSystemStatus() + diskSpaceInfo := common.DiskSpaceInfo{ + UsedPercent: systemStatus.DiskUsage, + } + // 如果需要详细信息,可以按需获取,或者扩展 SystemStatus + // 这里为了保持接口兼容性,我们仍然调用 GetDiskSpaceInfo,但注意这可能会有性能开销 + // 考虑到 GetPerformanceStats 是管理接口,频率较低,直接调用是可以接受的 + // 但为了一致性,我们也可以考虑从 SystemStatus 中获取部分信息 + diskSpaceInfo = common.GetDiskSpaceInfo() stats := PerformanceStats{ CacheStats: cacheStats, diff --git a/main.go b/main.go index 47f966da2..2bc897e8c 100644 --- a/main.go +++ b/main.go @@ -274,5 +274,9 @@ func InitResources() error { if err != nil { return err } + + // 启动系统监控 + common.StartSystemMonitor() + return nil } diff --git a/middleware/performance.go b/middleware/performance.go new file mode 100644 index 000000000..2229a8af5 --- /dev/null +++ b/middleware/performance.go @@ -0,0 +1,65 @@ +package middleware + +import ( + "errors" + "net/http" + "strings" + + "github.com/QuantumNous/new-api/common" + "github.com/QuantumNous/new-api/types" + "github.com/gin-gonic/gin" +) + +// SystemPerformanceCheck 检查系统性能中间件 +func SystemPerformanceCheck() gin.HandlerFunc { + return func(c *gin.Context) { + // 仅检查 Relay 接口 (/v1, /v1beta 等) + // 这里简单判断路径前缀,可以根据实际路由调整 + path := c.Request.URL.Path + if strings.HasPrefix(path, "/v1/messages") { + if err := checkSystemPerformance(); err != nil { + c.JSON(err.StatusCode, gin.H{ + "error": err.ToClaudeError(), + }) + c.Abort() + return + } + } else { + if err := checkSystemPerformance(); err != nil { + c.JSON(err.StatusCode, gin.H{ + "error": err.ToOpenAIError(), + }) + c.Abort() + return + } + } + c.Next() + } +} + +// checkSystemPerformance 检查系统性能是否超过阈值 +func checkSystemPerformance() *types.NewAPIError { + config := common.GetPerformanceMonitorConfig() + if !config.Enabled { + return nil + } + + status := common.GetSystemStatus() + + // 检查 CPU + if config.CPUThreshold > 0 && int(status.CPUUsage) > config.CPUThreshold { + return types.NewErrorWithStatusCode(errors.New("system cpu overloaded"), "system_cpu_overloaded", http.StatusServiceUnavailable) + } + + // 检查内存 + if config.MemoryThreshold > 0 && int(status.MemoryUsage) > config.MemoryThreshold { + return types.NewErrorWithStatusCode(errors.New("system memory overloaded"), "system_memory_overloaded", http.StatusServiceUnavailable) + } + + // 检查磁盘 + if config.DiskThreshold > 0 && int(status.DiskUsage) > config.DiskThreshold { + return types.NewErrorWithStatusCode(errors.New("system disk overloaded"), "system_disk_overloaded", http.StatusServiceUnavailable) + } + + return nil +} diff --git a/router/relay-router.go b/router/relay-router.go index 3f0329b36..04584945b 100644 --- a/router/relay-router.go +++ b/router/relay-router.go @@ -57,11 +57,13 @@ func SetRelayRouter(router *gin.Engine) { } playgroundRouter := router.Group("/pg") + playgroundRouter.Use(middleware.SystemPerformanceCheck()) playgroundRouter.Use(middleware.UserAuth(), middleware.Distribute()) { playgroundRouter.POST("/chat/completions", controller.Playground) } relayV1Router := router.Group("/v1") + relayV1Router.Use(middleware.SystemPerformanceCheck()) relayV1Router.Use(middleware.TokenAuth()) relayV1Router.Use(middleware.ModelRequestRateLimit()) { @@ -159,13 +161,16 @@ func SetRelayRouter(router *gin.Engine) { } relayMjRouter := router.Group("/mj") + relayMjRouter.Use(middleware.SystemPerformanceCheck()) registerMjRouterGroup(relayMjRouter) relayMjModeRouter := router.Group("/:mode/mj") + relayMjModeRouter.Use(middleware.SystemPerformanceCheck()) registerMjRouterGroup(relayMjModeRouter) //relayMjRouter.Use() relaySunoRouter := router.Group("/suno") + relaySunoRouter.Use(middleware.SystemPerformanceCheck()) relaySunoRouter.Use(middleware.TokenAuth(), middleware.Distribute()) { relaySunoRouter.POST("/submit/:action", controller.RelayTask) @@ -174,6 +179,7 @@ func SetRelayRouter(router *gin.Engine) { } relayGeminiRouter := router.Group("/v1beta") + relayGeminiRouter.Use(middleware.SystemPerformanceCheck()) relayGeminiRouter.Use(middleware.TokenAuth()) relayGeminiRouter.Use(middleware.ModelRequestRateLimit()) relayGeminiRouter.Use(middleware.Distribute()) diff --git a/setting/performance_setting/config.go b/setting/performance_setting/config.go index 47ce9d45e..b4baff876 100644 --- a/setting/performance_setting/config.go +++ b/setting/performance_setting/config.go @@ -15,6 +15,15 @@ type PerformanceSetting struct { DiskCacheMaxSizeMB int `json:"disk_cache_max_size_mb"` // DiskCachePath 磁盘缓存目录 DiskCachePath string `json:"disk_cache_path"` + + // MonitorEnabled 是否启用性能监控 + MonitorEnabled bool `json:"monitor_enabled"` + // MonitorCPUThreshold CPU 使用率阈值(%) + MonitorCPUThreshold int `json:"monitor_cpu_threshold"` + // MonitorMemoryThreshold 内存使用率阈值(%) + MonitorMemoryThreshold int `json:"monitor_memory_threshold"` + // MonitorDiskThreshold 磁盘使用率阈值(%) + MonitorDiskThreshold int `json:"monitor_disk_threshold"` } // 默认配置 @@ -23,6 +32,11 @@ var performanceSetting = PerformanceSetting{ DiskCacheThresholdMB: 10, // 超过 10MB 使用磁盘缓存 DiskCacheMaxSizeMB: 1024, // 最大 1GB 磁盘缓存 DiskCachePath: "", // 空表示使用系统临时目录 + + MonitorEnabled: true, + MonitorCPUThreshold: 90, + MonitorMemoryThreshold: 90, + MonitorDiskThreshold: 90, } func init() { @@ -40,6 +54,13 @@ func syncToCommon() { MaxSizeMB: performanceSetting.DiskCacheMaxSizeMB, Path: performanceSetting.DiskCachePath, }) + + common.SetPerformanceMonitorConfig(common.PerformanceMonitorConfig{ + Enabled: performanceSetting.MonitorEnabled, + CPUThreshold: performanceSetting.MonitorCPUThreshold, + MemoryThreshold: performanceSetting.MonitorMemoryThreshold, + DiskThreshold: performanceSetting.MonitorDiskThreshold, + }) } // GetPerformanceSetting 获取性能设置 diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index 4ebe93553..9119f9cb8 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -2316,6 +2316,45 @@ "输入验证码完成设置": "Enter verification code to complete setup", "输出": "Output", "输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}": "Output {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}}", + "磁盘缓存设置(磁盘换内存)": "Disk Cache Settings (Disk Swap Memory)", + "启用磁盘缓存后,大请求体将临时存储到磁盘而非内存,可显著降低内存占用,适用于处理包含大量图片/文件的请求。建议在 SSD 环境下使用。": "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. Suitable for requests with large images/files. SSD recommended.", + "启用磁盘缓存": "Enable Disk Cache", + "将大请求体临时存储到磁盘": "Store large request bodies temporarily on disk", + "磁盘缓存阈值 (MB)": "Disk Cache Threshold (MB)", + "请求体超过此大小时使用磁盘缓存": "Use disk cache when request body exceeds this size", + "磁盘缓存最大总量 (MB)": "Max Disk Cache Size (MB)", + "可用空间: {{free}} / 总空间: {{total}}": "Free: {{free}} / Total: {{total}}", + "磁盘缓存占用的最大空间": "Maximum space occupied by disk cache", + "留空使用系统临时目录": "Leave empty to use system temp directory", + "例如 /var/cache/new-api": "e.g. /var/cache/new-api", + "性能监控": "Performance Monitor", + "刷新统计": "Refresh Stats", + "重置统计": "Reset Stats", + "执行 GC": "Run GC", + "请求体磁盘缓存": "Request Body Disk Cache", + "活跃文件": "Active Files", + "磁盘命中": "Disk Hits", + "请求体内存缓存": "Request Body Memory Cache", + "当前缓存大小": "Current Cache Size", + "活跃缓存数": "Active Cache Count", + "内存命中": "Memory Hits", + "缓存目录磁盘空间": "Cache Directory Disk Space", + "磁盘可用空间小于缓存最大总量设置": "Disk free space is less than max cache size setting", + "已分配内存": "Allocated Memory", + "总分配内存": "Total Allocated Memory", + "系统内存": "System Memory", + "GC 次数": "GC Count", + "Goroutine 数": "Goroutine Count", + "目录文件数": "Directory File Count", + "目录总大小": "Directory Total Size", + "磁盘缓存已清理": "Disk cache cleared", + "清理失败": "Cleanup failed", + "统计已重置": "Statistics reset", + "重置失败": "Reset failed", + "GC 已执行": "GC executed", + "GC 执行失败": "GC execution failed", + "缓存目录": "Cache Directory", + "可用": "Available", "输出价格": "Output Price", "输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "Output price: {{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (Completion ratio: {{completionRatio}})", "输出倍率 {{completionRatio}}": "Output ratio {{completionRatio}}", @@ -2687,6 +2726,46 @@ "套餐名称": "Plan Name", "应付金额": "Amount Due", "支付": "Pay", - "管理员未开启在线支付功能,请联系管理员配置。": "Online payment is not enabled by the admin. Please contact the administrator." + "管理员未开启在线支付功能,请联系管理员配置。": "Online payment is not enabled by the admin. Please contact the administrator.", + "磁盘缓存设置(磁盘换内存)": "Disk Cache Settings (Disk Swap Memory)", + "启用磁盘缓存后,大请求体将临时存储到磁盘而非内存,可显著降低内存占用,适用于处理包含大量图片/文件的请求。建议在 SSD 环境下使用。": "When enabled, large request bodies are temporarily stored on disk instead of memory, significantly reducing memory usage. Suitable for requests with large images/files. SSD recommended.", + "启用磁盘缓存": "Enable Disk Cache", + "将大请求体临时存储到磁盘": "Store large request bodies temporarily on disk", + "磁盘缓存阈值 (MB)": "Disk Cache Threshold (MB)", + "请求体超过此大小时使用磁盘缓存": "Use disk cache when request body exceeds this size", + "磁盘缓存最大总量 (MB)": "Max Disk Cache Size (MB)", + "可用空间: {{free}} / 总空间: {{total}}": "Free: {{free}} / Total: {{total}}", + "磁盘缓存占用的最大空间": "Maximum space occupied by disk cache", + "留空使用系统临时目录": "Leave empty to use system temp directory", + "例如 /var/cache/new-api": "e.g. /var/cache/new-api", + "性能监控": "Performance Monitor", + "刷新统计": "Refresh Stats", + "重置统计": "Reset Stats", + "执行 GC": "Run GC", + "请求体磁盘缓存": "Request Body Disk Cache", + "活跃文件": "Active Files", + "磁盘命中": "Disk Hits", + "请求体内存缓存": "Request Body Memory Cache", + "当前缓存大小": "Current Cache Size", + "活跃缓存数": "Active Cache Count", + "内存命中": "Memory Hits", + "缓存目录磁盘空间": "Cache Directory Disk Space", + "磁盘可用空间小于缓存最大总量设置": "Disk free space is less than max cache size setting", + "已分配内存": "Allocated Memory", + "总分配内存": "Total Allocated Memory", + "系统内存": "System Memory", + "GC 次数": "GC Count", + "Goroutine 数": "Goroutine Count", + "目录文件数": "Directory File Count", + "目录总大小": "Directory Total Size", + "磁盘缓存已清理": "Disk cache cleared", + "清理失败": "Cleanup failed", + "统计已重置": "Statistics reset", + "重置失败": "Reset failed", + "GC 已执行": "GC executed", + "GC execution failed": "GC execution failed", + "Cache Directory": "Cache Directory", + "Available": "Available", + "输出价格": "Output Price" } } diff --git a/web/src/i18n/locales/zh.json b/web/src/i18n/locales/zh.json index ed4f921e9..46eea9ce6 100644 --- a/web/src/i18n/locales/zh.json +++ b/web/src/i18n/locales/zh.json @@ -1823,6 +1823,17 @@ "系统文档和帮助信息": "系统文档和帮助信息", "系统消息": "系统消息", "系统管理功能": "系统管理功能", + "系统性能监控": "系统性能监控", + "启用性能监控后,当系统资源使用率超过设定阈值时,将拒绝新的 Relay 请求 (/v1, /v1beta 等),以保护系统稳定性。": "启用性能监控后,当系统资源使用率超过设定阈值时,将拒绝新的 Relay 请求 (/v1, /v1beta 等),以保护系统稳定性。", + "启用性能监控": "启用性能监控", + "超过阈值时拒绝新请求": "超过阈值时拒绝新请求", + "CPU 阈值 (%)": "CPU 阈值 (%)", + "CPU 使用率超过此值时拒绝请求": "CPU 使用率超过此值时拒绝请求", + "内存 阈值 (%)": "内存 阈值 (%)", + "内存使用率超过此值时拒绝请求": "内存使用率超过此值时拒绝请求", + "磁盘 阈值 (%)": "磁盘 阈值 (%)", + "磁盘使用率超过此值时拒绝请求": "磁盘使用率超过此值时拒绝请求", + "保存性能设置": "保存性能设置", "系统设置": "系统设置", "系统访问令牌": "系统访问令牌", "约": "约", @@ -2305,6 +2316,45 @@ "输入验证码完成设置": "输入验证码完成设置", "输出": "输出", "输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}": "输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}", + "磁盘缓存设置(磁盘换内存)": "磁盘缓存设置(磁盘换内存)", + "启用磁盘缓存后,大请求体将临时存储到磁盘而非内存,可显著降低内存占用,适用于处理包含大量图片/文件的请求。建议在 SSD 环境下使用。": "启用磁盘缓存后,大请求体将临时存储到磁盘而非内存,可显著降低内存占用,适用于处理包含大量图片/文件的请求。建议在 SSD 环境下使用。", + "启用磁盘缓存": "启用磁盘缓存", + "将大请求体临时存储到磁盘": "将大请求体临时存储到磁盘", + "磁盘缓存阈值 (MB)": "磁盘缓存阈值 (MB)", + "请求体超过此大小时使用磁盘缓存": "请求体超过此大小时使用磁盘缓存", + "磁盘缓存最大总量 (MB)": "磁盘缓存最大总量 (MB)", + "可用空间: {{free}} / 总空间: {{total}}": "可用空间: {{free}} / 总空间: {{total}}", + "磁盘缓存占用的最大空间": "磁盘缓存占用的最大空间", + "留空使用系统临时目录": "留空使用系统临时目录", + "例如 /var/cache/new-api": "例如 /var/cache/new-api", + "性能监控": "性能监控", + "刷新统计": "刷新统计", + "重置统计": "重置统计", + "执行 GC": "执行 GC", + "请求体磁盘缓存": "请求体磁盘缓存", + "活跃文件": "活跃文件", + "磁盘命中": "磁盘命中", + "请求体内存缓存": "请求体内存缓存", + "当前缓存大小": "当前缓存大小", + "活跃缓存数": "活跃缓存数", + "内存命中": "内存命中", + "缓存目录磁盘空间": "缓存目录磁盘空间", + "磁盘可用空间小于缓存最大总量设置": "磁盘可用空间小于缓存最大总量设置", + "已分配内存": "已分配内存", + "总分配内存": "总分配内存", + "系统内存": "系统内存", + "GC 次数": "GC 次数", + "Goroutine 数": "Goroutine 数", + "目录文件数": "目录文件数", + "目录总大小": "目录总大小", + "磁盘缓存已清理": "磁盘缓存已清理", + "清理失败": "清理失败", + "统计已重置": "统计已重置", + "重置失败": "重置失败", + "GC 已执行": "GC 已执行", + "GC 执行失败": "GC 执行失败", + "缓存目录": "缓存目录", + "可用": "可用", "输出价格": "输出价格", "输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})": "输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})", "输出倍率 {{completionRatio}}": "输出倍率 {{completionRatio}}", diff --git a/web/src/pages/Setting/Performance/SettingsPerformance.jsx b/web/src/pages/Setting/Performance/SettingsPerformance.jsx index 1669a43f0..146695069 100644 --- a/web/src/pages/Setting/Performance/SettingsPerformance.jsx +++ b/web/src/pages/Setting/Performance/SettingsPerformance.jsx @@ -65,6 +65,10 @@ export default function SettingsPerformance(props) { 'performance_setting.disk_cache_threshold_mb': 10, 'performance_setting.disk_cache_max_size_mb': 1024, 'performance_setting.disk_cache_path': '', + 'performance_setting.monitor_enabled': false, + 'performance_setting.monitor_cpu_threshold': 90, + 'performance_setting.monitor_memory_threshold': 90, + 'performance_setting.monitor_disk_threshold': 90, }); const refForm = useRef(); const [inputsRow, setInputsRow] = useState(inputs); @@ -274,6 +278,70 @@ export default function SettingsPerformance(props) { )} + + +