Files
NBA_Go/controllers/health_controller.go
T
2026-09-04 12:01:20 -05:00

121 lines
2.9 KiB
Go

package controllers
import (
"context"
"fmt"
"os"
"time"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
"gorm.io/plugin/dbresolver"
)
type TargetHealth struct {
Status string `json:"status"`
Target string `json:"target"`
LatencyMs float64 `json:"latencyMs"`
Error string `json:"error,omitempty"`
}
type ReadinessResponse struct {
Status string `json:"status"`
Timestamp time.Time `json:"timestamp"`
Targets map[string]TargetHealth `json:"targets"`
}
// RegisterHealthRoutes mounts /healthz and /readyz probes
func RegisterHealthRoutes(app *fiber.App, db *gorm.DB) {
app.Get("/healthz", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"status": "UP",
"timestamp": time.Now().UTC(),
})
})
app.Get("/readyz", func(c *fiber.Ctx) error {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
targets := make(map[string]TargetHealth)
overallHealthy := true
writeHost := os.Getenv("DB_WRITE_HOST")
if writeHost == "" {
writeHost = "178.105.149.129"
}
writePort := os.Getenv("DB_WRITE_PORT")
if writePort == "" {
writePort = "5437"
}
readHost := os.Getenv("DB_READ_HOST")
if readHost == "" {
readHost = "178.105.149.129"
}
readPort := os.Getenv("DB_READ_PORT")
if readPort == "" {
readPort = "5438"
}
// Check Write Ingress (:5437)
writeTarget := fmt.Sprintf("%s:%s", writeHost, writePort)
writeStart := time.Now()
writeDB, err := db.Clauses(dbresolver.Write).DB()
if err != nil || writeDB == nil || writeDB.PingContext(ctx) != nil {
overallHealthy = false
errMsg := "Write ingress unreachable"
if err != nil {
errMsg = err.Error()
}
targets["db_write"] = TargetHealth{
Status: "DOWN",
Target: writeTarget,
Error: errMsg,
}
} else {
targets["db_write"] = TargetHealth{
Status: "UP",
Target: writeTarget,
LatencyMs: float64(time.Since(writeStart).Microseconds()) / 1000.0,
}
}
// Check Read Ingress (:5438)
readTarget := fmt.Sprintf("%s:%s", readHost, readPort)
readStart := time.Now()
readDB, err := db.Clauses(dbresolver.Read).DB()
if err != nil || readDB == nil || readDB.PingContext(ctx) != nil {
overallHealthy = false
errMsg := "Read ingress unreachable"
if err != nil {
errMsg = err.Error()
}
targets["db_read"] = TargetHealth{
Status: "DOWN",
Target: readTarget,
Error: errMsg,
}
} else {
targets["db_read"] = TargetHealth{
Status: "UP",
Target: readTarget,
LatencyMs: float64(time.Since(readStart).Microseconds()) / 1000.0,
}
}
statusCode := fiber.StatusOK
statusText := "UP"
if !overallHealthy {
statusCode = fiber.StatusServiceUnavailable
statusText = "DEGRADED"
}
return c.Status(statusCode).JSON(ReadinessResponse{
Status: statusText,
Timestamp: time.Now().UTC(),
Targets: targets,
})
})
}