Repository navigation
Expand file tree
/
Copy pathmetrics_chainselection.go
More file actions
112 lines (105 loc) · 4.25 KB
/
Copy pathmetrics_chainselection.go
File metadata and controls
112 lines (105 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Copyright 2026 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dingo
import (
"github.com/blinklabs-io/dingo/chainselection"
"github.com/blinklabs-io/dingo/internal/promutil"
"github.com/prometheus/client_golang/prometheus"
)
// Reasons reported by dingo_chainselection_stalled_total.
const (
// chainSelectionStallNoSelectablePeer is the ordinary stall: no tracked
// peer passed the selectability checks.
chainSelectionStallNoSelectablePeer = "no_selectable_peer"
// chainSelectionStallGenesisCorroboration is a stall caused by the Genesis
// corroboration gate denying the densest fast source.
chainSelectionStallGenesisCorroboration = "genesis_corroboration"
)
// chainSelectionMetrics counts chain-selection transitions that are otherwise
// only visible in the log: how often selection stalled with no selectable peer,
// and how often a peer was (re)registered from a chainsync rollback, which is
// the post-recycle path that keeps a stall from lasting until the next block.
type chainSelectionMetrics struct {
stalls *prometheus.CounterVec
rollbackRegistrations *prometheus.CounterVec
}
// registerChainSelectionMetrics registers the chain-selection counters. It runs
// in New(), against the pre-wrap registerer, because these counters live for
// the node's entire lifetime: the ChainSelector is not rebuilt by a live
// database restore/truncate, so they must not be unregistered by
// rebuildableRegisterer.unregisterAll (see metrics_registerer.go).
//
// Every label value is materialized here so a scrape reports an explicit 0
// instead of a missing series before the first occurrence -- a stall counter
// that only appears once the node has stalled is useless for alerting.
func (n *Node) registerChainSelectionMetrics(r *promutil.Registration) {
if n.config.promRegistry == nil {
return
}
metrics := &chainSelectionMetrics{
stalls: promutil.Register(r, prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "dingo_chainselection_stalled_total",
Help: "times chain selection transitioned to having no selectable peer",
},
[]string{"reason"},
)),
rollbackRegistrations: promutil.Register(r, prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "dingo_chainselection_rollback_registrations_total",
Help: "attempts to register a peer into chain selection from a chainsync rollback on an untracked connection, by outcome",
},
[]string{"outcome"},
)),
}
for _, reason := range []string{
chainSelectionStallNoSelectablePeer,
chainSelectionStallGenesisCorroboration,
} {
metrics.stalls.WithLabelValues(reason)
}
for _, outcome := range []chainselection.RollbackRegistrationOutcome{
chainselection.RollbackRegistrationRegistered,
chainselection.RollbackRegistrationClosedConnection,
chainselection.RollbackRegistrationImplausibleTip,
chainselection.RollbackRegistrationAtCapacity,
} {
metrics.rollbackRegistrations.WithLabelValues(string(outcome))
}
n.chainSelectionMetrics = metrics
}
// recordChainSelectionStall counts one selected-to-none transition. Safe to
// call when metrics are disabled.
func (n *Node) recordChainSelectionStall(genesisCorroboration bool) {
if n.chainSelectionMetrics == nil {
return
}
reason := chainSelectionStallNoSelectablePeer
if genesisCorroboration {
reason = chainSelectionStallGenesisCorroboration
}
n.chainSelectionMetrics.stalls.WithLabelValues(reason).Inc()
}
// recordRollbackRegistration counts one attempt to register a peer from a
// chainsync rollback. Safe to call when metrics are disabled.
func (n *Node) recordRollbackRegistration(
outcome chainselection.RollbackRegistrationOutcome,
) {
if n.chainSelectionMetrics == nil {
return
}
n.chainSelectionMetrics.rollbackRegistrations.
WithLabelValues(string(outcome)).
Inc()
}