package health import ( "net" "net/http" "os/exec" "strings" "time" "github.com/labstack/echo/v4" ) type Checker struct { YtdlpPath string ProxyURL string } type HealthResponse struct { Status string `json:"status"` Ytdlp string `json:"ytdlp"` Byedpi string `json:"byedpi"` Uptime string `json:"uptime"` StartTime time.Time `json:"-"` } func NewChecker(ytdlpPath, proxyURL string) *Checker { return &Checker{ YtdlpPath: ytdlpPath, ProxyURL: proxyURL, } } func (c *Checker) Handler(startTime time.Time) echo.HandlerFunc { return func(ctx echo.Context) error { resp := HealthResponse{ Status: "ok", StartTime: startTime, Uptime: time.Since(startTime).Round(time.Second).String(), } // Check yt-dlp if err := exec.Command(c.YtdlpPath, "--version").Run(); err != nil { resp.Status = "degraded" resp.Ytdlp = "unavailable" } else { resp.Ytdlp = "ok" } // Check proxy (ByeByeDPI) — we check if we can resolve the host // A real check would connect via SOCKS5, but for MVP TCP check is enough if strings.Contains(c.ProxyURL, "localhost:1080") || strings.Contains(c.ProxyURL, "byedpi:1080") { // Quick TCP dial check proxyHost := "localhost:1080" if strings.Contains(c.ProxyURL, "byedpi") { proxyHost = "byedpi:1080" } conn, err := net.DialTimeout("tcp", proxyHost, 2*time.Second) if err != nil { resp.Status = "degraded" resp.Byedpi = "unreachable" } else { conn.Close() resp.Byedpi = "ok" } } else { resp.Byedpi = "disabled" } if resp.Status != "ok" { return ctx.JSON(http.StatusServiceUnavailable, resp) } return ctx.JSON(http.StatusOK, resp) } }