Skip to content

Commit fa68f98

Browse files
authored
Merge pull request #33 from Chia-Network/farmer-harvester
Farmer harvester
2 parents f4f2b79 + 6910c9f commit fa68f98

File tree

6 files changed

+184
-11
lines changed

6 files changed

+184
-11
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/chia-network/chia-exporter
33
go 1.17
44

55
require (
6-
github.com/chia-network/go-chia-libs v0.0.3
6+
github.com/chia-network/go-chia-libs v0.0.5
77
github.com/oschwald/maxminddb-golang v1.8.0
88
github.com/prometheus/client_golang v1.12.0
99
github.com/sirupsen/logrus v1.8.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
7373
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
7474
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
7575
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
76-
github.com/chia-network/go-chia-libs v0.0.3 h1:9HsfmYUpCSdVPtYVhwc60GGZLzncMxRzs8wnXNWYSI4=
77-
github.com/chia-network/go-chia-libs v0.0.3/go.mod h1:h1y8enwmbHVylzRDd5jA9C7RZMXX82pV8/rviB7L4V8=
76+
github.com/chia-network/go-chia-libs v0.0.5 h1:a+NNZf9TT4I65EtzKeEqJgsa7OBxB902KhUYVOJ1bG4=
77+
github.com/chia-network/go-chia-libs v0.0.5/go.mod h1:h1y8enwmbHVylzRDd5jA9C7RZMXX82pV8/rviB7L4V8=
7878
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
7979
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
8080
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=

internal/metrics/farmer.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package metrics
2+
3+
import (
4+
"encoding/json"
5+
6+
"github.com/chia-network/go-chia-libs/pkg/types"
7+
"github.com/prometheus/client_golang/prometheus"
8+
log "github.com/sirupsen/logrus"
9+
10+
wrappedPrometheus "github.com/chia-network/chia-exporter/internal/prometheus"
11+
)
12+
13+
// Metrics that are based on Farmer RPC calls are in this file
14+
15+
// FarmerServiceMetrics contains all metrics related to the harvester
16+
type FarmerServiceMetrics struct {
17+
// Holds a reference to the main metrics container this is a part of
18+
metrics *Metrics
19+
20+
// Partial/Pooling Metrics
21+
submittedPartials *prometheus.CounterVec
22+
currentDifficulty *prometheus.GaugeVec
23+
pointsAckSinceStart *prometheus.GaugeVec
24+
25+
// Proof Metrics
26+
proofsFound *wrappedPrometheus.LazyCounter
27+
}
28+
29+
// InitMetrics sets all the metrics properties
30+
func (s *FarmerServiceMetrics) InitMetrics() {
31+
// Partial/Pooling Metrics, by launcher ID
32+
poolLabels := []string{"launcher_id"}
33+
s.submittedPartials = s.metrics.newCounterVec(chiaServiceFarmer, "submitted_partials", "Number of partials submitted since the exporter was started", poolLabels)
34+
s.currentDifficulty = s.metrics.newGaugeVec(chiaServiceFarmer, "current_difficulty", "Current difficulty for this launcher id", poolLabels)
35+
s.pointsAckSinceStart = s.metrics.newGaugeVec(chiaServiceFarmer, "points_acknowledged_since_start", "Points acknowledged since start. This is calculated by chia, NOT since start of the exporter.", poolLabels)
36+
37+
// Proof Metrics
38+
s.proofsFound = s.metrics.newCounter(chiaServiceFarmer, "proofs_found", "Number of proofs found since the exporter has been running")
39+
}
40+
41+
// InitialData is called on startup of the metrics server, to allow seeding metrics with current/initial data
42+
func (s *FarmerServiceMetrics) InitialData() {}
43+
44+
// Disconnected clears/unregisters metrics when the connection drops
45+
func (s *FarmerServiceMetrics) Disconnected() {}
46+
47+
// ReceiveResponse handles crawler responses that are returned over the websocket
48+
func (s *FarmerServiceMetrics) ReceiveResponse(resp *types.WebsocketResponse) {
49+
switch resp.Command {
50+
case "submitted_partial":
51+
s.SubmittedPartial(resp)
52+
case "proof":
53+
s.Proof(resp)
54+
}
55+
}
56+
57+
// SubmittedPartial handles a received submitted_partial event
58+
func (s *FarmerServiceMetrics) SubmittedPartial(resp *types.WebsocketResponse) {
59+
partial := &types.EventFarmerSubmittedPartial{}
60+
err := json.Unmarshal(resp.Data, partial)
61+
if err != nil {
62+
log.Errorf("Error unmarshalling: %s\n", err.Error())
63+
return
64+
}
65+
66+
s.submittedPartials.WithLabelValues(partial.LauncherID).Inc()
67+
s.currentDifficulty.WithLabelValues(partial.LauncherID).Set(float64(partial.CurrentDifficulty))
68+
s.pointsAckSinceStart.WithLabelValues(partial.LauncherID).Set(float64(partial.PointsAcknowledgedSinceStart))
69+
}
70+
71+
// Proof handles a received `proof` event from the farmer
72+
func (s *FarmerServiceMetrics) Proof(resp *types.WebsocketResponse) {
73+
proof := &types.EventFarmerProof{}
74+
err := json.Unmarshal(resp.Data, proof)
75+
if err != nil {
76+
log.Errorf("Error unmarshalling: %s\n", err.Error())
77+
return
78+
}
79+
80+
s.proofsFound.Inc()
81+
}

internal/metrics/fullnode.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ type FullNodeServiceMetrics struct {
4141
connectionCount *prometheus.GaugeVec
4242

4343
// Block Metrics
44-
maxBlockCost *wrappedPrometheus.LazyGauge
45-
blockCost *wrappedPrometheus.LazyGauge
46-
blockFees *wrappedPrometheus.LazyGauge
47-
kSize *prometheus.CounterVec
44+
maxBlockCost *wrappedPrometheus.LazyGauge
45+
blockCost *wrappedPrometheus.LazyGauge
46+
blockFees *wrappedPrometheus.LazyGauge
47+
kSize *prometheus.CounterVec
48+
preValidationTime *wrappedPrometheus.LazyGauge
49+
validationTime *wrappedPrometheus.LazyGauge
4850

4951
// Signage Point Metrics
5052
totalSignagePoints *wrappedPrometheus.LazyCounter
@@ -78,6 +80,8 @@ func (s *FullNodeServiceMetrics) InitMetrics() {
7880
s.blockCost = s.metrics.newGauge(chiaServiceFullNode, "block_cost", "Total cost of all transactions in the last block")
7981
s.blockFees = s.metrics.newGauge(chiaServiceFullNode, "block_fees", "Total fees in the last block")
8082
s.kSize = s.metrics.newCounterVec(chiaServiceFullNode, "k_size", "Counts of winning plot size since the exporter was last started", []string{"size"})
83+
s.preValidationTime = s.metrics.newGauge(chiaServiceFullNode, "pre_validation_time", "Last pre_validation_time from the block event")
84+
s.validationTime = s.metrics.newGauge(chiaServiceFullNode, "validation_time", "Last validation time from the block event")
8185

8286
s.totalSignagePoints = s.metrics.newCounter(chiaServiceFullNode, "total_signage_points", "Total number of signage points since the metrics exporter started. Only useful when combined with rate() or similar")
8387
s.signagePointsSubSlot = s.metrics.newGauge(chiaServiceFullNode, "signage_points_sub_slot", "Number of signage points per sub slot")
@@ -234,6 +238,8 @@ func (s *FullNodeServiceMetrics) Block(resp *types.WebsocketResponse) {
234238
}
235239

236240
s.kSize.WithLabelValues(fmt.Sprintf("%d", block.KSize)).Inc()
241+
s.preValidationTime.Set(block.PreValidationTime)
242+
s.validationTime.Set(block.ValidationTime)
237243

238244
if block.TransactionBlock {
239245
s.blockCost.Set(float64(block.BlockCost))

internal/metrics/harvester.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package metrics
2+
3+
import (
4+
"encoding/json"
5+
6+
"github.com/chia-network/go-chia-libs/pkg/types"
7+
log "github.com/sirupsen/logrus"
8+
9+
wrappedPrometheus "github.com/chia-network/chia-exporter/internal/prometheus"
10+
)
11+
12+
// Metrics that are based on Harvester RPC calls are in this file
13+
14+
// HarvesterServiceMetrics contains all metrics related to the harvester
15+
type HarvesterServiceMetrics struct {
16+
// Holds a reference to the main metrics container this is a part of
17+
metrics *Metrics
18+
19+
// Farming Info Metrics
20+
totalPlots *wrappedPrometheus.LazyGauge
21+
totalFoundProofs *wrappedPrometheus.LazyCounter
22+
lastFoundProofs *wrappedPrometheus.LazyGauge
23+
totalEligiblePlots *wrappedPrometheus.LazyCounter
24+
lastEligiblePlots *wrappedPrometheus.LazyGauge
25+
lastLookupTime *wrappedPrometheus.LazyGauge
26+
}
27+
28+
// InitMetrics sets all the metrics properties
29+
func (s *HarvesterServiceMetrics) InitMetrics() {
30+
s.totalPlots = s.metrics.newGauge(chiaServiceHarvester, "total_plots", "Total number plots on this harvester")
31+
32+
s.totalFoundProofs = s.metrics.newCounter(chiaServiceHarvester, "total_found_proofs", "Counter of total found proofs since the exporter started")
33+
s.lastFoundProofs = s.metrics.newGauge(chiaServiceHarvester, "last_found_proofs", "Number of proofs found for the last farmer_info event")
34+
35+
s.totalEligiblePlots = s.metrics.newCounter(chiaServiceHarvester, "total_eligible_plots", "Counter of total eligible plots since the exporter started")
36+
s.lastEligiblePlots = s.metrics.newGauge(chiaServiceHarvester, "last_eligible_plots", "Number of eligible plots for the last farmer_info event")
37+
38+
s.lastLookupTime = s.metrics.newGauge(chiaServiceHarvester, "last_lookup_time", "Lookup time for the last farmer_info event")
39+
}
40+
41+
// InitialData is called on startup of the metrics server, to allow seeding metrics with current/initial data
42+
func (s *HarvesterServiceMetrics) InitialData() {}
43+
44+
// Disconnected clears/unregisters metrics when the connection drops
45+
func (s *HarvesterServiceMetrics) Disconnected() {
46+
s.totalPlots.Unregister()
47+
s.lastFoundProofs.Unregister()
48+
s.lastEligiblePlots.Unregister()
49+
s.lastLookupTime.Unregister()
50+
}
51+
52+
// ReceiveResponse handles crawler responses that are returned over the websocket
53+
func (s *HarvesterServiceMetrics) ReceiveResponse(resp *types.WebsocketResponse) {
54+
switch resp.Command {
55+
case "farming_info":
56+
s.FarmingInfo(resp)
57+
}
58+
}
59+
60+
// FarmingInfo handles the farming_info event from the harvester
61+
func (s *HarvesterServiceMetrics) FarmingInfo(resp *types.WebsocketResponse) {
62+
info := &types.EventHarvesterFarmingInfo{}
63+
err := json.Unmarshal(resp.Data, info)
64+
if err != nil {
65+
log.Errorf("Error unmarshalling: %s\n", err.Error())
66+
return
67+
}
68+
69+
s.totalPlots.Set(float64(info.TotalPlots))
70+
71+
s.totalFoundProofs.Add(float64(info.FoundProofs))
72+
s.lastFoundProofs.Set(float64(info.FoundProofs))
73+
74+
s.totalEligiblePlots.Add(float64(info.EligiblePlots))
75+
s.lastEligiblePlots.Set(float64(info.EligiblePlots))
76+
77+
s.lastLookupTime.Set(info.Time)
78+
}

internal/metrics/metrics.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ import (
1717
type chiaService string
1818

1919
const (
20-
chiaServiceFullNode chiaService = "full_node"
21-
chiaServiceWallet chiaService = "wallet"
22-
chiaServiceCrawler chiaService = "crawler"
23-
chiaServiceTimelord chiaService = "timelord"
20+
chiaServiceFullNode chiaService = "full_node"
21+
chiaServiceWallet chiaService = "wallet"
22+
chiaServiceCrawler chiaService = "crawler"
23+
chiaServiceTimelord chiaService = "timelord"
24+
chiaServiceHarvester chiaService = "harvester"
25+
chiaServiceFarmer chiaService = "farmer"
2426
)
2527

2628
// serviceMetrics defines methods that must be on all metrics services
@@ -87,6 +89,8 @@ func NewMetrics(port uint16, logLevel log.Level) (*Metrics, error) {
8789
metrics.serviceMetrics[chiaServiceWallet] = &WalletServiceMetrics{metrics: metrics}
8890
metrics.serviceMetrics[chiaServiceCrawler] = &CrawlerServiceMetrics{metrics: metrics}
8991
metrics.serviceMetrics[chiaServiceTimelord] = &TimelordServiceMetrics{metrics: metrics}
92+
metrics.serviceMetrics[chiaServiceHarvester] = &HarvesterServiceMetrics{metrics: metrics}
93+
metrics.serviceMetrics[chiaServiceFarmer] = &FarmerServiceMetrics{metrics: metrics}
9094

9195
// Init each service's metrics
9296
for _, service := range metrics.serviceMetrics {
@@ -227,6 +231,10 @@ func (m *Metrics) websocketReceive(resp *types.WebsocketResponse, err error) {
227231
m.serviceMetrics[chiaServiceCrawler].ReceiveResponse(resp)
228232
case "chia_timelord":
229233
m.serviceMetrics[chiaServiceTimelord].ReceiveResponse(resp)
234+
case "chia_harvester":
235+
m.serviceMetrics[chiaServiceHarvester].ReceiveResponse(resp)
236+
case "chia_farmer":
237+
m.serviceMetrics[chiaServiceFarmer].ReceiveResponse(resp)
230238
}
231239
}
232240

0 commit comments

Comments
 (0)