github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/metrics/compliance.go (about)

     1  package metrics
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/prometheus/client_golang/prometheus"
     7  	"github.com/prometheus/client_golang/prometheus/promauto"
     8  
     9  	"github.com/onflow/flow-go/model/flow"
    10  	"github.com/onflow/flow-go/module"
    11  )
    12  
    13  type ComplianceCollector struct {
    14  	finalizedHeight                 prometheus.Gauge
    15  	sealedHeight                    prometheus.Gauge
    16  	finalizedBlocks                 prometheus.Counter
    17  	sealedBlocks                    prometheus.Counter
    18  	finalizedPayload                *prometheus.CounterVec
    19  	sealedPayload                   *prometheus.CounterVec
    20  	lastBlockFinalizedAt            time.Time
    21  	finalizedBlocksPerSecond        prometheus.Summary
    22  	lastEpochTransitionHeight       prometheus.Gauge
    23  	currentEpochCounter             prometheus.Gauge
    24  	currentEpochPhase               prometheus.Gauge
    25  	currentEpochFinalView           prometheus.Gauge
    26  	currentDKGPhase1FinalView       prometheus.Gauge
    27  	currentDKGPhase2FinalView       prometheus.Gauge
    28  	currentDKGPhase3FinalView       prometheus.Gauge
    29  	epochEmergencyFallbackTriggered prometheus.Gauge
    30  }
    31  
    32  var _ module.ComplianceMetrics = (*ComplianceCollector)(nil)
    33  
    34  func NewComplianceCollector() *ComplianceCollector {
    35  
    36  	cc := &ComplianceCollector{
    37  
    38  		currentEpochCounter: promauto.NewGauge(prometheus.GaugeOpts{
    39  			Name:      "current_epoch_counter",
    40  			Namespace: namespaceConsensus,
    41  			Subsystem: subsystemCompliance,
    42  			Help:      "the current epoch's counter",
    43  		}),
    44  
    45  		currentEpochPhase: promauto.NewGauge(prometheus.GaugeOpts{
    46  			Name:      "current_epoch_phase",
    47  			Namespace: namespaceConsensus,
    48  			Subsystem: subsystemCompliance,
    49  			Help:      "the current epoch's phase",
    50  		}),
    51  
    52  		lastEpochTransitionHeight: promauto.NewGauge(prometheus.GaugeOpts{
    53  			Name:      "last_epoch_transition_height",
    54  			Namespace: namespaceConsensus,
    55  			Subsystem: subsystemCompliance,
    56  			Help:      "the height of the most recent finalized epoch transition; in other words the height of the first block of the current epoch",
    57  		}),
    58  
    59  		currentEpochFinalView: promauto.NewGauge(prometheus.GaugeOpts{
    60  			Name:      "current_epoch_final_view",
    61  			Namespace: namespaceConsensus,
    62  			Subsystem: subsystemCompliance,
    63  			Help:      "the final view of the current epoch",
    64  		}),
    65  
    66  		currentDKGPhase1FinalView: promauto.NewGauge(prometheus.GaugeOpts{
    67  			Name:      "current_dkg_phase1_final_view",
    68  			Namespace: namespaceConsensus,
    69  			Subsystem: subsystemCompliance,
    70  			Help:      "the final view of phase 1 of the current epochs DKG",
    71  		}),
    72  		currentDKGPhase2FinalView: promauto.NewGauge(prometheus.GaugeOpts{
    73  			Name:      "current_dkg_phase2_final_view",
    74  			Namespace: namespaceConsensus,
    75  			Subsystem: subsystemCompliance,
    76  			Help:      "the final view of phase 2 of current epochs DKG",
    77  		}),
    78  
    79  		currentDKGPhase3FinalView: promauto.NewGauge(prometheus.GaugeOpts{
    80  			Name:      "current_dkg_phase3_final_view",
    81  			Namespace: namespaceConsensus,
    82  			Subsystem: subsystemCompliance,
    83  			Help:      "the final view of phase 3 of the current epochs DKG (a successful DKG will end shortly after this view)",
    84  		}),
    85  
    86  		finalizedHeight: promauto.NewGauge(prometheus.GaugeOpts{
    87  			Name:      "finalized_height",
    88  			Namespace: namespaceConsensus,
    89  			Subsystem: subsystemCompliance,
    90  			Help:      "the last finalized height",
    91  		}),
    92  
    93  		sealedHeight: promauto.NewGauge(prometheus.GaugeOpts{
    94  			Name:      "sealed_height",
    95  			Namespace: namespaceConsensus,
    96  			Subsystem: subsystemCompliance,
    97  			Help:      "the last sealed height",
    98  		}),
    99  
   100  		finalizedBlocks: promauto.NewCounter(prometheus.CounterOpts{
   101  			Name:      "finalized_blocks_total",
   102  			Namespace: namespaceConsensus,
   103  			Subsystem: subsystemCompliance,
   104  			Help:      "the number of finalized blocks",
   105  		}),
   106  
   107  		sealedBlocks: promauto.NewCounter(prometheus.CounterOpts{
   108  			Name:      "sealed_blocks_total",
   109  			Namespace: namespaceConsensus,
   110  			Subsystem: subsystemCompliance,
   111  			Help:      "the number of sealed blocks",
   112  		}),
   113  
   114  		finalizedPayload: promauto.NewCounterVec(prometheus.CounterOpts{
   115  			Name:      "finalized_payload_total",
   116  			Namespace: namespaceConsensus,
   117  			Subsystem: subsystemCompliance,
   118  			Help:      "the number of resources in finalized blocks",
   119  		}, []string{LabelResource}),
   120  
   121  		sealedPayload: promauto.NewCounterVec(prometheus.CounterOpts{
   122  			Name:      "sealed_payload_total",
   123  			Namespace: namespaceConsensus,
   124  			Subsystem: subsystemCompliance,
   125  			Help:      "the number of resources in sealed blocks",
   126  		}, []string{LabelResource}),
   127  
   128  		finalizedBlocksPerSecond: promauto.NewSummary(prometheus.SummaryOpts{
   129  			Name:      "finalized_blocks_per_second",
   130  			Namespace: namespaceConsensus,
   131  			Subsystem: subsystemCompliance,
   132  			Help:      "the number of finalized blocks per second/the finalized block rate",
   133  			Objectives: map[float64]float64{
   134  				0.01: 0.001,
   135  				0.1:  0.01,
   136  				0.5:  0.05,
   137  				0.9:  0.01,
   138  				0.99: 0.001,
   139  			},
   140  			MaxAge:     10 * time.Minute,
   141  			AgeBuckets: 5,
   142  			BufCap:     500,
   143  		}),
   144  
   145  		epochEmergencyFallbackTriggered: promauto.NewGauge(prometheus.GaugeOpts{
   146  			Name:      "epoch_fallback_triggered",
   147  			Namespace: namespaceConsensus,
   148  			Subsystem: subsystemCompliance,
   149  			Help:      "indicates whether epoch emergency fallback is triggered; if >0, the fallback is triggered",
   150  		}),
   151  	}
   152  
   153  	return cc
   154  }
   155  
   156  // FinalizedHeight sets the finalized height.
   157  func (cc *ComplianceCollector) FinalizedHeight(height uint64) {
   158  	cc.finalizedHeight.Set(float64(height))
   159  }
   160  
   161  // BlockFinalized reports metrics about finalized blocks.
   162  func (cc *ComplianceCollector) BlockFinalized(block *flow.Block) {
   163  	now := time.Now()
   164  	if !cc.lastBlockFinalizedAt.IsZero() {
   165  		cc.finalizedBlocksPerSecond.Observe(1.0 / now.Sub(cc.lastBlockFinalizedAt).Seconds())
   166  	}
   167  	cc.lastBlockFinalizedAt = now
   168  
   169  	cc.finalizedBlocks.Inc()
   170  	cc.finalizedPayload.With(prometheus.Labels{LabelResource: ResourceGuarantee}).Add(float64(len(block.Payload.Guarantees)))
   171  	cc.finalizedPayload.With(prometheus.Labels{LabelResource: ResourceSeal}).Add(float64(len(block.Payload.Seals)))
   172  }
   173  
   174  // SealedHeight sets the finalized height.
   175  func (cc *ComplianceCollector) SealedHeight(height uint64) {
   176  	cc.sealedHeight.Set(float64(height))
   177  }
   178  
   179  // BlockSealed reports metrics about sealed blocks.
   180  func (cc *ComplianceCollector) BlockSealed(block *flow.Block) {
   181  	cc.sealedBlocks.Inc()
   182  	cc.sealedPayload.With(prometheus.Labels{LabelResource: ResourceGuarantee}).Add(float64(len(block.Payload.Guarantees)))
   183  	cc.sealedPayload.With(prometheus.Labels{LabelResource: ResourceSeal}).Add(float64(len(block.Payload.Seals)))
   184  }
   185  
   186  func (cc *ComplianceCollector) EpochTransitionHeight(height uint64) {
   187  	// An epoch transition comprises a block in epoch N followed by a block in epoch N+1.
   188  	// height here refers to the height of the first block in epoch N+1.
   189  	cc.lastEpochTransitionHeight.Set(float64(height))
   190  }
   191  
   192  func (cc *ComplianceCollector) CurrentEpochCounter(counter uint64) {
   193  	cc.currentEpochCounter.Set(float64(counter))
   194  }
   195  
   196  func (cc *ComplianceCollector) CurrentEpochPhase(phase flow.EpochPhase) {
   197  	cc.currentEpochPhase.Set(float64(phase))
   198  }
   199  
   200  func (cc *ComplianceCollector) CurrentEpochFinalView(view uint64) {
   201  	cc.currentEpochFinalView.Set(float64(view))
   202  }
   203  
   204  func (cc *ComplianceCollector) CurrentDKGPhase1FinalView(view uint64) {
   205  	cc.currentDKGPhase1FinalView.Set(float64(view))
   206  }
   207  
   208  func (cc *ComplianceCollector) CurrentDKGPhase2FinalView(view uint64) {
   209  	cc.currentDKGPhase2FinalView.Set(float64(view))
   210  }
   211  
   212  func (cc *ComplianceCollector) CurrentDKGPhase3FinalView(view uint64) {
   213  	cc.currentDKGPhase3FinalView.Set(float64(view))
   214  }
   215  
   216  func (cc *ComplianceCollector) EpochEmergencyFallbackTriggered() {
   217  	cc.epochEmergencyFallbackTriggered.Set(float64(1))
   218  }