diff --git a/internal/metrics/crawler.go b/internal/metrics/crawler.go index 494b39b..65403a1 100644 --- a/internal/metrics/crawler.go +++ b/internal/metrics/crawler.go @@ -28,6 +28,9 @@ type CrawlerServiceMetrics struct { // Holds a reference to the main metrics container this is a part of metrics *Metrics + // General Service Metrics + version *prometheus.GaugeVec + // Current network network *string @@ -50,6 +53,10 @@ type CrawlerServiceMetrics struct { // InitMetrics sets all the metrics properties func (s *CrawlerServiceMetrics) InitMetrics(network *string) { s.network = network + + // General Service Metrics + s.version = s.metrics.newGaugeVec(chiaServiceCrawler, "version", "The version of chia-blockchain the service is running", []string{"version"}) + // Crawler Metrics s.totalNodes5Days = s.metrics.newGauge(chiaServiceCrawler, "total_nodes_5_days", "Total number of nodes that have been gossiped around the network with a timestamp in the last 5 days. The crawler did not necessarily connect to all of these peers itself.") s.reliableNodes = s.metrics.newGauge(chiaServiceCrawler, "reliable_nodes", "reliable nodes are nodes that have port 8444 open and have available space for more peer connections") @@ -108,6 +115,9 @@ func (s *CrawlerServiceMetrics) initMaxmindASNDB() error { // InitialData is called on startup of the metrics server, to allow seeding metrics with current/initial data func (s *CrawlerServiceMetrics) InitialData() { + // Only get the version on an initial or reconnection + utils.LogErr(s.metrics.client.CrawlerService.GetVersion(&rpc.GetVersionOptions{})) + utils.LogErr(s.metrics.client.CrawlerService.GetPeerCounts()) } @@ -116,6 +126,7 @@ func (s *CrawlerServiceMetrics) SetupPollingMetrics() {} // Disconnected clears/unregisters metrics when the connection drops func (s *CrawlerServiceMetrics) Disconnected() { + s.version.Reset() s.totalNodes5Days.Unregister() s.reliableNodes.Unregister() s.ipv4Nodes5Days.Unregister() @@ -132,6 +143,8 @@ func (s *CrawlerServiceMetrics) Reconnected() { // ReceiveResponse handles crawler responses that are returned over the websocket func (s *CrawlerServiceMetrics) ReceiveResponse(resp *types.WebsocketResponse) { switch resp.Command { + case "get_version": + versionHelper(resp, s.version) case "get_peer_counts": fallthrough case "loaded_initial_peers": diff --git a/internal/metrics/farmer.go b/internal/metrics/farmer.go index 917fc79..0212860 100644 --- a/internal/metrics/farmer.go +++ b/internal/metrics/farmer.go @@ -22,6 +22,9 @@ type FarmerServiceMetrics struct { // Holds a reference to the main metrics container this is a part of metrics *Metrics + // General Service Metrics + version *prometheus.GaugeVec + // Connection Metrics connectionCount *prometheus.GaugeVec @@ -58,6 +61,9 @@ type FarmerServiceMetrics struct { // InitMetrics sets all the metrics properties func (s *FarmerServiceMetrics) InitMetrics(network *string) { + // General Service Metrics + s.version = s.metrics.newGaugeVec(chiaServiceFarmer, "version", "The version of chia-blockchain the service is running", []string{"version"}) + s.totalPlotsValue = map[types.Bytes32]uint64{} s.nodeIDToHostname = map[types.Bytes32]string{} @@ -89,6 +95,9 @@ func (s *FarmerServiceMetrics) InitMetrics(network *string) { // InitialData is called on startup of the metrics server, to allow seeding metrics with current/initial data func (s *FarmerServiceMetrics) InitialData() { + // Only get the version on an initial or reconnection + utils.LogErr(s.metrics.client.FarmerService.GetVersion(&rpc.GetVersionOptions{})) + utils.LogErr(s.metrics.client.FarmerService.GetConnections(&rpc.GetConnectionsOptions{})) } @@ -97,6 +106,7 @@ func (s *FarmerServiceMetrics) SetupPollingMetrics() {} // Disconnected clears/unregisters metrics when the connection drops func (s *FarmerServiceMetrics) Disconnected() { + s.version.Reset() s.connectionCount.Reset() s.plotFilesize.Reset() s.plotCount.Reset() @@ -113,6 +123,8 @@ func (s *FarmerServiceMetrics) Reconnected() { // ReceiveResponse handles crawler responses that are returned over the websocket func (s *FarmerServiceMetrics) ReceiveResponse(resp *types.WebsocketResponse) { switch resp.Command { + case "get_version": + versionHelper(resp, s.version) case "get_connections": s.GetConnections(resp) case "new_farming_info": diff --git a/internal/metrics/fullnode.go b/internal/metrics/fullnode.go index 9af042b..4c66fc8 100644 --- a/internal/metrics/fullnode.go +++ b/internal/metrics/fullnode.go @@ -34,6 +34,9 @@ type FullNodeServiceMetrics struct { // Holds a reference to the main metrics container this is a part of metrics *Metrics + // General Service Metrics + version *prometheus.GaugeVec + // GetBlockchainState Metrics difficulty *wrappedPrometheus.LazyGauge mempoolCost *wrappedPrometheus.LazyGauge @@ -94,6 +97,9 @@ type FullNodeServiceMetrics struct { // InitMetrics sets all the metrics properties func (s *FullNodeServiceMetrics) InitMetrics(network *string) { + // General Service Metrics + s.version = s.metrics.newGaugeVec(chiaServiceFullNode, "version", "The version of chia-blockchain the service is running", []string{"version"}) + // BlockchainState Metrics s.difficulty = s.metrics.newGauge(chiaServiceFullNode, "difficulty", "Current network difficulty") s.mempoolCost = s.metrics.newGauge(chiaServiceFullNode, "mempool_cost", "Current mempool size in cost") @@ -151,6 +157,9 @@ func (s *FullNodeServiceMetrics) InitMetrics(network *string) { // InitialData is called on startup of the metrics server, to allow seeding metrics with // current/initial data func (s *FullNodeServiceMetrics) InitialData() { + // Only get the version on an initial or reconnection + utils.LogErr(s.metrics.client.FullNodeService.GetVersion(&rpc.GetVersionOptions{})) + // Ask for some initial data so we dont have to wait as long utils.LogErr(s.metrics.client.FullNodeService.GetBlockchainState()) // Also calls get_connections once we get the response utils.LogErr(s.metrics.client.FullNodeService.GetBlockCountMetrics()) @@ -170,6 +179,7 @@ func (s *FullNodeServiceMetrics) SetupPollingMetrics() {} // Disconnected clears/unregisters metrics when the connection drops func (s *FullNodeServiceMetrics) Disconnected() { + s.version.Reset() s.difficulty.Unregister() s.mempoolCost.Unregister() s.mempoolMinFee.Reset() @@ -212,6 +222,8 @@ func (s *FullNodeServiceMetrics) Reconnected() { // ReceiveResponse handles full node related responses that are returned over the websocket func (s *FullNodeServiceMetrics) ReceiveResponse(resp *types.WebsocketResponse) { switch resp.Command { + case "get_version": + versionHelper(resp, s.version) case "get_blockchain_state": s.GetBlockchainState(resp) // Ask for connection info when we get updated blockchain state diff --git a/internal/metrics/harvester.go b/internal/metrics/harvester.go index b1d9849..4d89d69 100644 --- a/internal/metrics/harvester.go +++ b/internal/metrics/harvester.go @@ -23,6 +23,9 @@ type HarvesterServiceMetrics struct { // Holds a reference to the main metrics container this is a part of metrics *Metrics + // General Service Metrics + version *prometheus.GaugeVec + // Connection Metrics connectionCount *prometheus.GaugeVec @@ -48,6 +51,9 @@ type HarvesterServiceMetrics struct { // InitMetrics sets all the metrics properties func (s *HarvesterServiceMetrics) InitMetrics(network *string) { + // General Service Metrics + s.version = s.metrics.newGaugeVec(chiaServiceHarvester, "version", "The version of chia-blockchain the service is running", []string{"version"}) + // Connection Metrics s.connectionCount = s.metrics.newGaugeVec(chiaServiceHarvester, "connection_count", "Number of active connections for each type of peer", []string{"node_type"}) @@ -70,6 +76,9 @@ func (s *HarvesterServiceMetrics) InitMetrics(network *string) { // InitialData is called on startup of the metrics server, to allow seeding metrics with current/initial data func (s *HarvesterServiceMetrics) InitialData() { + // Only get the version on an initial or reconnection + utils.LogErr(s.metrics.client.HarvesterService.GetVersion(&rpc.GetVersionOptions{})) + s.httpGetPlots() } @@ -106,6 +115,7 @@ func (s *HarvesterServiceMetrics) httpGetPlots() { // Disconnected clears/unregisters metrics when the connection drops func (s *HarvesterServiceMetrics) Disconnected() { + s.version.Reset() s.connectionCount.Reset() s.totalPlots.Unregister() s.plotFilesize.Reset() @@ -123,6 +133,8 @@ func (s *HarvesterServiceMetrics) Reconnected() { // ReceiveResponse handles crawler responses that are returned over the websocket func (s *HarvesterServiceMetrics) ReceiveResponse(resp *types.WebsocketResponse) { switch resp.Command { + case "get_version": + versionHelper(resp, s.version) case "get_connections": s.GetConnections(resp) case "farming_info": diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 7e48b8e..e50432a 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -500,6 +500,17 @@ func connectionCountHelper(resp *types.WebsocketResponse, connectionCount *prome connectionCount.WithLabelValues("wallet").Set(wallet) } +func versionHelper(resp *types.WebsocketResponse, versionMetric *prometheus.GaugeVec) { + version := &rpc.GetVersionResponse{} + err := json.Unmarshal(resp.Data, version) + if err != nil { + log.Errorf("Error unmarshalling: %s\n", err.Error()) + return + } + + versionMetric.WithLabelValues(version.Version).Set(1) +} + type debugEvent struct { Data map[string]float64 `json:"data"` } diff --git a/internal/metrics/timelord.go b/internal/metrics/timelord.go index 653051c..0ccacda 100644 --- a/internal/metrics/timelord.go +++ b/internal/metrics/timelord.go @@ -3,6 +3,7 @@ package metrics import ( "encoding/json" + "github.com/chia-network/go-chia-libs/pkg/rpc" log "github.com/sirupsen/logrus" "github.com/chia-network/go-chia-libs/pkg/types" @@ -20,6 +21,9 @@ type TimelordServiceMetrics struct { // Holds a reference to the main metrics container this is a part of metrics *Metrics + // General Service Metrics + version *prometheus.GaugeVec + // Timelord Metrics fastestTimelord *wrappedPrometheus.LazyCounter slowTimelord *wrappedPrometheus.LazyCounter @@ -32,6 +36,9 @@ type TimelordServiceMetrics struct { // InitMetrics sets all the metrics properties func (s *TimelordServiceMetrics) InitMetrics(network *string) { + // General Service Metrics + s.version = s.metrics.newGaugeVec(chiaServiceTimelord, "version", "The version of chia-blockchain the service is running", []string{"version"}) + s.fastestTimelord = s.metrics.newCounter(chiaServiceTimelord, "fastest_timelord", "Counter for how many times this timelord has been fastest since the exporter has been running") s.slowTimelord = s.metrics.newCounter(chiaServiceTimelord, "slow_timelord", "Counter for how many times this timelord has NOT been the fastest since the exporter has been running") s.estimatedIPS = s.metrics.newGauge(chiaServiceTimelord, "estimated_ips", "Current estimated IPS. Updated every time a new PoT Challenge is complete") @@ -44,7 +51,8 @@ func (s *TimelordServiceMetrics) InitMetrics(network *string) { // InitialData is called on startup of the metrics server, to allow seeding metrics with // current/initial data func (s *TimelordServiceMetrics) InitialData() { - utils.LogErr(s.metrics.client.CrawlerService.GetPeerCounts()) + // Only get the version on an initial or reconnection + utils.LogErr(s.metrics.client.TimelordService.GetVersion(&rpc.GetVersionOptions{})) } // SetupPollingMetrics starts any metrics that happen on an interval @@ -52,6 +60,7 @@ func (s *TimelordServiceMetrics) SetupPollingMetrics() {} // Disconnected clears/unregisters metrics when the connection drops func (s *TimelordServiceMetrics) Disconnected() { + s.version.Reset() s.fastestTimelord.Unregister() s.slowTimelord.Unregister() s.estimatedIPS.Unregister() @@ -67,6 +76,8 @@ func (s *TimelordServiceMetrics) Reconnected() { func (s *TimelordServiceMetrics) ReceiveResponse(resp *types.WebsocketResponse) { //("finished_pot_challenge", "new_compact_proof", "skipping_peak", "new_peak") switch resp.Command { + case "get_version": + versionHelper(resp, s.version) case "finished_pot": s.FinishedPoT(resp) case "new_compact_proof": diff --git a/internal/metrics/wallet.go b/internal/metrics/wallet.go index 56cfcca..e7f5ad9 100644 --- a/internal/metrics/wallet.go +++ b/internal/metrics/wallet.go @@ -23,6 +23,9 @@ type WalletServiceMetrics struct { // Holds a reference to the main metrics container this is a part of metrics *Metrics + // General Service Metrics + version *prometheus.GaugeVec + // Connection Metrics connectionCount *prometheus.GaugeVec @@ -40,6 +43,9 @@ type WalletServiceMetrics struct { // InitMetrics sets all the metrics properties func (s *WalletServiceMetrics) InitMetrics(network *string) { + // General Service Metrics + s.version = s.metrics.newGaugeVec(chiaServiceWallet, "version", "The version of chia-blockchain the service is running", []string{"version"}) + // Connection Metrics s.connectionCount = s.metrics.newGaugeVec(chiaServiceWallet, "connection_count", "Number of active connections for each type of peer", []string{"node_type"}) @@ -59,6 +65,9 @@ func (s *WalletServiceMetrics) InitMetrics(network *string) { // InitialData is called on startup of the metrics server, to allow seeding metrics with // current/initial data func (s *WalletServiceMetrics) InitialData() { + // Only get the version on an initial or reconnection + utils.LogErr(s.metrics.client.WalletService.GetVersion(&rpc.GetVersionOptions{})) + utils.LogErr(s.metrics.client.WalletService.GetWallets(&rpc.GetWalletsOptions{})) utils.LogErr(s.metrics.client.WalletService.GetSyncStatus()) } @@ -75,6 +84,7 @@ func (s *WalletServiceMetrics) SetupPollingMetrics() { // Disconnected clears/unregisters metrics when the connection drops func (s *WalletServiceMetrics) Disconnected() { + s.version.Reset() s.connectionCount.Reset() s.walletSynced.Unregister() s.confirmedBalance.Reset() @@ -92,6 +102,8 @@ func (s *WalletServiceMetrics) Reconnected() { // ReceiveResponse handles wallet responses that are returned over the websocket func (s *WalletServiceMetrics) ReceiveResponse(resp *types.WebsocketResponse) { switch resp.Command { + case "get_version": + versionHelper(resp, s.version) case "get_connections": s.GetConnections(resp) case "coin_added":