package monitoring import ( "net/http" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // HealthStatus 健康状态 type HealthStatus string const ( HealthStatusUP HealthStatus = "UP" HealthStatusDOWN HealthStatus = "DOWN" HealthStatusUNKNOWN HealthStatus = "UNKNOWN" ) // HealthCheck 健康检查器 type HealthCheck struct { db *gorm.DB } // NewHealthCheck 创建健康检查器 func NewHealthCheck(db *gorm.DB) *HealthCheck { return &HealthCheck{db: db} } // Status 健康状态 type Status struct { Status HealthStatus `json:"status"` Checks map[string]CheckResult `json:"checks"` } // CheckResult 检查结果 type CheckResult struct { Status HealthStatus `json:"status"` Error string `json:"error,omitempty"` } // Check 执行健康检查 func (h *HealthCheck) Check() *Status { status := &Status{ Status: HealthStatusUP, Checks: make(map[string]CheckResult), } // 检查数据库 dbResult := h.checkDatabase() status.Checks["database"] = dbResult if dbResult.Status != HealthStatusUP { status.Status = HealthStatusDOWN } return status } // checkDatabase 检查数据库 func (h *HealthCheck) checkDatabase() CheckResult { if h == nil || h.db == nil { return CheckResult{ Status: HealthStatusDOWN, Error: "database not configured", } } sqlDB, err := h.db.DB() if err != nil { return CheckResult{ Status: HealthStatusDOWN, Error: err.Error(), } } // Ping数据库 if err := sqlDB.Ping(); err != nil { return CheckResult{ Status: HealthStatusDOWN, Error: err.Error(), } } return CheckResult{Status: HealthStatusUP} } // ReadinessHandler reports dependency readiness. func (h *HealthCheck) ReadinessHandler(c *gin.Context) { status := h.Check() httpStatus := http.StatusOK if status.Status != HealthStatusUP { httpStatus = http.StatusServiceUnavailable } c.JSON(httpStatus, status) } // LivenessHandler reports process liveness without dependency checks. func (h *HealthCheck) LivenessHandler(c *gin.Context) { c.Status(http.StatusNoContent) c.Writer.WriteHeaderNow() } // Handler keeps backward compatibility with the historical /health endpoint. func (h *HealthCheck) Handler(c *gin.Context) { h.ReadinessHandler(c) }