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 }