netmaker/metrics/metrics.go

111 lines
2.9 KiB
Go
Raw Normal View History

2023-01-28 03:51:06 +08:00
package metrics
import (
"fmt"
"sync"
"time"
"github.com/go-ping/ping"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
)
// lock for metrics map
var metricsMapLock = &sync.RWMutex{}
// metrics data map
var metricsPeerMap = make(map[string]map[string]*models.ProxyMetric)
// GetMetricByServer - get metric data of peers by server
func GetMetricByServer(server string) map[string]*models.ProxyMetric {
metricsMapLock.RLock()
defer metricsMapLock.RUnlock()
if _, ok := metricsPeerMap[server]; !ok {
return nil
}
return metricsPeerMap[server]
}
// GetMetric - fetches the metric data for the peer
func GetMetric(server, peerKey string) models.ProxyMetric {
metric := models.ProxyMetric{}
peerMetricMap := GetMetricByServer(server)
metricsMapLock.RLock()
defer metricsMapLock.RUnlock()
if peerMetricMap == nil {
return metric
}
if m, ok := peerMetricMap[peerKey]; ok && m != nil {
metric = *m
}
return metric
}
// UpdateMetric - updates metric data for the peer
func UpdateMetric(server, peerKey string, metric *models.ProxyMetric) {
metricsMapLock.Lock()
defer metricsMapLock.Unlock()
if metricsPeerMap[server] == nil {
metricsPeerMap[server] = make(map[string]*models.ProxyMetric)
}
metricsPeerMap[server][peerKey] = metric
}
// UpdateMetricByPeer - updates metrics data by peer public key
func UpdateMetricByPeer(peerKey string, metric *models.ProxyMetric, onlyTraffic bool) {
metricsMapLock.Lock()
defer metricsMapLock.Unlock()
for server, peerKeyMap := range metricsPeerMap {
if peerMetric, ok := peerKeyMap[peerKey]; ok {
peerMetric.TrafficRecieved += metric.TrafficRecieved
peerMetric.TrafficSent += metric.TrafficSent
if !onlyTraffic {
peerMetric.LastRecordedLatency = metric.LastRecordedLatency
}
metricsPeerMap[server][peerKey] = peerMetric
}
}
}
// ResetMetricsForPeer - reset metrics for peer
func ResetMetricsForPeer(server, peerKey string) {
metricsMapLock.Lock()
defer metricsMapLock.Unlock()
delete(metricsPeerMap[server], peerKey)
}
// ResetMetricForNode - resets node level metrics
func ResetMetricForNode(server, peerKey, peerID string) {
metric := GetMetric(server, peerKey)
delete(metric.NodeConnectionStatus, peerID)
UpdateMetric(server, peerKey, &metric)
}
const MetricCollectionInterval = time.Second * 25
// PeerConnectionStatus - get peer connection status by pinging
func PeerConnectionStatus(address string) (connected bool) {
fmt.Println("PINGER ADDR: ", address)
pinger, err := ping.NewPinger(address)
if err != nil {
logger.Log(0, "could not initiliaze ping peer address", address, err.Error())
connected = false
} else {
pinger.Timeout = time.Second * 2
err = pinger.Run()
if err != nil {
logger.Log(0, "failed to ping on peer address", address, err.Error())
return false
} else {
pingStats := pinger.Statistics()
if pingStats.PacketsRecv > 0 {
connected = true
return
}
}
}
return
}