feat: add readiness and liveness probes for self healing (#734)

Jay Madden created

* feat: add k8s readiness and liveness probes

* fix: switch to single err var and add logging

* chore: remove fmt import

Change summary

pkg/web/health.go | 34 ++++++++++++++++++++++++++++++++++
pkg/web/server.go |  3 +++
2 files changed, 37 insertions(+)

Detailed changes

pkg/web/health.go 🔗

@@ -0,0 +1,34 @@
+package web
+
+import (
+	"context"
+	"net/http"
+
+	"github.com/charmbracelet/log/v2"
+	"github.com/charmbracelet/soft-serve/pkg/db"
+	"github.com/gorilla/mux"
+)
+
+// HealthController registers the health check routes for the web server.
+func HealthController(_ context.Context, r *mux.Router) {
+	r.HandleFunc("/livez", getLiveness)
+	r.HandleFunc("/readyz", getReadiness)
+}
+
+func getLiveness(w http.ResponseWriter, _ *http.Request) {
+	renderStatus(http.StatusOK)(w, nil)
+}
+
+func getReadiness(w http.ResponseWriter, r *http.Request) {
+	ctx := r.Context()
+	logger := log.FromContext(ctx)
+	db := db.FromContext(ctx)
+
+	if err := db.PingContext(ctx); err != nil {
+		logger.Error("error getting db readiness", "err", err)
+		renderStatus(http.StatusServiceUnavailable)(w, nil)
+		return
+	}
+
+	renderStatus(http.StatusOK)(w, nil)
+}

pkg/web/server.go 🔗

@@ -14,6 +14,9 @@ func NewRouter(ctx context.Context) http.Handler {
 	logger := log.FromContext(ctx).WithPrefix("http")
 	router := mux.NewRouter()
 
+	// Health routes
+	HealthController(ctx, router)
+
 	// Git routes
 	GitController(ctx, router)