network/pkg/rqlite/metrics.go
anonpenguin23 ea5ef6bc1a feat: implement dynamic cluster discovery and validation for RQLite nodes
- Added ClusterDiscoveryService to manage peer discovery and synchronization for RQLite nodes.
- Introduced new configuration options for cluster synchronization intervals, peer inactivity limits, and minimum cluster size.
- Enhanced validation logic to ensure proper configuration of cluster parameters.
- Implemented metrics collection for cluster health and peer status, improving monitoring capabilities.
- Updated RQLiteManager to integrate with the new discovery service, allowing for dynamic leadership and cluster joining logic.
2025-10-31 10:46:52 +02:00

75 lines
1.8 KiB
Go

package rqlite
import (
"time"
)
// GetMetrics returns current cluster metrics
func (c *ClusterDiscoveryService) GetMetrics() *ClusterMetrics {
c.mu.RLock()
defer c.mu.RUnlock()
activeCount := 0
inactiveCount := 0
totalHealth := 0.0
currentLeader := ""
now := time.Now()
for nodeID, health := range c.peerHealth {
if health.Status == "active" {
activeCount++
// Calculate health score (0-100) based on last seen
timeSinceLastSeen := now.Sub(health.LastSeen)
healthScore := 100.0
if timeSinceLastSeen > time.Minute {
// Degrade health score based on time since last seen
healthScore = 100.0 - (float64(timeSinceLastSeen.Seconds()) / float64(c.inactivityLimit.Seconds()) * 100.0)
if healthScore < 0 {
healthScore = 0
}
}
totalHealth += healthScore
} else {
inactiveCount++
}
// Try to determine leader
if peer, ok := c.knownPeers[nodeID]; ok {
// We'd need to check the actual leader status from RQLite
// For now, bootstrap nodes are more likely to be leader
if peer.NodeType == "bootstrap" && currentLeader == "" {
currentLeader = nodeID
}
}
}
averageHealth := 0.0
if activeCount > 0 {
averageHealth = totalHealth / float64(activeCount)
}
// Determine discovery status
discoveryStatus := "healthy"
if len(c.knownPeers) == 0 {
discoveryStatus = "no_peers"
} else if len(c.knownPeers) == 1 {
discoveryStatus = "single_node"
} else if averageHealth < 50 {
discoveryStatus = "degraded"
}
return &ClusterMetrics{
ClusterSize: len(c.knownPeers),
ActiveNodes: activeCount,
InactiveNodes: inactiveCount,
RemovedNodes: 0, // Could track this with a counter
LastUpdate: c.lastUpdate,
DiscoveryStatus: discoveryStatus,
CurrentLeader: currentLeader,
AveragePeerHealth: averageHealth,
}
}