diff --git a/tools/bootnode/BUILD.bazel b/tools/bootnode/BUILD.bazel index 0e89d3751b..ed5f2a39f2 100644 --- a/tools/bootnode/BUILD.bazel +++ b/tools/bootnode/BUILD.bazel @@ -13,6 +13,7 @@ go_library( "//shared/iputils:go_default_library", "//shared/logutil:go_default_library", "//shared/params:go_default_library", + "//shared/runutil:go_default_library", "//shared/version:go_default_library", "@com_github_btcsuite_btcd//btcec:go_default_library", "@com_github_ethereum_go_ethereum//log:go_default_library", @@ -28,6 +29,8 @@ go_library( "@com_github_libp2p_go_libp2p_kad_dht//opts:go_default_library", "@com_github_multiformats_go_multiaddr//:go_default_library", "@com_github_pkg_errors//:go_default_library", + "@com_github_prometheus_client_golang//prometheus:go_default_library", + "@com_github_prometheus_client_golang//prometheus/promauto:go_default_library", "@com_github_prysmaticlabs_go_bitfield//:go_default_library", "@com_github_prysmaticlabs_go_ssz//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", @@ -48,9 +51,10 @@ go_image( visibility = ["//visibility:private"], deps = [ "//proto/beacon/p2p/v1:go_default_library", - "//shared/iputils:go_default_library", "//shared/logutil:go_default_library", "//shared/params:go_default_library", + "//shared/runutil:go_default_library", + "//shared/iputils:go_default_library", "//shared/version:go_default_library", "@com_github_btcsuite_btcd//btcec:go_default_library", "@com_github_ethereum_go_ethereum//log:go_default_library", @@ -66,6 +70,8 @@ go_image( "@com_github_libp2p_go_libp2p_kad_dht//opts:go_default_library", "@com_github_multiformats_go_multiaddr//:go_default_library", "@com_github_pkg_errors//:go_default_library", + "@com_github_prometheus_client_golang//prometheus:go_default_library", + "@com_github_prometheus_client_golang//prometheus/promauto:go_default_library", "@com_github_prysmaticlabs_go_bitfield//:go_default_library", "@com_github_prysmaticlabs_go_ssz//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", diff --git a/tools/bootnode/bootnode.go b/tools/bootnode/bootnode.go index 3a91103121..682422837f 100644 --- a/tools/bootnode/bootnode.go +++ b/tools/bootnode/bootnode.go @@ -20,6 +20,7 @@ import ( "net" "net/http" "os" + "time" "github.com/btcsuite/btcd/btcec" gethlog "github.com/ethereum/go-ethereum/log" @@ -35,27 +36,38 @@ import ( dhtopts "github.com/libp2p/go-libp2p-kad-dht/opts" ma "github.com/multiformats/go-multiaddr" "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prysmaticlabs/go-bitfield" "github.com/prysmaticlabs/go-ssz" pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" "github.com/prysmaticlabs/prysm/shared/iputils" "github.com/prysmaticlabs/prysm/shared/logutil" "github.com/prysmaticlabs/prysm/shared/params" + "github.com/prysmaticlabs/prysm/shared/runutil" "github.com/prysmaticlabs/prysm/shared/version" "github.com/sirupsen/logrus" _ "go.uber.org/automaxprocs" ) var ( - debug = flag.Bool("debug", false, "Enable debug logging") - logFileName = flag.String("log-file", "", "Specify log filename, relative or absolute") - privateKey = flag.String("private", "", "Private key to use for peer ID") - discv5port = flag.Int("discv5-port", 4000, "Port to listen for discv5 connections") - kademliaPort = flag.Int("kad-port", 4500, "Port to listen for connections to kad DHT") - metricsPort = flag.Int("metrics-port", 5000, "Port to listen for connections") - externalIP = flag.String("external-ip", "", "External IP for the bootnode") - disableKad = flag.Bool("disable-kad", false, "Disables the bootnode from running kademlia dht") - log = logrus.WithField("prefix", "bootnode") + debug = flag.Bool("debug", false, "Enable debug logging") + logFileName = flag.String("log-file", "", "Specify log filename, relative or absolute") + privateKey = flag.String("private", "", "Private key to use for peer ID") + discv5port = flag.Int("discv5-port", 4000, "Port to listen for discv5 connections") + kademliaPort = flag.Int("kad-port", 4500, "Port to listen for connections to kad DHT") + metricsPort = flag.Int("metrics-port", 5000, "Port to listen for connections") + externalIP = flag.String("external-ip", "", "External IP for the bootnode") + disableKad = flag.Bool("disable-kad", false, "Disables the bootnode from running kademlia dht") + log = logrus.WithField("prefix", "bootnode") + kadPeersCount = promauto.NewGauge(prometheus.GaugeOpts{ + Name: "bootstrap_node_kaddht_peers", + Help: "The current number of kaddht peers of the bootstrap node", + }) + discv5PeersCount = promauto.NewGauge(prometheus.GaugeOpts{ + Name: "bootstrap_node_discv5_peers", + Help: "The current number of discv5 peers of the bootstrap node", + }) ) const dhtProtocol = "/prysm/0.0.0/dht" @@ -99,8 +111,9 @@ func main() { node := listener.Self() log.Infof("Running bootnode: %s", node.String()) + var dhtValue *kaddht.IpfsDHT if !*disableKad { - startKademliaDHT(interfacePrivKey) + dhtValue = startKademliaDHT(interfacePrivKey) } handler := &handler{ @@ -113,14 +126,20 @@ func main() { log.Fatalf("Failed to start server %v", err) } + // Update metrics once per slot. + slotDuration := time.Duration(params.BeaconConfig().SecondsPerSlot) + runutil.RunEvery(context.Background(), slotDuration*time.Second, func() { + updateMetrics(listener, dhtValue) + }) + select {} } -func startKademliaDHT(privKey crypto.PrivKey) { - +func startKademliaDHT(privKey crypto.PrivKey) *kaddht.IpfsDHT { if *debug { logging.SetDebugLogging() } + ipAddr := defaultIP if *externalIP != "" { ipAddr = *externalIP @@ -157,6 +176,7 @@ func startKademliaDHT(privKey crypto.PrivKey) { } fmt.Printf("Running Kademlia DHT bootnode: /ip4/%s/tcp/%d/p2p/%s\n", ipAddr, *kademliaPort, host.ID().Pretty()) + return dht } func createListener(ipAddr string, port int, cfg discover.Config) *discover.UDPv5 { @@ -264,3 +284,12 @@ func extractPrivateKey() (*ecdsa.PrivateKey, crypto.PrivKey) { return privKey, interfaceKey } + +func updateMetrics(listener *discover.UDPv5, dht *kaddht.IpfsDHT) { + if dht != nil { + kadPeersCount.Set(float64(len(dht.Host().Peerstore().Peers()))) + } + if listener != nil { + discv5PeersCount.Set(float64(len(listener.AllNodes()))) + } +}