diff --git a/api/nginx/router.go b/api/nginx/router.go index e7be797d..f4440e92 100644 --- a/api/nginx/router.go +++ b/api/nginx/router.go @@ -13,13 +13,13 @@ func InitRouter(r *gin.RouterGroup) { r.POST("nginx/restart", Restart) r.POST("nginx/test", Test) r.GET("nginx/status", Status) - // 获取 Nginx 详细状态信息,包括连接数、进程信息等(Issue #850) + // Get detailed Nginx status information, including connection count, process information, etc. (Issue #850) r.GET("nginx/detail_status", GetDetailStatus) - // 使用SSE推送Nginx详细状态信息 + // Use SSE to push detailed Nginx status information r.GET("nginx/detail_status/stream", StreamDetailStatus) - // 获取 stub_status 模块状态 + // Get stub_status module status r.GET("nginx/stub_status", CheckStubStatus) - // 启用或禁用 stub_status 模块 + // Enable or disable stub_status module r.POST("nginx/stub_status", ToggleStubStatus) r.POST("nginx_log", nginx_log.GetNginxLogPage) r.GET("nginx/directives", GetDirectives) diff --git a/api/nginx/status.go b/api/nginx/status.go index 5b8d5e1b..d794e81f 100644 --- a/api/nginx/status.go +++ b/api/nginx/status.go @@ -1,6 +1,6 @@ -// GetDetailedStatus API 实现 -// 该功能用于解决 Issue #850,提供类似宝塔面板的 Nginx 负载监控功能 -// 返回详细的 Nginx 状态信息,包括请求统计、连接数、工作进程等数据 +// Implementation of GetDetailedStatus API +// This feature is designed to address Issue #850, providing Nginx load monitoring functionality similar to BT Panel +// Returns detailed Nginx status information, including request statistics, connections, worker processes, and other data package nginx import ( @@ -15,79 +15,79 @@ import ( "github.com/uozi-tech/cosy/logger" ) -// NginxPerformanceInfo 存储 Nginx 性能相关信息 +// NginxPerformanceInfo stores Nginx performance-related information type NginxPerformanceInfo struct { - // 基本状态信息 + // Basic status information nginx.StubStatusData - // 进程相关信息 + // Process-related information nginx.NginxProcessInfo - // 配置信息 + // Configuration information nginx.NginxConfigInfo } -// GetDetailStatus 获取 Nginx 详细状态信息 +// GetDetailStatus retrieves detailed Nginx status information func GetDetailStatus(c *gin.Context) { response := nginx.GetPerformanceData() c.JSON(http.StatusOK, response) } -// StreamDetailStatus 使用 SSE 流式推送 Nginx 详细状态信息 +// StreamDetailStatus streams Nginx detailed status information using SSE func StreamDetailStatus(c *gin.Context) { - // 设置 SSE 的响应头 + // Set SSE response headers c.Header("Content-Type", "text/event-stream") c.Header("Cache-Control", "no-cache") c.Header("Connection", "keep-alive") c.Header("Access-Control-Allow-Origin", "*") - // 创建上下文,当客户端断开连接时取消 + // Create context that cancels when client disconnects ctx := c.Request.Context() - // 为防止 goroutine 泄漏,创建一个计时器通道 + // Create a ticker channel to prevent goroutine leaks ticker := time.NewTicker(5 * time.Second) defer ticker.Stop() - // 立即发送一次初始数据 + // Send initial data immediately sendPerformanceData(c) - // 使用 goroutine 定期发送数据 + // Use goroutine to send data periodically for { select { case <-ticker.C: - // 发送性能数据 + // Send performance data if err := sendPerformanceData(c); err != nil { logger.Warn("Error sending SSE data:", err) return } case <-ctx.Done(): - // 客户端断开连接或请求被取消 + // Client closed connection or request canceled logger.Debug("Client closed connection") return } } } -// sendPerformanceData 发送一次性能数据 +// sendPerformanceData sends performance data once func sendPerformanceData(c *gin.Context) error { response := nginx.GetPerformanceData() - // 发送 SSE 事件 + // Send SSE event c.SSEvent("message", response) - // 刷新缓冲区,确保数据立即发送 + // Flush buffer to ensure data is sent immediately c.Writer.Flush() return nil } -// CheckStubStatus 获取 Nginx stub_status 模块状态 +// CheckStubStatus gets Nginx stub_status module status func CheckStubStatus(c *gin.Context) { stubStatus := nginx.GetStubStatus() c.JSON(http.StatusOK, stubStatus) } -// ToggleStubStatus 启用或禁用 stub_status 模块 +// ToggleStubStatus enables or disables stub_status module func ToggleStubStatus(c *gin.Context) { var json struct { Enable bool `json:"enable"` @@ -99,7 +99,7 @@ func ToggleStubStatus(c *gin.Context) { stubStatus := nginx.GetStubStatus() - // 如果当前状态与期望状态相同,则无需操作 + // If current status matches desired status, no action needed if stubStatus.Enabled == json.Enable { c.JSON(http.StatusOK, stubStatus) return @@ -117,7 +117,7 @@ func ToggleStubStatus(c *gin.Context) { return } - // 重新加载 Nginx 配置 + // Reload Nginx configuration reloadOutput := nginx.Reload() if len(reloadOutput) > 0 && (strings.Contains(strings.ToLower(reloadOutput), "error") || strings.Contains(strings.ToLower(reloadOutput), "failed")) { @@ -125,7 +125,7 @@ func ToggleStubStatus(c *gin.Context) { return } - // 检查操作后的状态 + // Check status after operation newStubStatus := nginx.GetStubStatus() c.JSON(http.StatusOK, newStubStatus) diff --git a/api/settings/settings.go b/api/settings/settings.go index 8c34da47..a50fe36c 100644 --- a/api/settings/settings.go +++ b/api/settings/settings.go @@ -71,6 +71,7 @@ func SaveSettings(c *gin.Context) { Node settings.Node `json:"node"` Openai settings.OpenAI `json:"openai"` Logrotate settings.Logrotate `json:"logrotate"` + Nginx settings.Nginx `json:"nginx"` } if !cosy.BindAndValid(c, &json) { @@ -104,6 +105,7 @@ func SaveSettings(c *gin.Context) { cSettings.ProtectedFill(settings.NodeSettings, &json.Node) cSettings.ProtectedFill(settings.OpenAISettings, &json.Openai) cSettings.ProtectedFill(settings.LogrotateSettings, &json.Logrotate) + cSettings.ProtectedFill(settings.NginxSettings, &json.Nginx) err := settings.Save() if err != nil { diff --git a/app/src/api/settings.ts b/app/src/api/settings.ts index 6ad23ad0..9d9dbdd8 100644 --- a/app/src/api/settings.ts +++ b/app/src/api/settings.ts @@ -63,6 +63,7 @@ export interface NginxSettings { test_config_cmd: string reload_cmd: string restart_cmd: string + stub_status_port: number } export interface NodeSettings { diff --git a/app/src/views/preference/NginxSettings.vue b/app/src/views/preference/NginxSettings.vue index 273a9a73..38e5a5b5 100644 --- a/app/src/views/preference/NginxSettings.vue +++ b/app/src/views/preference/NginxSettings.vue @@ -6,6 +6,9 @@ const data: Ref = inject('data') as Ref