Skip to content

Commit

Permalink
Add Detailed Multi Value Metrics (#13429)
Browse files Browse the repository at this point in the history
* add it

* pingo

* gaz

* remove pingo

* fix for old forks
  • Loading branch information
nisdas authored Jan 9, 2024
1 parent 5cea6be commit 75bbeb6
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 30 deletions.
1 change: 1 addition & 0 deletions beacon-chain/blockchain/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ func reportEpochMetrics(ctx context.Context, postState, headState state.BeaconSt
for name, val := range refMap {
stateTrieReferences.WithLabelValues(name).Set(float64(val))
}
postState.RecordStateMetrics()

return nil
}
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type ReadOnlyBeaconState interface {
HistoricalSummaries() ([]*ethpb.HistoricalSummary, error)
Slashings() []uint64
FieldReferencesCount() map[string]uint64
RecordStateMetrics()
MarshalSSZ() ([]byte, error)
IsNil() bool
Version() int
Expand Down
63 changes: 33 additions & 30 deletions beacon-chain/state/state-native/multi_value_slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,34 @@ import (

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
multi_value_slice "github.com/prysmaticlabs/prysm/v4/container/multi-value-slice"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
)

var (
multiValueRandaoMixesCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
Name: "multi_value_randao_mixes_count",
})
multiValueBlockRootsCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
Name: "multi_value_block_roots_count",
})
multiValueStateRootsCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
Name: "multi_value_state_roots_count",
})
multiValueBalancesCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
Name: "multi_value_balances_count",
})
multiValueValidatorsCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
Name: "multi_value_validators_count",
})
multiValueInactivityScoresCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
Name: "multi_value_inactivity_scores_count",
})
multiValueCountGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "multi_value_object_count",
Help: "The number of instances that exist for the multivalue slice for a particular field.",
}, []string{"field"})
multiValueIndividualElementsCountGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "multi_value_individual_elements_count",
Help: "The number of individual elements that exist for the multivalue slice object.",
}, []string{"field"})
multiValueIndividualElementReferencesCountGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "multi_value_individual_element_references_count",
Help: "The number of individual element references that exist for the multivalue slice object.",
}, []string{"field"})
multiValueAppendedElementsCountGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "multi_value_appended_elements_count",
Help: "The number of appended elements that exist for the multivalue slice object.",
}, []string{"field"})
multiValueAppendedElementReferencesCountGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "multi_value_appended_element_references_count",
Help: "The number of appended element references that exist for the multivalue slice object.",
}, []string{"field"})
)

// MultiValueRandaoMixes is a multi-value slice of randao mixes.
Expand All @@ -43,7 +46,7 @@ func NewMultiValueRandaoMixes(mixes [][]byte) *MultiValueRandaoMixes {
}
mv := &MultiValueRandaoMixes{}
mv.Init(items)
multiValueRandaoMixesCountGauge.Inc()
multiValueCountGauge.WithLabelValues(types.RandaoMixes.String()).Inc()
runtime.SetFinalizer(mv, randaoMixesFinalizer)
return mv
}
Expand All @@ -59,7 +62,7 @@ func NewMultiValueBlockRoots(roots [][]byte) *MultiValueBlockRoots {
}
mv := &MultiValueBlockRoots{}
mv.Init(items)
multiValueBlockRootsCountGauge.Inc()
multiValueCountGauge.WithLabelValues(types.BlockRoots.String()).Inc()
runtime.SetFinalizer(mv, blockRootsFinalizer)
return mv
}
Expand All @@ -75,7 +78,7 @@ func NewMultiValueStateRoots(roots [][]byte) *MultiValueStateRoots {
}
mv := &MultiValueStateRoots{}
mv.Init(items)
multiValueStateRootsCountGauge.Inc()
multiValueCountGauge.WithLabelValues(types.StateRoots.String()).Inc()
runtime.SetFinalizer(mv, stateRootsFinalizer)
return mv
}
Expand All @@ -89,7 +92,7 @@ func NewMultiValueBalances(balances []uint64) *MultiValueBalances {
copy(items, balances)
mv := &MultiValueBalances{}
mv.Init(items)
multiValueBalancesCountGauge.Inc()
multiValueCountGauge.WithLabelValues(types.Balances.String()).Inc()
runtime.SetFinalizer(mv, balancesFinalizer)
return mv
}
Expand All @@ -103,7 +106,7 @@ func NewMultiValueInactivityScores(scores []uint64) *MultiValueInactivityScores
copy(items, scores)
mv := &MultiValueInactivityScores{}
mv.Init(items)
multiValueInactivityScoresCountGauge.Inc()
multiValueCountGauge.WithLabelValues(types.InactivityScores.String()).Inc()
runtime.SetFinalizer(mv, inactivityScoresFinalizer)
return mv
}
Expand All @@ -115,31 +118,31 @@ type MultiValueValidators = multi_value_slice.Slice[*ethpb.Validator]
func NewMultiValueValidators(vals []*ethpb.Validator) *MultiValueValidators {
mv := &MultiValueValidators{}
mv.Init(vals)
multiValueValidatorsCountGauge.Inc()
multiValueCountGauge.WithLabelValues(types.Validators.String()).Inc()
runtime.SetFinalizer(mv, validatorsFinalizer)
return mv
}

func randaoMixesFinalizer(m *MultiValueRandaoMixes) {
multiValueRandaoMixesCountGauge.Dec()
multiValueCountGauge.WithLabelValues(types.RandaoMixes.String()).Dec()
}

func blockRootsFinalizer(m *MultiValueBlockRoots) {
multiValueBlockRootsCountGauge.Dec()
multiValueCountGauge.WithLabelValues(types.BlockRoots.String()).Dec()
}

func stateRootsFinalizer(m *MultiValueStateRoots) {
multiValueStateRootsCountGauge.Dec()
multiValueCountGauge.WithLabelValues(types.StateRoots.String()).Dec()
}

func balancesFinalizer(m *MultiValueBalances) {
multiValueBalancesCountGauge.Dec()
multiValueCountGauge.WithLabelValues(types.Balances.String()).Dec()
}

func validatorsFinalizer(m *MultiValueValidators) {
multiValueValidatorsCountGauge.Dec()
multiValueCountGauge.WithLabelValues(types.Validators.String()).Dec()
}

func inactivityScoresFinalizer(m *MultiValueInactivityScores) {
multiValueInactivityScoresCountGauge.Dec()
multiValueCountGauge.WithLabelValues(types.InactivityScores.String()).Dec()
}
62 changes: 62 additions & 0 deletions beacon-chain/state/state-native/state_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,68 @@ func (b *BeaconState) FieldReferencesCount() map[string]uint64 {
return refMap
}

// RecordStateMetrics proceeds to record any state related metrics data.
func (b *BeaconState) RecordStateMetrics() {
b.lock.RLock()
defer b.lock.RUnlock()
// Only run this for nodes running with the experimental state.
if !features.Get().EnableExperimentalState {
return
}

// Validators
if b.validatorsMultiValue != nil {
stats := b.validatorsMultiValue.MultiValueStatistics()
multiValueIndividualElementsCountGauge.WithLabelValues(types.Validators.String()).Set(float64(stats.TotalIndividualElements))
multiValueIndividualElementReferencesCountGauge.WithLabelValues(types.Validators.String()).Set(float64(stats.TotalIndividualElemReferences))
multiValueAppendedElementsCountGauge.WithLabelValues(types.Validators.String()).Set(float64(stats.TotalAppendedElements))
multiValueAppendedElementReferencesCountGauge.WithLabelValues(types.Validators.String()).Set(float64(stats.TotalAppendedElemReferences))
}

// Balances
if b.balancesMultiValue != nil {
stats := b.balancesMultiValue.MultiValueStatistics()
multiValueIndividualElementsCountGauge.WithLabelValues(types.Balances.String()).Set(float64(stats.TotalIndividualElements))
multiValueIndividualElementReferencesCountGauge.WithLabelValues(types.Balances.String()).Set(float64(stats.TotalIndividualElemReferences))
multiValueAppendedElementsCountGauge.WithLabelValues(types.Balances.String()).Set(float64(stats.TotalAppendedElements))
multiValueAppendedElementReferencesCountGauge.WithLabelValues(types.Balances.String()).Set(float64(stats.TotalAppendedElemReferences))
}

// InactivityScores
if b.inactivityScoresMultiValue != nil {
stats := b.inactivityScoresMultiValue.MultiValueStatistics()
multiValueIndividualElementsCountGauge.WithLabelValues(types.InactivityScores.String()).Set(float64(stats.TotalIndividualElements))
multiValueIndividualElementReferencesCountGauge.WithLabelValues(types.InactivityScores.String()).Set(float64(stats.TotalIndividualElemReferences))
multiValueAppendedElementsCountGauge.WithLabelValues(types.InactivityScores.String()).Set(float64(stats.TotalAppendedElements))
multiValueAppendedElementReferencesCountGauge.WithLabelValues(types.InactivityScores.String()).Set(float64(stats.TotalAppendedElemReferences))
}
// BlockRoots
if b.blockRootsMultiValue != nil {
stats := b.blockRootsMultiValue.MultiValueStatistics()
multiValueIndividualElementsCountGauge.WithLabelValues(types.BlockRoots.String()).Set(float64(stats.TotalIndividualElements))
multiValueIndividualElementReferencesCountGauge.WithLabelValues(types.BlockRoots.String()).Set(float64(stats.TotalIndividualElemReferences))
multiValueAppendedElementsCountGauge.WithLabelValues(types.BlockRoots.String()).Set(float64(stats.TotalAppendedElements))
multiValueAppendedElementReferencesCountGauge.WithLabelValues(types.BlockRoots.String()).Set(float64(stats.TotalAppendedElemReferences))
}

// StateRoots
if b.stateRootsMultiValue != nil {
stats := b.stateRootsMultiValue.MultiValueStatistics()
multiValueIndividualElementsCountGauge.WithLabelValues(types.StateRoots.String()).Set(float64(stats.TotalIndividualElements))
multiValueIndividualElementReferencesCountGauge.WithLabelValues(types.StateRoots.String()).Set(float64(stats.TotalIndividualElemReferences))
multiValueAppendedElementsCountGauge.WithLabelValues(types.StateRoots.String()).Set(float64(stats.TotalAppendedElements))
multiValueAppendedElementReferencesCountGauge.WithLabelValues(types.StateRoots.String()).Set(float64(stats.TotalAppendedElemReferences))
}
// RandaoMixes
if b.randaoMixesMultiValue != nil {
stats := b.randaoMixesMultiValue.MultiValueStatistics()
multiValueIndividualElementsCountGauge.WithLabelValues(types.RandaoMixes.String()).Set(float64(stats.TotalIndividualElements))
multiValueIndividualElementReferencesCountGauge.WithLabelValues(types.RandaoMixes.String()).Set(float64(stats.TotalIndividualElemReferences))
multiValueAppendedElementsCountGauge.WithLabelValues(types.RandaoMixes.String()).Set(float64(stats.TotalAppendedElements))
multiValueAppendedElementReferencesCountGauge.WithLabelValues(types.RandaoMixes.String()).Set(float64(stats.TotalAppendedElemReferences))
}
}

// IsNil checks if the state and the underlying proto
// object are nil.
func (b *BeaconState) IsNil() bool {
Expand Down
38 changes: 38 additions & 0 deletions container/multi-value-slice/multi_value_slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,36 @@ func (s *Slice[V]) Detach(obj Identifiable) {
delete(s.cachedLengths, obj.Id())
}

// MultiValueStatistics generates the multi-value stats object for the respective
// multivalue slice.
func (s *Slice[V]) MultiValueStatistics() MultiValueStatistics {
s.lock.RLock()
defer s.lock.RUnlock()

stats := MultiValueStatistics{}
stats.TotalIndividualElements = len(s.individualItems)
totalIndRefs := 0

for _, v := range s.individualItems {
for _, ival := range v.Values {
totalIndRefs += len(ival.ids)
}
}

stats.TotalAppendedElements = len(s.appendedItems)
totalAppRefs := 0

for _, v := range s.appendedItems {
for _, ival := range v.Values {
totalAppRefs += len(ival.ids)
}
}
stats.TotalIndividualElemReferences = totalIndRefs
stats.TotalAppendedElemReferences = totalAppRefs

return stats
}

func (s *Slice[V]) fillOriginalItems(obj Identifiable, items *[]V) {
for i, item := range s.sharedItems {
ind, ok := s.individualItems[uint64(i)]
Expand Down Expand Up @@ -538,3 +568,11 @@ func BuildEmptyCompositeSlice[V comparable](values []V) MultiValueSliceComposite
MultiValueSlice: EmptyMVSlice[V]{fullSlice: values},
}
}

// MultiValueStatistics represents the internal properties of a multivalue slice.
type MultiValueStatistics struct {
TotalIndividualElements int
TotalAppendedElements int
TotalIndividualElemReferences int
TotalAppendedElemReferences int
}

0 comments on commit 75bbeb6

Please sign in to comment.