[功能] 添加节点健康事件清理功能,优化节点观测数据管理

This commit is contained in:
ryan
2026-03-18 23:11:48 +08:00
parent 4945b8b44f
commit 782304012c
16 changed files with 3473 additions and 433 deletions
@@ -42,6 +42,11 @@ type NodeObservabilityTrends struct {
DiskIO24h []DiskIOTrendPoint `json:"disk_io_24h"`
}
type NodeHealthEventCleanupResult struct {
NodeID string `json:"node_id"`
DeletedCount int64 `json:"deleted_count"`
}
func GetNodeObservability(id uint, query NodeObservabilityQuery) (*NodeObservabilityView, error) {
now := time.Now()
node, err := model.GetNodeByID(id)
@@ -105,6 +110,21 @@ func GetNodeObservability(id uint, query NodeObservabilityQuery) (*NodeObservabi
}, nil
}
func CleanupNodeHealthEvents(id uint) (*NodeHealthEventCleanupResult, error) {
node, err := model.GetNodeByID(id)
if err != nil {
return nil, err
}
deletedCount, err := model.DeleteNodeHealthEvents(node.NodeID)
if err != nil {
return nil, err
}
return &NodeHealthEventCleanupResult{
NodeID: node.NodeID,
DeletedCount: deletedCount,
}, nil
}
func latestMetricSnapshot(snapshots []*model.NodeMetricSnapshot) *model.NodeMetricSnapshot {
for _, snapshot := range snapshots {
if snapshot != nil {
@@ -1201,6 +1201,66 @@ func TestGetNodeObservabilityAllowsMissingProfile(t *testing.T) {
}
}
func TestCleanupNodeHealthEvents(t *testing.T) {
setupServiceTestDB(t)
node := &model.Node{
NodeID: "node-health-cleanup",
Name: "health-cleanup-edge",
IP: "10.0.0.72",
AgentToken: "token-health-cleanup",
AgentVersion: "v0.6.0",
NginxVersion: "1.27.1.2",
Status: NodeStatusOnline,
}
if err := node.Insert(); err != nil {
t.Fatalf("failed to insert node: %v", err)
}
resolvedAt := time.Now().Add(-4 * time.Minute)
if err := model.DB.Create(&model.NodeHealthEvent{
NodeID: node.NodeID,
EventType: "sync_error",
Severity: NodeHealthSeverityWarning,
Status: NodeHealthEventStatusActive,
Message: "checksum mismatch",
FirstTriggeredAt: time.Now().Add(-2 * time.Minute),
LastTriggeredAt: time.Now().Add(-time.Minute),
ReportedAt: time.Now().Add(-time.Minute),
}).Error; err != nil {
t.Fatalf("failed to insert first node health event: %v", err)
}
if err := model.DB.Create(&model.NodeHealthEvent{
NodeID: node.NodeID,
EventType: "openresty_down",
Severity: NodeHealthSeverityCritical,
Status: NodeHealthEventStatusResolved,
Message: "openresty exited unexpectedly",
FirstTriggeredAt: time.Now().Add(-10 * time.Minute),
LastTriggeredAt: time.Now().Add(-5 * time.Minute),
ReportedAt: time.Now().Add(-5 * time.Minute),
ResolvedAt: &resolvedAt,
}).Error; err != nil {
t.Fatalf("failed to insert second node health event: %v", err)
}
result, err := CleanupNodeHealthEvents(node.ID)
if err != nil {
t.Fatalf("CleanupNodeHealthEvents failed: %v", err)
}
if result.NodeID != node.NodeID || result.DeletedCount != 2 {
t.Fatalf("unexpected cleanup result: %+v", result)
}
events, err := model.ListNodeHealthEvents(node.NodeID, false, 10)
if err != nil {
t.Fatalf("failed to list node health events after cleanup: %v", err)
}
if len(events) != 0 {
t.Fatalf("expected node health events to be removed, got %+v", events)
}
}
func TestGetDashboardOverview(t *testing.T) {
setupServiceTestDB(t)