78 lines
2.0 KiB
Go
78 lines
2.0 KiB
Go
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
|
|
}
|