Files
skybridge/internal/handlers/health.go
2025-08-22 14:06:20 -04:00

73 lines
1.8 KiB
Go

package handlers
import (
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"github.com/kms/api-key-service/internal/repository"
)
// HealthHandler handles health check endpoints
type HealthHandler struct {
db repository.DatabaseProvider
logger *zap.Logger
}
// NewHealthHandler creates a new health handler
func NewHealthHandler(db repository.DatabaseProvider, logger *zap.Logger) *HealthHandler {
return &HealthHandler{
db: db,
logger: logger,
}
}
// HealthResponse represents the health check response
type HealthResponse struct {
Status string `json:"status"`
Timestamp string `json:"timestamp"`
Version string `json:"version,omitempty"`
Checks map[string]string `json:"checks,omitempty"`
}
// Health handles basic health check - lightweight endpoint for load balancers
func (h *HealthHandler) Health(c *gin.Context) {
response := HealthResponse{
Status: "healthy",
Timestamp: time.Now().UTC().Format(time.RFC3339),
}
c.JSON(http.StatusOK, response)
}
// Ready handles readiness check - checks if service is ready to accept traffic
func (h *HealthHandler) Ready(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second)
defer cancel()
checks := make(map[string]string)
status := "ready"
statusCode := http.StatusOK
// Check database connectivity
if err := h.db.Ping(ctx); err != nil {
h.logger.Error("Database health check failed", zap.Error(err))
checks["database"] = "unhealthy: " + err.Error()
status = "not ready"
statusCode = http.StatusServiceUnavailable
} else {
checks["database"] = "healthy"
}
response := HealthResponse{
Status: status,
Timestamp: time.Now().UTC().Format(time.RFC3339),
Checks: checks,
}
c.JSON(statusCode, response)
}