mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-11 09:46:37 +08:00
feat(dashboard): enhance risk summary and peak node display in dashboard overview
- Added risk summary metrics including critical alerts, high CPU/memory nodes, and lagging nodes to the dashboard overview. - Introduced peak node metrics for busiest and riskiest nodes with detailed display. - Updated types for dashboard overview to include risk and peak summaries. - Implemented new components for displaying risk signals and peak cards. - Enhanced unit tests to cover new risk and peak metrics in the dashboard overview. fix(update): improve error messages for server upgrade processes - Translated and clarified error messages related to server upgrades and binary uploads. - Ensured consistent error handling and messaging throughout the upgrade process. test(update): refactor test utilities for server upgrade - Renamed roundTripFunc to serverUpdateRoundTripFunc for clarity in test code. - Updated test cases to utilize the new naming convention. feat(node-detail): add traffic structure distribution and health event timeline - Implemented traffic breakdown visualization for status codes and top domains in node detail page. - Added health event timeline to display active and resolved events for better observability. feat(rank-chart): create reusable rank chart component - Developed a new RankChart component for visualizing ranked data distributions. - Integrated RankChart into node detail page for displaying status code and domain distributions.
This commit is contained in:
@@ -15,6 +15,8 @@ type DashboardOverviewView struct {
|
||||
Traffic DashboardTraffic `json:"traffic"`
|
||||
Capacity DashboardCapacity `json:"capacity"`
|
||||
Config DashboardConfig `json:"config"`
|
||||
Risk DashboardRiskSummary `json:"risk"`
|
||||
Peaks DashboardPeakSummary `json:"peaks"`
|
||||
Trends DashboardTrends `json:"trends"`
|
||||
Nodes []DashboardNodeHealth `json:"nodes"`
|
||||
ActiveAlerts []DashboardAlert `json:"active_alerts"`
|
||||
@@ -52,6 +54,42 @@ type DashboardConfig struct {
|
||||
PendingNodes int `json:"pending_nodes"`
|
||||
}
|
||||
|
||||
type DashboardRiskSummary struct {
|
||||
CriticalAlerts int `json:"critical_alerts"`
|
||||
WarningAlerts int `json:"warning_alerts"`
|
||||
InfoAlerts int `json:"info_alerts"`
|
||||
OfflineNodes int `json:"offline_nodes"`
|
||||
UnhealthyNodes int `json:"unhealthy_nodes"`
|
||||
LaggingNodes int `json:"lagging_nodes"`
|
||||
HighCPUNodes int `json:"high_cpu_nodes"`
|
||||
HighMemoryNodes int `json:"high_memory_nodes"`
|
||||
HighStorageNodes int `json:"high_storage_nodes"`
|
||||
}
|
||||
|
||||
type DashboardPeakSummary struct {
|
||||
PeakRequestHour DashboardPeakHour `json:"peak_request_hour"`
|
||||
PeakErrorHour DashboardPeakHour `json:"peak_error_hour"`
|
||||
BusiestNode *DashboardPeakNode `json:"busiest_node"`
|
||||
RiskiestNode *DashboardPeakNode `json:"riskiest_node"`
|
||||
}
|
||||
|
||||
type DashboardPeakHour struct {
|
||||
BucketStartedAt time.Time `json:"bucket_started_at"`
|
||||
RequestCount int64 `json:"request_count"`
|
||||
ErrorCount int64 `json:"error_count"`
|
||||
}
|
||||
|
||||
type DashboardPeakNode struct {
|
||||
NodeID string `json:"node_id"`
|
||||
NodeName string `json:"node_name"`
|
||||
RequestCount int64 `json:"request_count"`
|
||||
ErrorCount int64 `json:"error_count"`
|
||||
CPUUsagePercent float64 `json:"cpu_usage_percent"`
|
||||
ActiveEventCount int `json:"active_event_count"`
|
||||
OpenrestyStatus string `json:"openresty_status"`
|
||||
StorageUsagePercent float64 `json:"storage_usage_percent"`
|
||||
}
|
||||
|
||||
type DashboardTrends struct {
|
||||
Traffic24h []TrafficTrendPoint `json:"traffic_24h"`
|
||||
Capacity24h []CapacityTrendPoint `json:"capacity_24h"`
|
||||
@@ -135,17 +173,21 @@ func GetDashboardOverview() (*DashboardOverviewView, error) {
|
||||
view.Summary.OnlineNodes++
|
||||
case NodeStatusOffline:
|
||||
view.Summary.OfflineNodes++
|
||||
view.Risk.OfflineNodes++
|
||||
case NodeStatusPending:
|
||||
view.Summary.PendingNodes++
|
||||
}
|
||||
if node.OpenrestyStatus == OpenrestyStatusUnhealthy {
|
||||
view.Summary.UnhealthyNodes++
|
||||
view.Risk.UnhealthyNodes++
|
||||
}
|
||||
if activeVersion != "" && node.CurrentVersion != "" && node.CurrentVersion != activeVersion {
|
||||
view.Summary.LaggingNodes++
|
||||
view.Risk.LaggingNodes++
|
||||
}
|
||||
if activeVersion != "" && node.CurrentVersion == "" && computedStatus != NodeStatusPending {
|
||||
view.Summary.LaggingNodes++
|
||||
view.Risk.LaggingNodes++
|
||||
}
|
||||
|
||||
latestSnapshot := latestSnapshots[node.NodeID]
|
||||
@@ -173,6 +215,14 @@ func GetDashboardOverview() (*DashboardOverviewView, error) {
|
||||
LastTriggeredAt: event.LastTriggeredAt,
|
||||
Status: event.Status,
|
||||
})
|
||||
switch event.Severity {
|
||||
case NodeHealthSeverityCritical:
|
||||
view.Risk.CriticalAlerts++
|
||||
case NodeHealthSeverityWarning:
|
||||
view.Risk.WarningAlerts++
|
||||
default:
|
||||
view.Risk.InfoAlerts++
|
||||
}
|
||||
}
|
||||
|
||||
if latestSnapshot != nil {
|
||||
@@ -189,12 +239,15 @@ func GetDashboardOverview() (*DashboardOverviewView, error) {
|
||||
}
|
||||
if latestSnapshot.CPUUsagePercent >= 80 {
|
||||
view.Capacity.HighCPUNodes++
|
||||
view.Risk.HighCPUNodes++
|
||||
}
|
||||
if nodeHealth.MemoryUsagePercent >= 85 {
|
||||
view.Capacity.HighMemoryNodes++
|
||||
view.Risk.HighMemoryNodes++
|
||||
}
|
||||
if nodeHealth.StorageUsagePercent >= 85 {
|
||||
view.Capacity.HighStorageNodes++
|
||||
view.Risk.HighStorageNodes++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +298,15 @@ func GetDashboardOverview() (*DashboardOverviewView, error) {
|
||||
view.ActiveAlerts = view.ActiveAlerts[:8]
|
||||
}
|
||||
|
||||
view.Peaks.PeakRequestHour = peakTrafficHour(view.Trends.Traffic24h, func(point TrafficTrendPoint) int64 {
|
||||
return point.RequestCount
|
||||
})
|
||||
view.Peaks.PeakErrorHour = peakTrafficHour(view.Trends.Traffic24h, func(point TrafficTrendPoint) int64 {
|
||||
return point.ErrorCount
|
||||
})
|
||||
view.Peaks.BusiestNode = busiestDashboardNode(view.Nodes)
|
||||
view.Peaks.RiskiestNode = riskiestDashboardNode(view.Nodes)
|
||||
|
||||
return view, nil
|
||||
}
|
||||
|
||||
@@ -304,3 +366,58 @@ func severityWeight(severity string) int {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func peakTrafficHour(points []TrafficTrendPoint, selector func(point TrafficTrendPoint) int64) DashboardPeakHour {
|
||||
var result DashboardPeakHour
|
||||
var maxValue int64 = -1
|
||||
for _, point := range points {
|
||||
value := selector(point)
|
||||
if value <= maxValue {
|
||||
continue
|
||||
}
|
||||
maxValue = value
|
||||
result = DashboardPeakHour{
|
||||
BucketStartedAt: point.BucketStartedAt,
|
||||
RequestCount: point.RequestCount,
|
||||
ErrorCount: point.ErrorCount,
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func busiestDashboardNode(nodes []DashboardNodeHealth) *DashboardPeakNode {
|
||||
var selected *DashboardPeakNode
|
||||
for _, node := range nodes {
|
||||
candidate := &DashboardPeakNode{
|
||||
NodeID: node.NodeID,
|
||||
NodeName: node.Name,
|
||||
RequestCount: node.RequestCount,
|
||||
ErrorCount: node.ErrorCount,
|
||||
CPUUsagePercent: node.CPUUsagePercent,
|
||||
ActiveEventCount: node.ActiveEventCount,
|
||||
OpenrestyStatus: node.OpenrestyStatus,
|
||||
StorageUsagePercent: node.StorageUsagePercent,
|
||||
}
|
||||
if selected == nil || candidate.RequestCount > selected.RequestCount || (candidate.RequestCount == selected.RequestCount && candidate.ErrorCount > selected.ErrorCount) {
|
||||
selected = candidate
|
||||
}
|
||||
}
|
||||
return selected
|
||||
}
|
||||
|
||||
func riskiestDashboardNode(nodes []DashboardNodeHealth) *DashboardPeakNode {
|
||||
if len(nodes) == 0 {
|
||||
return nil
|
||||
}
|
||||
node := nodes[0]
|
||||
return &DashboardPeakNode{
|
||||
NodeID: node.NodeID,
|
||||
NodeName: node.Name,
|
||||
RequestCount: node.RequestCount,
|
||||
ErrorCount: node.ErrorCount,
|
||||
CPUUsagePercent: node.CPUUsagePercent,
|
||||
ActiveEventCount: node.ActiveEventCount,
|
||||
OpenrestyStatus: node.OpenrestyStatus,
|
||||
StorageUsagePercent: node.StorageUsagePercent,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user