fix: 初验针对修改
This commit is contained in:
115
internal/health/readiness.go
Normal file
115
internal/health/readiness.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package health
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/ops/logs/internal/config"
|
||||
"git.apinb.com/ops/logs/internal/impl"
|
||||
"git.apinb.com/ops/logs/internal/ingest"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CheckResult struct {
|
||||
Name string `json:"name"`
|
||||
Required bool `json:"required"`
|
||||
Ready bool `json:"ready"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type Readiness struct {
|
||||
Ready bool `json:"ready"`
|
||||
CheckedAt time.Time `json:"checked_at"`
|
||||
Checks []CheckResult `json:"checks,omitempty"`
|
||||
Workers []ingest.WorkerStatus `json:"workers,omitempty"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func Evaluate(ctx context.Context) Readiness {
|
||||
result := Readiness{Ready: true, CheckedAt: time.Now().UTC(), Workers: ingest.WorkerStatuses(), Version: runtimeVersion()}
|
||||
result.add("config", true, config.Validate())
|
||||
result.add("database", true, pingDatabase(ctx, impl.DBService))
|
||||
workerMap := make(map[string]ingest.WorkerStatus, len(result.Workers))
|
||||
for _, worker := range result.Workers {
|
||||
workerMap[worker.Name] = worker
|
||||
}
|
||||
for _, name := range requiredWorkers() {
|
||||
worker, exists := workerMap[name]
|
||||
if !exists || !worker.Running {
|
||||
message := "worker 未启动"
|
||||
if exists && worker.LastError != "" {
|
||||
message = worker.LastError
|
||||
}
|
||||
result.add(name, true, fmt.Errorf("%s", message))
|
||||
continue
|
||||
}
|
||||
result.add(name, true, nil)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func runtimeVersion() string {
|
||||
info, ok := debug.ReadBuildInfo()
|
||||
if !ok || strings.TrimSpace(info.Main.Version) == "" {
|
||||
return "unknown"
|
||||
}
|
||||
return info.Main.Version
|
||||
}
|
||||
|
||||
func Ready(c *gin.Context) {
|
||||
result := Evaluate(c.Request.Context())
|
||||
status := http.StatusOK
|
||||
if !result.Ready {
|
||||
status = http.StatusServiceUnavailable
|
||||
}
|
||||
c.JSON(status, gin.H{"ready": result.Ready})
|
||||
}
|
||||
|
||||
func Status(c *gin.Context) {
|
||||
result := Evaluate(c.Request.Context())
|
||||
status := http.StatusOK
|
||||
if !result.Ready {
|
||||
status = http.StatusServiceUnavailable
|
||||
}
|
||||
c.JSON(status, result)
|
||||
}
|
||||
|
||||
func requiredWorkers() []string {
|
||||
workers := []string{"rule_refresher", "alert_dispatcher"}
|
||||
if strings.TrimSpace(config.Spec.Ingest.SyslogListenAddr) != "" {
|
||||
workers = append(workers, "syslog_udp")
|
||||
}
|
||||
if strings.TrimSpace(config.Spec.Ingest.TrapListenAddr) != "" {
|
||||
workers = append(workers, "trap_udp")
|
||||
}
|
||||
return workers
|
||||
}
|
||||
|
||||
func (r *Readiness) add(name string, required bool, err error) {
|
||||
check := CheckResult{Name: name, Required: required, Ready: err == nil}
|
||||
if err != nil {
|
||||
check.Message = strings.TrimSpace(err.Error())
|
||||
if required {
|
||||
r.Ready = false
|
||||
}
|
||||
}
|
||||
r.Checks = append(r.Checks, check)
|
||||
}
|
||||
|
||||
func pingDatabase(ctx context.Context, db *gorm.DB) error {
|
||||
if db == nil {
|
||||
return fmt.Errorf("数据库未初始化")
|
||||
}
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
checkCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
||||
defer cancel()
|
||||
return sqlDB.PingContext(checkCtx)
|
||||
}
|
||||
Reference in New Issue
Block a user