fix(platform): verify storage health by reads
This commit is contained in:
@@ -377,20 +377,54 @@ func (s *ProductionStore) OpsHealth(ctx context.Context) (OpsHealth, error) {
|
||||
mysqlStatus = "error"
|
||||
mysqlDetail = err.Error()
|
||||
}
|
||||
snapshotHealth := s.mysqlTableReadHealth(ctx, "vehicle_realtime_snapshot", "读取实时快照表正常")
|
||||
locationHealth := s.mysqlTableReadHealth(ctx, "vehicle_realtime_location", "读取实时位置表正常")
|
||||
tdengineHealth := s.tdengineRawFrameHealth(ctx)
|
||||
mysqlWritable := mysqlStatus == "ok" && snapshotHealth.Status == "ok" && locationHealth.Status == "ok"
|
||||
return OpsHealth{
|
||||
LinkHealth: []LinkHealth{
|
||||
{Name: "MySQL realtime", Status: mysqlStatus, Detail: mysqlDetail},
|
||||
{Name: "vehicle_realtime_snapshot", Status: "ok", Detail: "读取实时快照表"},
|
||||
{Name: "vehicle_realtime_location", Status: "ok", Detail: "读取实时位置表"},
|
||||
{Name: "TDengine raw_frames", Status: tdengineStatus(s.tdengine), Detail: tdengineDetail(s.tdengine)},
|
||||
snapshotHealth,
|
||||
locationHealth,
|
||||
tdengineHealth,
|
||||
{Name: "Kafka lag", Status: "warning", Detail: "平台暂未接入 Kafka consumer lag 监控"},
|
||||
{Name: "Redis online keys", Status: "warning", Detail: "平台暂未接入 Redis 在线 key 读取"},
|
||||
},
|
||||
TDengineWritable: s.tdengine != nil,
|
||||
MySQLWritable: mysqlStatus == "ok",
|
||||
TDengineWritable: tdengineHealth.Status == "ok",
|
||||
MySQLWritable: mysqlWritable,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *ProductionStore) mysqlTableReadHealth(ctx context.Context, table string, okDetail string) LinkHealth {
|
||||
health := LinkHealth{Name: table, Status: "ok", Detail: okDetail}
|
||||
query := "SELECT 1 FROM " + table + " LIMIT 1"
|
||||
rows, err := s.db.QueryContext(ctx, query)
|
||||
if err != nil {
|
||||
health.Status = "error"
|
||||
health.Detail = err.Error()
|
||||
return health
|
||||
}
|
||||
_ = rows.Close()
|
||||
return health
|
||||
}
|
||||
|
||||
func (s *ProductionStore) tdengineRawFrameHealth(ctx context.Context) LinkHealth {
|
||||
health := LinkHealth{Name: "TDengine raw_frames", Status: "ok", Detail: "读取 TDengine raw_frames 正常"}
|
||||
if s.tdengine == nil {
|
||||
health.Status = "warning"
|
||||
health.Detail = "TDengine 未配置或连接失败,历史查询降级"
|
||||
return health
|
||||
}
|
||||
rows, err := s.tdengine.QueryContext(ctx, "SELECT ts FROM "+qualifyTDengine(s.tdDatabase, "raw_frames")+" LIMIT 1")
|
||||
if err != nil {
|
||||
health.Status = "error"
|
||||
health.Detail = err.Error()
|
||||
return health
|
||||
}
|
||||
_ = rows.Close()
|
||||
return health
|
||||
}
|
||||
|
||||
func (s *ProductionStore) protocolStats(ctx context.Context) ([]ProtocolStat, error) {
|
||||
rows, err := s.db.QueryContext(ctx, `SELECT protocol, SUM(CASE WHEN updated_at >= DATE_SUB(NOW(), INTERVAL 1 MINUTE) THEN 1 ELSE 0 END) AS online_count, COUNT(*) AS total_count FROM vehicle_realtime_snapshot GROUP BY protocol ORDER BY protocol`)
|
||||
if err != nil {
|
||||
@@ -451,17 +485,3 @@ func firstNonEmpty(values ...string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func tdengineStatus(db *sql.DB) string {
|
||||
if db == nil {
|
||||
return "warning"
|
||||
}
|
||||
return "ok"
|
||||
}
|
||||
|
||||
func tdengineDetail(db *sql.DB) string {
|
||||
if db == nil {
|
||||
return "TDengine 未配置或连接失败,历史查询降级"
|
||||
}
|
||||
return "读取 TDengine raw_frames / vehicle_locations"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user