Skip to content
Snippets Groups Projects
Unverified Commit 082f5574 authored by Levente Pap's avatar Levente Pap
Browse files

:chart_with_upwards_trend: Autopeering NeighborCount + Network Diameter metrics

parent 927c861b
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,7 @@ import (
"sync"
"time"
"github.com/iotaledger/goshimmer/packages/graph"
"github.com/iotaledger/goshimmer/packages/shutdown"
"github.com/iotaledger/goshimmer/plugins/analysis/packet"
analysisserver "github.com/iotaledger/goshimmer/plugins/analysis/server"
......@@ -21,9 +22,57 @@ var (
nodes = make(map[string]time.Time)
// maps nodeId to outgoing connections + latest arrival of heartbeat.
links = make(map[string]map[string]time.Time)
lock sync.Mutex
lock sync.RWMutex
)
type NeighborMetric struct {
Inbound uint
Outbound uint
}
// NumOfNeighbors returns a map of nodeId-s to their neighbor count.
func NumOfNeighbors() map[string]*NeighborMetric {
lock.RLock()
defer lock.RUnlock()
result := make(map[string]*NeighborMetric)
for nodeID, _ := range nodes {
// number of outgoing neighbors
if _, exist := result[nodeID]; !exist {
result[nodeID] = &NeighborMetric{Outbound: uint(len(links[nodeID]))}
} else {
result[nodeID].Outbound = uint(len(links[nodeID]))
}
// fill in incoming neighbors
for outNeighborID, _ := range links[nodeID] {
if _, exist := result[outNeighborID]; !exist {
result[outNeighborID] = &NeighborMetric{Inbound: 1}
} else {
result[outNeighborID].Inbound++
}
}
}
return result
}
// NetworkGraph returns a graph.
func NetworkGraph() *graph.Graph {
lock.RLock()
defer lock.RUnlock()
var nodeIDs []string
for id, _ := range nodes {
nodeIDs = append(nodeIDs, id)
}
g := graph.New(nodeIDs)
for src, trgMap := range links {
for dst, _ := range trgMap {
g.AddEdge(src, dst)
}
}
return g
}
// configures the event recording by attaching to the analysis server's events.
func configureEventsRecording() {
analysisserver.Events.Heartbeat.Attach(events.NewClosure(func(hb *packet.Heartbeat) {
......@@ -156,8 +205,8 @@ func cleanUp(interval time.Duration) {
}
func getEventsToReplay() (map[string]time.Time, map[string]map[string]time.Time) {
lock.Lock()
defer lock.Unlock()
lock.RLock()
defer lock.RUnlock()
copiedNodes := make(map[string]time.Time, len(nodes))
for nodeID, lastHeartbeat := range nodes {
......
package metrics
import (
"fmt"
"sync"
analysisdashboard "github.com/iotaledger/goshimmer/plugins/analysis/dashboard"
"github.com/iotaledger/goshimmer/plugins/analysis/packet"
"github.com/iotaledger/hive.go/events"
"github.com/mr-tron/base58/base58"
"go.uber.org/atomic"
)
type ClientInfo struct {
......@@ -19,6 +22,7 @@ type ClientInfo struct {
var (
clientsMetrics = make(map[string]ClientInfo)
clientsMetricsMutex sync.RWMutex
networkDiameter atomic.Int32
)
var onMetricHeartbeatReceived = events.NewClosure(func(hb *packet.MetricHeartbeat) {
......@@ -45,3 +49,15 @@ func ClientsMetrics() map[string]ClientInfo {
}
return copy
}
func calculateNetworkDiameter() {
g := analysisdashboard.NetworkGraph()
diameter := g.Diameter()
networkDiameter.Store(int32(diameter))
fmt.Println("Calculated network diameter: ", diameter)
}
// NetworkDiameter returns the current network diameter.
func NetworkDiameter() int32 {
return networkDiameter.Load()
}
......@@ -66,6 +66,10 @@ func run(_ *node.Plugin) {
gossipCurrentTx.Store(uint64(g.BytesWritten))
}, 1*time.Second, shutdownSignal)
}
if config.Node.GetBool(CfgMetricsGlobal) {
timeutil.Ticker(calculateNetworkDiameter, 1 * time.Minute, shutdownSignal)
}
}, shutdown.PriorityMetrics); err != nil {
log.Panicf("Failed to start as daemon: %s", err)
}
......
......@@ -3,6 +3,7 @@ package prometheus
import (
"strconv"
analysisdashboard "github.com/iotaledger/goshimmer/plugins/analysis/dashboard"
"github.com/iotaledger/goshimmer/plugins/metrics"
"github.com/prometheus/client_golang/prometheus"
)
......@@ -10,6 +11,9 @@ import (
var (
clientsInfoCPU *prometheus.GaugeVec
clientsInfoMemory *prometheus.GaugeVec
clientsNeighborCount *prometheus.GaugeVec
networkDiameter prometheus.Gauge
)
func registerClientsMetrics() {
......@@ -39,8 +43,26 @@ func registerClientsMetrics() {
},
)
clientsNeighborCount = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "clients_neighbor_count",
Help: "Info about client's memory usage labeled with nodeID, OS, ARCH and number of cpu cores",
},
[]string{
"nodeID",
"direction",
},
)
networkDiameter = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "clients_network_diameter",
Help: "Autopeering network diameter",
})
registry.MustRegister(clientsInfoCPU)
registry.MustRegister(clientsInfoMemory)
registry.MustRegister(clientsNeighborCount)
registry.MustRegister(networkDiameter)
addCollect(collectClientsInfo)
}
......@@ -62,4 +84,10 @@ func collectClientsInfo() {
strconv.Itoa(clientInfo.NumCPU),
).Set(float64(clientInfo.MemoryUsage))
}
for nodeID, neighborCount := range analysisdashboard.NumOfNeighbors() {
clientsNeighborCount.WithLabelValues(nodeID, "in").Set(float64(neighborCount.Inbound))
clientsNeighborCount.WithLabelValues(nodeID, "out").Set(float64(neighborCount.Inbound))
}
networkDiameter.Set(float64(metrics.NetworkDiameter()))
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment