feat: backend core - auth, user, role, permission, device, webhook, monitoring, cache, repository, service, middleware, API handlers
This commit is contained in:
107
internal/monitoring/health.go
Normal file
107
internal/monitoring/health.go
Normal file
@@ -0,0 +1,107 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user