Sync from /srv/compose/unified-media-manager
This commit is contained in:
77
internal/api/health.go
Normal file
77
internal/api/health.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/TopherMayor/unified-media-manager/internal/config"
|
||||
"github.com/TopherMayor/unified-media-manager/internal/db"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func healthLive(c echo.Context) error {
|
||||
return c.JSON(http.StatusOK, map[string]string{"status": "alive"})
|
||||
}
|
||||
|
||||
func healthReady(database *db.DB, cfg *config.Config) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
ctx, cancel := context.WithTimeout(c.Request().Context(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
checks := map[string]string{}
|
||||
allReady := true
|
||||
|
||||
if err := database.Ping(ctx); err != nil {
|
||||
checks["database"] = "unhealthy: " + err.Error()
|
||||
allReady = false
|
||||
slog.Error("readiness check failed", "component", "database", "error", err)
|
||||
} else {
|
||||
checks["database"] = "healthy"
|
||||
}
|
||||
|
||||
if err := checkHTTPService(ctx, cfg.QdrantURL+"/healthz"); err != nil {
|
||||
checks["qdrant"] = "unhealthy: " + err.Error()
|
||||
allReady = false
|
||||
slog.Error("readiness check failed", "component", "qdrant", "error", err)
|
||||
} else {
|
||||
checks["qdrant"] = "healthy"
|
||||
}
|
||||
|
||||
if err := checkHTTPService(ctx, cfg.OllamaURL+"/api/version"); err != nil {
|
||||
checks["ollama"] = "unhealthy: " + err.Error()
|
||||
allReady = false
|
||||
slog.Error("readiness check failed", "component", "ollama", "error", err)
|
||||
} else {
|
||||
checks["ollama"] = "healthy"
|
||||
}
|
||||
|
||||
status := "healthy"
|
||||
code := http.StatusOK
|
||||
if !allReady {
|
||||
status = "degraded"
|
||||
code = http.StatusServiceUnavailable
|
||||
}
|
||||
|
||||
return c.JSON(code, map[string]interface{}{"status": status, "checks": checks})
|
||||
}
|
||||
}
|
||||
|
||||
func checkHTTPService(ctx context.Context, url string) error {
|
||||
client := &http.Client{Timeout: 3 * time.Second}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("build request: %w", err)
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("request failed: %w", err)
|
||||
}
|
||||
resp.Body.Close()
|
||||
if resp.StatusCode >= 500 {
|
||||
return fmt.Errorf("server returned %d", resp.StatusCode)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user