From 273c3cb68323167e578ca979057498ad2cb2e0b7 Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Fri, 9 Sep 2022 11:49:38 +1000 Subject: [PATCH 1/2] feat: Detect remote peer client version --- pkg/exporter/consensus/api/types/peer.go | 42 ++++++++++++++++++++++++ pkg/exporter/consensus/jobs/general.go | 18 ++++++++++ pkg/exporter/consensus/metrics.go | 1 + 3 files changed, 61 insertions(+) diff --git a/pkg/exporter/consensus/api/types/peer.go b/pkg/exporter/consensus/api/types/peer.go index 3769392..08a7129 100644 --- a/pkg/exporter/consensus/api/types/peer.go +++ b/pkg/exporter/consensus/api/types/peer.go @@ -18,6 +18,11 @@ type Peer struct { LastSeenP2PAddress string `json:"last_seen_p2p_address"` State string `json:"state"` Direction string `json:"direction"` + Agent string `json:"agent"` +} + +func (p *Peer) DeriveAgent() Agent { + return AgentFromString(p.Agent) } type Peers []Peer @@ -64,3 +69,40 @@ func (p *Peers) ByStateAndDirection(state, direction string) Peers { return peers } + +func (p *Peers) ByAgent(agent Agent) Peers { + var peers []Peer + + for _, peer := range *p { + if peer.DeriveAgent() == agent { + peers = append(peers, peer) + } + } + + return peers +} + +func (p *Peers) AgentCount() AgentCount { + count := AgentCount{} + + for _, agent := range AllAgents { + numberOfAgents := len(p.ByAgent(agent)) + + switch agent { + case AgentUnknown: + count.Unknown = numberOfAgents + case AgentLighthouse: + count.Lighthouse = numberOfAgents + case AgentNimbus: + count.Nimbus = numberOfAgents + case AgentTeku: + count.Teku = numberOfAgents + case AgentPrysm: + count.Prysm = numberOfAgents + case AgentLodestar: + count.Lodestar = numberOfAgents + } + } + + return count +} diff --git a/pkg/exporter/consensus/jobs/general.go b/pkg/exporter/consensus/jobs/general.go index 2572aad..52d87cd 100644 --- a/pkg/exporter/consensus/jobs/general.go +++ b/pkg/exporter/consensus/jobs/general.go @@ -16,6 +16,7 @@ type General struct { NodeVersion prometheus.GaugeVec ClientName prometheus.GaugeVec Peers prometheus.GaugeVec + PeerAgents prometheus.GaugeVec } const ( @@ -52,6 +53,17 @@ func NewGeneralJob(beac beacon.Node, log logrus.FieldLogger, namespace string, c "direction", }, ), + PeerAgents: *prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: namespace, + Name: "peer_agents", + Help: "The count of peers connected to beacon node by agent.", + ConstLabels: constLabels, + }, + []string{ + "agent", + }, + ), } } @@ -76,6 +88,12 @@ func (g *General) Start(ctx context.Context) error { } } + connected := event.Peers.ByState("connected") + + for _, agent := range types.AllAgents { + g.PeerAgents.WithLabelValues(string(agent)).Set(float64(len(connected.ByAgent(agent)))) + } + return nil }); err != nil { return err diff --git a/pkg/exporter/consensus/metrics.go b/pkg/exporter/consensus/metrics.go index dc6a243..dd97356 100644 --- a/pkg/exporter/consensus/metrics.go +++ b/pkg/exporter/consensus/metrics.go @@ -49,6 +49,7 @@ func NewMetrics(client eth2client.Service, ap api.ConsensusClient, beac beacon.N prometheus.MustRegister(m.generalMetrics.NodeVersion) prometheus.MustRegister(m.generalMetrics.Peers) + prometheus.MustRegister(m.generalMetrics.PeerAgents) prometheus.MustRegister(m.syncMetrics.Percentage) prometheus.MustRegister(m.syncMetrics.EstimatedHighestSlot) From 66eb748bde98801ecbe338995ebb895d03e19a52 Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Fri, 9 Sep 2022 12:00:25 +1000 Subject: [PATCH 2/2] feat: Add consensus peer client detection --- pkg/exporter/consensus/api/types/agents.go | 60 +++++++++++++++++++ .../consensus/api/types/agents_test.go | 27 +++++++++ 2 files changed, 87 insertions(+) create mode 100644 pkg/exporter/consensus/api/types/agents.go create mode 100644 pkg/exporter/consensus/api/types/agents_test.go diff --git a/pkg/exporter/consensus/api/types/agents.go b/pkg/exporter/consensus/api/types/agents.go new file mode 100644 index 0000000..3d3e981 --- /dev/null +++ b/pkg/exporter/consensus/api/types/agents.go @@ -0,0 +1,60 @@ +package types + +import ( + "strings" +) + +type Agent string + +const ( + AgentUnknown Agent = "unknown" + AgentLighthouse Agent = "lighthouse" + AgentNimbus Agent = "nimbus" + AgentTeku Agent = "teku" + AgentPrysm Agent = "prysm" + AgentLodestar Agent = "lodestar" +) + +var AllAgents = []Agent{ + AgentUnknown, + AgentLighthouse, + AgentNimbus, + AgentTeku, + AgentPrysm, + AgentLodestar, +} + +type AgentCount struct { + Unknown int `json:"unknown"` + Lighthouse int `json:"lighthouse"` + Nimbus int `json:"nimbus"` + Teku int `json:"teku"` + Prysm int `json:"prysm"` + Lodestar int `json:"lodestar"` +} + +func AgentFromString(agent string) Agent { + asLower := strings.ToLower(agent) + + if strings.Contains(asLower, "lighthouse") { + return AgentLighthouse + } + + if strings.Contains(asLower, "nimbus") { + return AgentNimbus + } + + if strings.Contains(asLower, "teku") { + return AgentTeku + } + + if strings.Contains(asLower, "prysm") { + return AgentPrysm + } + + if strings.Contains(asLower, "lodestar") { + return AgentLodestar + } + + return AgentUnknown +} diff --git a/pkg/exporter/consensus/api/types/agents_test.go b/pkg/exporter/consensus/api/types/agents_test.go new file mode 100644 index 0000000..26f2a32 --- /dev/null +++ b/pkg/exporter/consensus/api/types/agents_test.go @@ -0,0 +1,27 @@ +package types + +import "testing" + +func TestAgentParsing(t *testing.T) { + t.Parallel() + + tests := []struct { + input string + expect Agent + }{ + {"Prysm/v2.0.2/4a4a7e97dfd2285a5e48a178f693d870e9a4ff60", AgentPrysm}, + {"Lighthouse/v3.1.0-aa022f4/x86_64-linux", AgentLighthouse}, + {"nimbus", AgentNimbus}, + {"teku/teku/v22.9.0/linux-x86_64/-privatebuild-openjdk64bitservervm-java-17", AgentTeku}, + {"Lodestar/v0.32.0-rc.0-1-gc3b5b6a9/linux-x64/nodejs", AgentLodestar}, + } + + for _, test := range tests { + t.Run(test.input, func(t *testing.T) { + t.Parallel() + if actual := AgentFromString(test.input); actual != test.expect { + t.Errorf("Expected %s, got %s", test.expect, actual) + } + }) + } +}