github.com/amazechain/amc@v0.1.3/internal/p2p/monitoring.go (about)

     1  package p2p
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/libp2p/go-libp2p/core/peer"
     7  	"github.com/libp2p/go-libp2p/core/peerstore"
     8  	"github.com/prometheus/client_golang/prometheus"
     9  	"github.com/prometheus/client_golang/prometheus/promauto"
    10  )
    11  
    12  var (
    13  	knownAgentVersions = []string{
    14  		"lighthouse",
    15  		"nimbus",
    16  		"prysm",
    17  		"teku",
    18  		"lodestar",
    19  		"js-libp2p",
    20  		"rust-libp2p",
    21  	}
    22  	p2pPeerCount = promauto.NewGaugeVec(prometheus.GaugeOpts{
    23  		Name: "p2p_peer_count",
    24  		Help: "The number of peers in a given state.",
    25  	},
    26  		[]string{"state"})
    27  	connectedPeersCount = promauto.NewGaugeVec(prometheus.GaugeOpts{
    28  		Name: "connected_libp2p_peers",
    29  		Help: "Tracks the total number of connected libp2p peers by agent string",
    30  	},
    31  		[]string{"agent"},
    32  	)
    33  	avgScoreConnectedClients = promauto.NewGaugeVec(prometheus.GaugeOpts{
    34  		Name: "connected_libp2p_peers_average_scores",
    35  		Help: "Tracks the overall p2p scores of connected libp2p peers by agent string",
    36  	},
    37  		[]string{"agent"},
    38  	)
    39  	repeatPeerConnections = promauto.NewCounter(prometheus.CounterOpts{
    40  		Name: "p2p_repeat_attempts",
    41  		Help: "The number of repeat attempts the connection handler is triggered for a peer.",
    42  	})
    43  	statusMessageMissing = promauto.NewCounter(prometheus.CounterOpts{
    44  		Name: "p2p_status_message_missing",
    45  		Help: "The number of attempts the connection handler rejects a peer for a missing status message.",
    46  	})
    47  
    48  	// Gossip Tracer Metrics
    49  	pubsubTopicsActive = promauto.NewGaugeVec(prometheus.GaugeOpts{
    50  		Name: "p2p_pubsub_topic_active",
    51  		Help: "The topics that the peer is participating in gossipsub.",
    52  	},
    53  		[]string{"topic"})
    54  	pubsubTopicsGraft = promauto.NewCounterVec(prometheus.CounterOpts{
    55  		Name: "p2p_pubsub_graft_total",
    56  		Help: "The number of graft messages sent for a particular topic",
    57  	},
    58  		[]string{"topic"})
    59  	pubsubTopicsPrune = promauto.NewCounterVec(prometheus.CounterOpts{
    60  		Name: "p2p_pubsub_prune_total",
    61  		Help: "The number of prune messages sent for a particular topic",
    62  	},
    63  		[]string{"topic"})
    64  	pubsubMessageDeliver = promauto.NewCounterVec(prometheus.CounterOpts{
    65  		Name: "p2p_pubsub_deliver_total",
    66  		Help: "The number of messages received for delivery of a particular topic",
    67  	},
    68  		[]string{"topic"})
    69  	pubsubMessageUndeliverable = promauto.NewCounterVec(prometheus.CounterOpts{
    70  		Name: "p2p_pubsub_undeliverable_total",
    71  		Help: "The number of messages received which weren't able to be delivered of a particular topic",
    72  	},
    73  		[]string{"topic"})
    74  	pubsubMessageValidate = promauto.NewCounterVec(prometheus.CounterOpts{
    75  		Name: "p2p_pubsub_validate_total",
    76  		Help: "The number of messages received for validation of a particular topic",
    77  	},
    78  		[]string{"topic"})
    79  	pubsubMessageDuplicate = promauto.NewCounterVec(prometheus.CounterOpts{
    80  		Name: "p2p_pubsub_duplicate_total",
    81  		Help: "The number of duplicate messages sent for a particular topic",
    82  	},
    83  		[]string{"topic"})
    84  	pubsubMessageReject = promauto.NewCounterVec(prometheus.CounterOpts{
    85  		Name: "p2p_pubsub_reject_total",
    86  		Help: "The number of messages rejected of a particular topic",
    87  	},
    88  		[]string{"topic"})
    89  	pubsubPeerThrottle = promauto.NewCounterVec(prometheus.CounterOpts{
    90  		Name: "p2p_pubsub_throttle_total",
    91  		Help: "The number of times a peer has been throttled for a particular topic",
    92  	},
    93  		[]string{"topic"})
    94  	pubsubRPCRecv = promauto.NewCounterVec(prometheus.CounterOpts{
    95  		Name: "p2p_pubsub_rpc_recv_total",
    96  		Help: "The number of messages received via rpc for a particular topic",
    97  	},
    98  		[]string{"control_message"})
    99  	pubsubRPCSubRecv = promauto.NewCounter(prometheus.CounterOpts{
   100  		Name: "p2p_pubsub_rpc_recv_sub_total",
   101  		Help: "The number of subscription messages received via rpc",
   102  	})
   103  	pubsubRPCDrop = promauto.NewCounterVec(prometheus.CounterOpts{
   104  		Name: "p2p_pubsub_rpc_drop_total",
   105  		Help: "The number of messages dropped via rpc for a particular topic",
   106  	},
   107  		[]string{"control_message"})
   108  	pubsubRPCSubDrop = promauto.NewCounter(prometheus.CounterOpts{
   109  		Name: "p2p_pubsub_rpc_drop_sub_total",
   110  		Help: "The number of subscription messages dropped via rpc",
   111  	})
   112  	pubsubRPCSent = promauto.NewCounterVec(prometheus.CounterOpts{
   113  		Name: "p2p_pubsub_rpc_sent_total",
   114  		Help: "The number of messages sent via rpc for a particular topic",
   115  	},
   116  		[]string{"control_message"})
   117  	pubsubRPCSubSent = promauto.NewCounter(prometheus.CounterOpts{
   118  		Name: "p2p_pubsub_rpc_sent_sub_total",
   119  		Help: "The number of subscription messages sent via rpc",
   120  	})
   121  )
   122  
   123  func (s *Service) updateMetrics() {
   124  	connectedPeers := s.peers.Connected()
   125  	p2pPeerCount.WithLabelValues("Connected").Set(float64(len(connectedPeers)))
   126  	p2pPeerCount.WithLabelValues("Disconnected").Set(float64(len(s.peers.Disconnected())))
   127  	p2pPeerCount.WithLabelValues("Connecting").Set(float64(len(s.peers.Connecting())))
   128  	p2pPeerCount.WithLabelValues("Disconnecting").Set(float64(len(s.peers.Disconnecting())))
   129  	p2pPeerCount.WithLabelValues("Bad").Set(float64(len(s.peers.Bad())))
   130  
   131  	store := s.Host().Peerstore()
   132  	numConnectedPeersByClient := make(map[string]float64)
   133  	peerScoresByClient := make(map[string][]float64)
   134  	for i := 0; i < len(connectedPeers); i++ {
   135  		p := connectedPeers[i]
   136  		pid, err := peer.Decode(p.String())
   137  		if err != nil {
   138  			log.Debug("Could not decode peer string", "err", err)
   139  			continue
   140  		}
   141  
   142  		foundName := agentFromPid(pid, store)
   143  		numConnectedPeersByClient[foundName] += 1
   144  
   145  		// Get peer scoring data.
   146  		overallScore := s.peers.Scorers().Score(pid)
   147  		peerScoresByClient[foundName] = append(peerScoresByClient[foundName], overallScore)
   148  	}
   149  	for agent, total := range numConnectedPeersByClient {
   150  		connectedPeersCount.WithLabelValues(agent).Set(total)
   151  	}
   152  	for agent, scoringData := range peerScoresByClient {
   153  		avgScore := average(scoringData)
   154  		avgScoreConnectedClients.WithLabelValues(agent).Set(avgScore)
   155  	}
   156  }
   157  
   158  func average(xs []float64) float64 {
   159  	if len(xs) == 0 {
   160  		return 0
   161  	}
   162  	total := 0.0
   163  	for _, v := range xs {
   164  		total += v
   165  	}
   166  	return total / float64(len(xs))
   167  }
   168  
   169  func agentFromPid(pid peer.ID, store peerstore.Peerstore) string {
   170  	// Get the agent data.
   171  	rawAgent, err := store.Get(pid, "AgentVersion")
   172  	agent, ok := rawAgent.(string)
   173  	if err != nil || !ok {
   174  		return "unknown"
   175  	}
   176  	foundName := "unknown"
   177  	for _, knownAgent := range knownAgentVersions {
   178  		// If the agent string matches one of our known agents, we set
   179  		// the value to our own, sanitized string.
   180  		if strings.Contains(strings.ToLower(agent), knownAgent) {
   181  			foundName = knownAgent
   182  		}
   183  	}
   184  	return foundName
   185  }