Merge pull request #1924 from gravitl/feature_host_metrics

Feature host metrics
This commit is contained in:
dcarns 2023-01-12 12:59:58 -05:00 committed by GitHub
commit 41cd6a6ff3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 60 deletions

4
go.mod
View file

@ -29,7 +29,7 @@ require (
require ( require (
filippo.io/edwards25519 v1.0.0 filippo.io/edwards25519 v1.0.0
github.com/c-robinson/iplib v1.0.6 github.com/c-robinson/iplib v1.0.6
github.com/go-ping/ping v1.1.0 github.com/go-ping/ping v1.1.0 // indirect
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0 github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0
) )
@ -43,7 +43,7 @@ require (
) )
require ( require (
github.com/gravitl/netclient v0.0.0-20230110162232-fcba83b2f589 github.com/gravitl/netclient v0.0.0-20230112093844-8ad3677b614d
github.com/guumaster/tablewriter v0.0.10 github.com/guumaster/tablewriter v0.0.10
github.com/matryer/is v1.4.0 github.com/matryer/is v1.4.0
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v0.0.5

View file

@ -3,9 +3,7 @@ package metrics
import ( import (
"time" "time"
"github.com/go-ping/ping"
proxy_metrics "github.com/gravitl/netclient/nmproxy/metrics" proxy_metrics "github.com/gravitl/netclient/nmproxy/metrics"
proxy_models "github.com/gravitl/netclient/nmproxy/models"
"github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
@ -13,7 +11,7 @@ import (
) )
// Collect - collects metrics // Collect - collects metrics
func Collect(iface, network string, proxy bool, peerMap models.PeerMap) (*models.Metrics, error) { func Collect(iface, server, network string, peerMap models.PeerMap) (*models.Metrics, error) {
var metrics models.Metrics var metrics models.Metrics
metrics.Connectivity = make(map[string]models.Metric) metrics.Connectivity = make(map[string]models.Metric)
var wgclient, err = wgctrl.New() var wgclient, err = wgctrl.New()
@ -27,49 +25,30 @@ func Collect(iface, network string, proxy bool, peerMap models.PeerMap) (*models
fillUnconnectedData(&metrics, peerMap) fillUnconnectedData(&metrics, peerMap)
return &metrics, err return &metrics, err
} }
metrics.ProxyMetrics = make(map[string]proxy_models.Metric)
// TODO handle freebsd?? // TODO handle freebsd??
for i := range device.Peers { for i := range device.Peers {
currPeer := device.Peers[i] currPeer := device.Peers[i]
if _, ok := peerMap[currPeer.PublicKey.String()]; !ok {
continue
}
id := peerMap[currPeer.PublicKey.String()].ID id := peerMap[currPeer.PublicKey.String()].ID
address := peerMap[currPeer.PublicKey.String()].Address address := peerMap[currPeer.PublicKey.String()].Address
if id == "" || address == "" { if id == "" || address == "" {
logger.Log(0, "attempted to parse metrics for invalid peer from server", id, address) logger.Log(0, "attempted to parse metrics for invalid peer from server", id, address)
continue continue
} }
proxyMetrics := proxy_metrics.GetMetric(server, currPeer.PublicKey.String())
var newMetric = models.Metric{ var newMetric = models.Metric{
NodeName: peerMap[currPeer.PublicKey.String()].Name, NodeName: peerMap[currPeer.PublicKey.String()].Name,
IsServer: peerMap[currPeer.PublicKey.String()].IsServer,
} }
logger.Log(2, "collecting metrics for peer", address) logger.Log(2, "collecting metrics for peer", address)
newMetric.TotalReceived = currPeer.ReceiveBytes newMetric.TotalReceived = int64(proxyMetrics.TrafficRecieved)
newMetric.TotalSent = currPeer.TransmitBytes newMetric.TotalSent = int64(proxyMetrics.TrafficSent)
newMetric.Latency = int64(proxyMetrics.LastRecordedLatency)
// get latency newMetric.Connected = proxyMetrics.NodeConnectionStatus[id]
pinger, err := ping.NewPinger(address) if newMetric.Connected {
if err != nil { newMetric.Uptime = 1
logger.Log(0, "could not initiliaze ping for metrics on peer address", address, err.Error())
newMetric.Connected = false
newMetric.Latency = 999
} else {
pinger.Count = 1
pinger.Timeout = time.Second * 2
err = pinger.Run()
if err != nil {
logger.Log(0, "failed ping for metrics on peer address", address, err.Error())
newMetric.Connected = false
newMetric.Latency = 999
} else {
pingStats := pinger.Statistics()
if pingStats.PacketsRecv > 0 {
newMetric.Uptime = 1
newMetric.Connected = true
newMetric.Latency = pingStats.AvgRtt.Milliseconds()
}
}
} }
// check device peer to see if WG is working if ping failed // check device peer to see if WG is working if ping failed
if !newMetric.Connected { if !newMetric.Connected {
if currPeer.ReceiveBytes > 0 && if currPeer.ReceiveBytes > 0 &&
@ -79,11 +58,13 @@ func Collect(iface, network string, proxy bool, peerMap models.PeerMap) (*models
newMetric.Uptime = 1 newMetric.Uptime = 1
} }
} }
newMetric.TotalTime = 1 newMetric.TotalTime = 1
metrics.Connectivity[id] = newMetric metrics.Connectivity[id] = newMetric
metrics.ProxyMetrics[id] = proxy_metrics.GetMetric(network, currPeer.PublicKey.String()) if len(proxyMetrics.NodeConnectionStatus) == 1 {
proxy_metrics.ResetMetricsForPeer(network, currPeer.PublicKey.String()) proxy_metrics.ResetMetricsForPeer(server, currPeer.PublicKey.String())
} else {
proxy_metrics.ResetMetricForNode(server, currPeer.PublicKey.String(), id)
}
} }
fillUnconnectedData(&metrics, peerMap) fillUnconnectedData(&metrics, peerMap)
@ -133,7 +114,6 @@ func fillUnconnectedData(metrics *models.Metrics, peerMap models.PeerMap) {
if !metrics.Connectivity[id].Connected { if !metrics.Connectivity[id].Connected {
newMetric := models.Metric{ newMetric := models.Metric{
NodeName: peerMap[r].Name, NodeName: peerMap[r].Name,
IsServer: peerMap[r].IsServer,
Uptime: 0, Uptime: 0,
TotalTime: 1, TotalTime: 1,
Connected: false, Connected: false,

View file

@ -399,7 +399,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
IP: peerHost.EndpointIP, IP: peerHost.EndpointIP,
Port: peerHost.ListenPort, Port: peerHost.ListenPort,
} }
if !host.ProxyEnabled && peerHost.ProxyEnabled { if peerHost.ProxyEnabled {
if peerHost.ProxyListenPort == 0 { if peerHost.ProxyListenPort == 0 {
peerConfig.Endpoint.Port = proxy_models.NmProxyPort peerConfig.Endpoint.Port = proxy_models.NmProxyPort
} else { } else {
@ -462,6 +462,7 @@ func GetPeerUpdate(node *models.Node, host *models.Host) (models.PeerUpdate, err
Network: node.Network, Network: node.Network,
ServerVersion: ncutils.Version, ServerVersion: ncutils.Version,
DNS: getPeerDNS(node.Network), DNS: getPeerDNS(node.Network),
PeerIDs: make(models.PeerMap),
} }
currentPeers, err := GetNetworkNodes(node.Network) currentPeers, err := GetNetworkNodes(node.Network)
if err != nil { if err != nil {
@ -511,7 +512,7 @@ func GetPeerUpdate(node *models.Node, host *models.Host) (models.PeerUpdate, err
IP: peerHost.EndpointIP, IP: peerHost.EndpointIP,
Port: peerHost.ListenPort, Port: peerHost.ListenPort,
} }
if !host.ProxyEnabled && peerHost.ProxyEnabled { if peerHost.ProxyEnabled {
peerConfig.Endpoint.Port = peerHost.ProxyListenPort peerConfig.Endpoint.Port = peerHost.ProxyListenPort
} }
if uselocal { if uselocal {
@ -526,12 +527,16 @@ func GetPeerUpdate(node *models.Node, host *models.Host) (models.PeerUpdate, err
} }
} }
} }
if peer.IsRelay {
allowedips = append(allowedips, getRelayAllowedIPs(node, &peer)...)
}
if peer.IsEgressGateway { if peer.IsEgressGateway {
allowedips = append(allowedips, getEgressIPs(node, &peer)...) allowedips = append(allowedips, getEgressIPs(node, &peer)...)
} }
peerUpdate.PeerIDs[peerHost.PublicKey.String()] = models.IDandAddr{
ID: peer.ID.String(),
Address: peer.PrimaryAddress(),
Name: peerHost.Name,
Network: peer.Network,
}
peerConfig.AllowedIPs = allowedips peerConfig.AllowedIPs = allowedips
peerUpdate.Peers = append(peerUpdate.Peers, peerConfig) peerUpdate.Peers = append(peerUpdate.Peers, peerConfig)
} }

View file

@ -2,25 +2,20 @@ package models
import ( import (
"time" "time"
proxy_models "github.com/gravitl/netclient/nmproxy/models"
) )
// Metrics - metrics struct // Metrics - metrics struct
type Metrics struct { type Metrics struct {
Network string `json:"network" bson:"network" yaml:"network"` Network string `json:"network" bson:"network" yaml:"network"`
NodeID string `json:"node_id" bson:"node_id" yaml:"node_id"` NodeID string `json:"node_id" bson:"node_id" yaml:"node_id"`
NodeName string `json:"node_name" bson:"node_name" yaml:"node_name"` NodeName string `json:"node_name" bson:"node_name" yaml:"node_name"`
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"` Connectivity map[string]Metric `json:"connectivity" bson:"connectivity" yaml:"connectivity"`
Connectivity map[string]Metric `json:"connectivity" bson:"connectivity" yaml:"connectivity"` FailoverPeers map[string]string `json:"needsfailover" bson:"needsfailover" yaml:"needsfailover"`
FailoverPeers map[string]string `json:"needsfailover" bson:"needsfailover" yaml:"needsfailover"`
ProxyMetrics map[string]proxy_models.Metric `json:"proxy_metrics" bson:"proxy_metrics" yaml:"proxy_metrics"`
} }
// Metric - holds a metric for data between nodes // Metric - holds a metric for data between nodes
type Metric struct { type Metric struct {
NodeName string `json:"node_name" bson:"node_name" yaml:"node_name"` NodeName string `json:"node_name" bson:"node_name" yaml:"node_name"`
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
Uptime int64 `json:"uptime" bson:"uptime" yaml:"uptime"` Uptime int64 `json:"uptime" bson:"uptime" yaml:"uptime"`
TotalTime int64 `json:"totaltime" bson:"totaltime" yaml:"totaltime"` TotalTime int64 `json:"totaltime" bson:"totaltime" yaml:"totaltime"`
Latency int64 `json:"latency" bson:"latency" yaml:"latency"` Latency int64 `json:"latency" bson:"latency" yaml:"latency"`

View file

@ -287,7 +287,6 @@ func updateNodeMetrics(currentNode *models.Node, newMetrics *models.Metrics) boo
} }
} }
extMetric.NodeName = attachedClients[i].ClientID extMetric.NodeName = attachedClients[i].ClientID
extMetric.IsServer = "no"
delete(newMetrics.Connectivity, attachedClients[i].PublicKey) delete(newMetrics.Connectivity, attachedClients[i].PublicKey)
newMetrics.Connectivity[attachedClients[i].ClientID] = extMetric newMetrics.Connectivity[attachedClients[i].ClientID] = extMetric
} }
@ -308,12 +307,6 @@ func updateNodeMetrics(currentNode *models.Node, newMetrics *models.Metrics) boo
currMetric.ActualUptime = time.Duration(totalUpMinutes) * time.Minute currMetric.ActualUptime = time.Duration(totalUpMinutes) * time.Minute
delete(oldMetrics.Connectivity, k) // remove from old data delete(oldMetrics.Connectivity, k) // remove from old data
newMetrics.Connectivity[k] = currMetric newMetrics.Connectivity[k] = currMetric
if oldProxyMetric, ok := oldMetrics.ProxyMetrics[k]; ok {
newProxyMetric := newMetrics.ProxyMetrics[k]
newProxyMetric.TrafficSent += oldProxyMetric.TrafficSent
newProxyMetric.TrafficRecieved += oldProxyMetric.TrafficRecieved
newMetrics.ProxyMetrics[k] = newProxyMetric
}
} }