package health import ( "encoding/json" "net/http" "time" ) // Response represents a health check response type Response struct { Status string `json:"status"` Timestamp time.Time `json:"timestamp"` Version string `json:"version,omitempty"` Checks []Check `json:"checks,omitempty"` } // Check represents an individual health check type Check struct { Name string `json:"name"` Status string `json:"status"` Error string `json:"error,omitempty"` } // Handler handles health check requests type Handler struct { version string checks []HealthChecker } // HealthChecker interface for health checks type HealthChecker interface { Name() string Check() error } // NewHandler creates a new health check handler func NewHandler(version string) *Handler { return &Handler{ version: version, checks: make([]HealthChecker, 0), } } // AddCheck adds a health checker func (h *Handler) AddCheck(checker HealthChecker) { h.checks = append(h.checks, checker) } // ServeHTTP implements http.Handler func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { w.WriteHeader(http.StatusMethodNotAllowed) return } response := Response{ Status: "ok", Timestamp: time.Now().UTC(), Version: h.version, Checks: make([]Check, 0, len(h.checks)), } allHealthy := true for _, checker := range h.checks { check := Check{ Name: checker.Name(), Status: "ok", } if err := checker.Check(); err != nil { check.Status = "error" check.Error = err.Error() allHealthy = false } response.Checks = append(response.Checks, check) } if !allHealthy { response.Status = "error" w.WriteHeader(http.StatusServiceUnavailable) } else { w.WriteHeader(http.StatusOK) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } // SimpleChecker is a basic health checker type SimpleChecker struct { name string fn func() error } // NewSimpleChecker creates a new simple health checker func NewSimpleChecker(name string, fn func() error) *SimpleChecker { return &SimpleChecker{ name: name, fn: fn, } } // Name returns the checker name func (c *SimpleChecker) Name() string { return c.name } // Check performs the health check func (c *SimpleChecker) Check() error { return c.fn() }