github.com/ethereum-optimism/optimism@v1.7.2/op-node/metrics/metrics.go (about)

     1  // Package metrics provides a set of metrics for the op-node.
     2  package metrics
     3  
     4  import (
     5  	"context"
     6  	"net"
     7  	"strconv"
     8  	"time"
     9  
    10  	"github.com/ethereum/go-ethereum/params"
    11  
    12  	"github.com/ethereum-optimism/optimism/op-node/p2p/store"
    13  	plasma "github.com/ethereum-optimism/optimism/op-plasma"
    14  
    15  	ophttp "github.com/ethereum-optimism/optimism/op-service/httputil"
    16  	"github.com/ethereum-optimism/optimism/op-service/metrics"
    17  
    18  	pb "github.com/libp2p/go-libp2p-pubsub/pb"
    19  	libp2pmetrics "github.com/libp2p/go-libp2p/core/metrics"
    20  	"github.com/prometheus/client_golang/prometheus"
    21  	"github.com/prometheus/client_golang/prometheus/collectors"
    22  	"github.com/prometheus/client_golang/prometheus/promhttp"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  
    26  	"github.com/ethereum-optimism/optimism/op-service/eth"
    27  )
    28  
    29  const (
    30  	Namespace = "op_node"
    31  
    32  	BatchMethod = "<batch>"
    33  )
    34  
    35  type Metricer interface {
    36  	RecordInfo(version string)
    37  	RecordUp()
    38  	RecordRPCServerRequest(method string) func()
    39  	RecordRPCClientRequest(method string) func(err error)
    40  	RecordRPCClientResponse(method string, err error)
    41  	SetDerivationIdle(status bool)
    42  	RecordPipelineReset()
    43  	RecordSequencingError()
    44  	RecordPublishingError()
    45  	RecordDerivationError()
    46  	RecordReceivedUnsafePayload(payload *eth.ExecutionPayloadEnvelope)
    47  	RecordRef(layer string, name string, num uint64, timestamp uint64, h common.Hash)
    48  	RecordL1Ref(name string, ref eth.L1BlockRef)
    49  	RecordL2Ref(name string, ref eth.L2BlockRef)
    50  	RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next eth.BlockID)
    51  	RecordDerivedBatches(batchType string)
    52  	CountSequencedTxs(count int)
    53  	RecordL1ReorgDepth(d uint64)
    54  	RecordSequencerInconsistentL1Origin(from eth.BlockID, to eth.BlockID)
    55  	RecordSequencerReset()
    56  	RecordGossipEvent(evType int32)
    57  	IncPeerCount()
    58  	DecPeerCount()
    59  	IncStreamCount()
    60  	DecStreamCount()
    61  	RecordBandwidth(ctx context.Context, bwc *libp2pmetrics.BandwidthCounter)
    62  	RecordSequencerBuildingDiffTime(duration time.Duration)
    63  	RecordSequencerSealingTime(duration time.Duration)
    64  	Document() []metrics.DocumentedMetric
    65  	RecordChannelInputBytes(num int)
    66  	RecordHeadChannelOpened()
    67  	RecordChannelTimedOut()
    68  	RecordFrame()
    69  	// P2P Metrics
    70  	SetPeerScores(allScores []store.PeerScores)
    71  	ClientPayloadByNumberEvent(num uint64, resultCode byte, duration time.Duration)
    72  	ServerPayloadByNumberEvent(num uint64, resultCode byte, duration time.Duration)
    73  	PayloadsQuarantineSize(n int)
    74  	RecordPeerUnban()
    75  	RecordIPUnban()
    76  	RecordDial(allow bool)
    77  	RecordAccept(allow bool)
    78  	ReportProtocolVersions(local, engine, recommended, required params.ProtocolVersion)
    79  }
    80  
    81  // Metrics tracks all the metrics for the op-node.
    82  type Metrics struct {
    83  	Info *prometheus.GaugeVec
    84  	Up   prometheus.Gauge
    85  
    86  	metrics.RPCMetrics
    87  
    88  	L1SourceCache *metrics.CacheMetrics
    89  	L2SourceCache *metrics.CacheMetrics
    90  
    91  	DerivationIdle prometheus.Gauge
    92  
    93  	PipelineResets   *metrics.Event
    94  	UnsafePayloads   *metrics.Event
    95  	DerivationErrors *metrics.Event
    96  	SequencingErrors *metrics.Event
    97  	PublishingErrors *metrics.Event
    98  
    99  	DerivedBatches metrics.EventVec
   100  
   101  	P2PReqDurationSeconds *prometheus.HistogramVec
   102  	P2PReqTotal           *prometheus.CounterVec
   103  	P2PPayloadByNumber    *prometheus.GaugeVec
   104  
   105  	PayloadsQuarantineTotal prometheus.Gauge
   106  
   107  	SequencerInconsistentL1Origin *metrics.Event
   108  	SequencerResets               *metrics.Event
   109  
   110  	L1RequestDurationSeconds *prometheus.HistogramVec
   111  
   112  	SequencerBuildingDiffDurationSeconds prometheus.Histogram
   113  	SequencerBuildingDiffTotal           prometheus.Counter
   114  
   115  	SequencerSealingDurationSeconds prometheus.Histogram
   116  	SequencerSealingTotal           prometheus.Counter
   117  
   118  	UnsafePayloadsBufferLen     prometheus.Gauge
   119  	UnsafePayloadsBufferMemSize prometheus.Gauge
   120  
   121  	metrics.RefMetrics
   122  
   123  	L1ReorgDepth prometheus.Histogram
   124  
   125  	TransactionsSequencedTotal prometheus.Counter
   126  
   127  	PlasmaMetrics plasma.Metricer
   128  
   129  	// Channel Bank Metrics
   130  	headChannelOpenedEvent *metrics.Event
   131  	channelTimedOutEvent   *metrics.Event
   132  	frameAddedEvent        *metrics.Event
   133  
   134  	// P2P Metrics
   135  	PeerCount         prometheus.Gauge
   136  	StreamCount       prometheus.Gauge
   137  	GossipEventsTotal *prometheus.CounterVec
   138  	BandwidthTotal    *prometheus.GaugeVec
   139  	PeerUnbans        prometheus.Counter
   140  	IPUnbans          prometheus.Counter
   141  	Dials             *prometheus.CounterVec
   142  	Accepts           *prometheus.CounterVec
   143  	PeerScores        *prometheus.HistogramVec
   144  
   145  	ChannelInputBytes prometheus.Counter
   146  
   147  	// Protocol version reporting
   148  	// Delta = params.ProtocolVersionComparison
   149  	ProtocolVersionDelta *prometheus.GaugeVec
   150  	// ProtocolVersions is pseudo-metric to report the exact protocol version info
   151  	ProtocolVersions *prometheus.GaugeVec
   152  
   153  	registry *prometheus.Registry
   154  	factory  metrics.Factory
   155  }
   156  
   157  var _ Metricer = (*Metrics)(nil)
   158  
   159  // NewMetrics creates a new [Metrics] instance with the given process name.
   160  func NewMetrics(procName string) *Metrics {
   161  	if procName == "" {
   162  		procName = "default"
   163  	}
   164  	ns := Namespace + "_" + procName
   165  
   166  	registry := prometheus.NewRegistry()
   167  	registry.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
   168  	registry.MustRegister(collectors.NewGoCollector())
   169  	factory := metrics.With(registry)
   170  
   171  	return &Metrics{
   172  		Info: factory.NewGaugeVec(prometheus.GaugeOpts{
   173  			Namespace: ns,
   174  			Name:      "info",
   175  			Help:      "Pseudo-metric tracking version and config info",
   176  		}, []string{
   177  			"version",
   178  		}),
   179  		Up: factory.NewGauge(prometheus.GaugeOpts{
   180  			Namespace: ns,
   181  			Name:      "up",
   182  			Help:      "1 if the op node has finished starting up",
   183  		}),
   184  
   185  		RPCMetrics: metrics.MakeRPCMetrics(ns, factory),
   186  
   187  		L1SourceCache: metrics.NewCacheMetrics(factory, ns, "l1_source_cache", "L1 Source cache"),
   188  		L2SourceCache: metrics.NewCacheMetrics(factory, ns, "l2_source_cache", "L2 Source cache"),
   189  
   190  		DerivationIdle: factory.NewGauge(prometheus.GaugeOpts{
   191  			Namespace: ns,
   192  			Name:      "derivation_idle",
   193  			Help:      "1 if the derivation pipeline is idle",
   194  		}),
   195  
   196  		PipelineResets:   metrics.NewEvent(factory, ns, "", "pipeline_resets", "derivation pipeline resets"),
   197  		UnsafePayloads:   metrics.NewEvent(factory, ns, "", "unsafe_payloads", "unsafe payloads"),
   198  		DerivationErrors: metrics.NewEvent(factory, ns, "", "derivation_errors", "derivation errors"),
   199  		SequencingErrors: metrics.NewEvent(factory, ns, "", "sequencing_errors", "sequencing errors"),
   200  		PublishingErrors: metrics.NewEvent(factory, ns, "", "publishing_errors", "p2p publishing errors"),
   201  
   202  		DerivedBatches: metrics.NewEventVec(factory, ns, "", "derived_batches", "derived batches", []string{"type"}),
   203  
   204  		SequencerInconsistentL1Origin: metrics.NewEvent(factory, ns, "", "sequencer_inconsistent_l1_origin", "events when the sequencer selects an inconsistent L1 origin"),
   205  		SequencerResets:               metrics.NewEvent(factory, ns, "", "sequencer_resets", "sequencer resets"),
   206  
   207  		UnsafePayloadsBufferLen: factory.NewGauge(prometheus.GaugeOpts{
   208  			Namespace: ns,
   209  			Name:      "unsafe_payloads_buffer_len",
   210  			Help:      "Number of buffered L2 unsafe payloads",
   211  		}),
   212  		UnsafePayloadsBufferMemSize: factory.NewGauge(prometheus.GaugeOpts{
   213  			Namespace: ns,
   214  			Name:      "unsafe_payloads_buffer_mem_size",
   215  			Help:      "Total estimated memory size of buffered L2 unsafe payloads",
   216  		}),
   217  
   218  		RefMetrics: metrics.MakeRefMetrics(ns, factory),
   219  
   220  		L1ReorgDepth: factory.NewHistogram(prometheus.HistogramOpts{
   221  			Namespace: ns,
   222  			Name:      "l1_reorg_depth",
   223  			Buckets:   []float64{0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 20.5, 50.5, 100.5},
   224  			Help:      "Histogram of L1 Reorg Depths",
   225  		}),
   226  
   227  		TransactionsSequencedTotal: factory.NewGauge(prometheus.GaugeOpts{
   228  			Namespace: ns,
   229  			Name:      "transactions_sequenced_total",
   230  			Help:      "Count of total transactions sequenced",
   231  		}),
   232  
   233  		PeerCount: factory.NewGauge(prometheus.GaugeOpts{
   234  			Namespace: ns,
   235  			Subsystem: "p2p",
   236  			Name:      "peer_count",
   237  			Help:      "Count of currently connected p2p peers",
   238  		}),
   239  		PeerScores: factory.NewHistogramVec(prometheus.HistogramOpts{
   240  			Namespace: ns,
   241  			Name:      "peer_scores",
   242  			Help:      "Histogram of currently connected peer scores",
   243  			Buckets:   []float64{-100, -40, -20, -10, -5, -2, -1, -0.5, -0.05, 0, 0.05, 0.5, 1, 2, 5, 10, 20, 40},
   244  		}, []string{"type"}),
   245  		StreamCount: factory.NewGauge(prometheus.GaugeOpts{
   246  			Namespace: ns,
   247  			Subsystem: "p2p",
   248  			Name:      "stream_count",
   249  			Help:      "Count of currently connected p2p streams",
   250  		}),
   251  		GossipEventsTotal: factory.NewCounterVec(prometheus.CounterOpts{
   252  			Namespace: ns,
   253  			Subsystem: "p2p",
   254  			Name:      "gossip_events_total",
   255  			Help:      "Count of gossip events by type",
   256  		}, []string{
   257  			"type",
   258  		}),
   259  		BandwidthTotal: factory.NewGaugeVec(prometheus.GaugeOpts{
   260  			Namespace: ns,
   261  			Subsystem: "p2p",
   262  			Name:      "bandwidth_bytes_total",
   263  			Help:      "P2P bandwidth by direction",
   264  		}, []string{
   265  			"direction",
   266  		}),
   267  		PeerUnbans: factory.NewCounter(prometheus.CounterOpts{
   268  			Namespace: ns,
   269  			Subsystem: "p2p",
   270  			Name:      "peer_unbans",
   271  			Help:      "Count of peer unbans",
   272  		}),
   273  		IPUnbans: factory.NewCounter(prometheus.CounterOpts{
   274  			Namespace: ns,
   275  			Subsystem: "p2p",
   276  			Name:      "ip_unbans",
   277  			Help:      "Count of IP unbans",
   278  		}),
   279  		Dials: factory.NewCounterVec(prometheus.CounterOpts{
   280  			Namespace: ns,
   281  			Subsystem: "p2p",
   282  			Name:      "dials",
   283  			Help:      "Count of outgoing dial attempts, with label to filter to allowed attempts",
   284  		}, []string{"allow"}),
   285  		Accepts: factory.NewCounterVec(prometheus.CounterOpts{
   286  			Namespace: ns,
   287  			Subsystem: "p2p",
   288  			Name:      "accepts",
   289  			Help:      "Count of incoming dial attempts to accept, with label to filter to allowed attempts",
   290  		}, []string{"allow"}),
   291  
   292  		headChannelOpenedEvent: metrics.NewEvent(factory, ns, "", "head_channel", "New channel at the front of the channel bank"),
   293  		channelTimedOutEvent:   metrics.NewEvent(factory, ns, "", "channel_timeout", "Channel has timed out"),
   294  		frameAddedEvent:        metrics.NewEvent(factory, ns, "", "frame_added", "New frame ingested in the channel bank"),
   295  
   296  		ChannelInputBytes: factory.NewCounter(prometheus.CounterOpts{
   297  			Namespace: ns,
   298  			Name:      "channel_input_bytes",
   299  			Help:      "Number of compressed bytes added to the channel",
   300  		}),
   301  
   302  		P2PReqDurationSeconds: factory.NewHistogramVec(prometheus.HistogramOpts{
   303  			Namespace: ns,
   304  			Subsystem: "p2p",
   305  			Name:      "req_duration_seconds",
   306  			Buckets:   []float64{},
   307  			Help:      "Duration of P2P requests",
   308  		}, []string{
   309  			"p2p_role", // "client" or "server"
   310  			"p2p_method",
   311  			"result_code",
   312  		}),
   313  
   314  		P2PReqTotal: factory.NewCounterVec(prometheus.CounterOpts{
   315  			Namespace: ns,
   316  			Subsystem: "p2p",
   317  			Name:      "req_total",
   318  			Help:      "Number of P2P requests",
   319  		}, []string{
   320  			"p2p_role", // "client" or "server"
   321  			"p2p_method",
   322  			"result_code",
   323  		}),
   324  
   325  		P2PPayloadByNumber: factory.NewGaugeVec(prometheus.GaugeOpts{
   326  			Namespace: ns,
   327  			Subsystem: "p2p",
   328  			Name:      "payload_by_number",
   329  			Help:      "Payload by number requests",
   330  		}, []string{
   331  			"p2p_role", // "client" or "server"
   332  		}),
   333  		PayloadsQuarantineTotal: factory.NewGauge(prometheus.GaugeOpts{
   334  			Namespace: ns,
   335  			Subsystem: "p2p",
   336  			Name:      "payloads_quarantine_total",
   337  			Help:      "number of unverified execution payloads buffered in quarantine",
   338  		}),
   339  
   340  		L1RequestDurationSeconds: factory.NewHistogramVec(prometheus.HistogramOpts{
   341  			Namespace: ns,
   342  			Name:      "l1_request_seconds",
   343  			Buckets: []float64{
   344  				.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10},
   345  			Help: "Histogram of L1 request time",
   346  		}, []string{"request"}),
   347  
   348  		SequencerBuildingDiffDurationSeconds: factory.NewHistogram(prometheus.HistogramOpts{
   349  			Namespace: ns,
   350  			Name:      "sequencer_building_diff_seconds",
   351  			Buckets: []float64{
   352  				-10, -5, -2.5, -1, -.5, -.25, -.1, -0.05, -0.025, -0.01, -0.005,
   353  				.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10},
   354  			Help: "Histogram of Sequencer building time, minus block time",
   355  		}),
   356  		SequencerBuildingDiffTotal: factory.NewCounter(prometheus.CounterOpts{
   357  			Namespace: ns,
   358  			Name:      "sequencer_building_diff_total",
   359  			Help:      "Number of sequencer block building jobs",
   360  		}),
   361  		SequencerSealingDurationSeconds: factory.NewHistogram(prometheus.HistogramOpts{
   362  			Namespace: ns,
   363  			Name:      "sequencer_sealing_seconds",
   364  			Buckets:   []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10},
   365  			Help:      "Histogram of Sequencer block sealing time",
   366  		}),
   367  		SequencerSealingTotal: factory.NewCounter(prometheus.CounterOpts{
   368  			Namespace: ns,
   369  			Name:      "sequencer_sealing_total",
   370  			Help:      "Number of sequencer block sealing jobs",
   371  		}),
   372  
   373  		ProtocolVersionDelta: factory.NewGaugeVec(prometheus.GaugeOpts{
   374  			Namespace: ns,
   375  			Name:      "protocol_version_delta",
   376  			Help:      "Difference between local and global protocol version, and execution-engine, per type of version",
   377  		}, []string{
   378  			"type",
   379  		}),
   380  		ProtocolVersions: factory.NewGaugeVec(prometheus.GaugeOpts{
   381  			Namespace: ns,
   382  			Name:      "protocol_versions",
   383  			Help:      "Pseudo-metric tracking recommended and required protocol version info",
   384  		}, []string{
   385  			"local",
   386  			"engine",
   387  			"recommended",
   388  			"required",
   389  		}),
   390  
   391  		PlasmaMetrics: plasma.MakeMetrics(ns, factory),
   392  
   393  		registry: registry,
   394  		factory:  factory,
   395  	}
   396  }
   397  
   398  // SetPeerScores updates the peer score metrics.
   399  // Accepts a slice of peer scores in any order.
   400  func (m *Metrics) SetPeerScores(allScores []store.PeerScores) {
   401  	for _, scores := range allScores {
   402  		m.PeerScores.WithLabelValues("total").Observe(scores.Gossip.Total)
   403  		m.PeerScores.WithLabelValues("ipColocation").Observe(scores.Gossip.IPColocationFactor)
   404  		m.PeerScores.WithLabelValues("behavioralPenalty").Observe(scores.Gossip.BehavioralPenalty)
   405  		m.PeerScores.WithLabelValues("blocksFirstMessage").Observe(scores.Gossip.Blocks.FirstMessageDeliveries)
   406  		m.PeerScores.WithLabelValues("blocksTimeInMesh").Observe(scores.Gossip.Blocks.TimeInMesh)
   407  		m.PeerScores.WithLabelValues("blocksMessageDeliveries").Observe(scores.Gossip.Blocks.MeshMessageDeliveries)
   408  		m.PeerScores.WithLabelValues("blocksInvalidMessageDeliveries").Observe(scores.Gossip.Blocks.InvalidMessageDeliveries)
   409  
   410  		m.PeerScores.WithLabelValues("reqRespValidResponses").Observe(scores.ReqResp.ValidResponses)
   411  		m.PeerScores.WithLabelValues("reqRespErrorResponses").Observe(scores.ReqResp.ErrorResponses)
   412  		m.PeerScores.WithLabelValues("reqRespRejectedPayloads").Observe(scores.ReqResp.RejectedPayloads)
   413  	}
   414  }
   415  
   416  // RecordInfo sets a pseudo-metric that contains versioning and
   417  // config info for the opnode.
   418  func (m *Metrics) RecordInfo(version string) {
   419  	m.Info.WithLabelValues(version).Set(1)
   420  }
   421  
   422  // RecordUp sets the up metric to 1.
   423  func (m *Metrics) RecordUp() {
   424  	prometheus.MustRegister()
   425  	m.Up.Set(1)
   426  }
   427  
   428  func (m *Metrics) SetDerivationIdle(status bool) {
   429  	var val float64
   430  	if status {
   431  		val = 1
   432  	}
   433  	m.DerivationIdle.Set(val)
   434  }
   435  
   436  func (m *Metrics) RecordPipelineReset() {
   437  	m.PipelineResets.Record()
   438  }
   439  
   440  func (m *Metrics) RecordSequencingError() {
   441  	m.SequencingErrors.Record()
   442  }
   443  
   444  func (m *Metrics) RecordPublishingError() {
   445  	m.PublishingErrors.Record()
   446  }
   447  
   448  func (m *Metrics) RecordDerivationError() {
   449  	m.DerivationErrors.Record()
   450  }
   451  
   452  func (m *Metrics) RecordReceivedUnsafePayload(payload *eth.ExecutionPayloadEnvelope) {
   453  	m.UnsafePayloads.Record()
   454  	m.RecordRef("l2", "received_payload", uint64(payload.ExecutionPayload.BlockNumber), uint64(payload.ExecutionPayload.Timestamp), payload.ExecutionPayload.BlockHash)
   455  }
   456  
   457  func (m *Metrics) RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next eth.BlockID) {
   458  	m.RecordRef("l2", "l2_buffer_unsafe", next.Number, 0, next.Hash)
   459  	m.UnsafePayloadsBufferLen.Set(float64(length))
   460  	m.UnsafePayloadsBufferMemSize.Set(float64(memSize))
   461  }
   462  
   463  func (m *Metrics) RecordDerivedBatches(batchType string) {
   464  	m.DerivedBatches.Record(batchType)
   465  }
   466  
   467  func (m *Metrics) CountSequencedTxs(count int) {
   468  	m.TransactionsSequencedTotal.Add(float64(count))
   469  }
   470  
   471  func (m *Metrics) RecordL1ReorgDepth(d uint64) {
   472  	m.L1ReorgDepth.Observe(float64(d))
   473  }
   474  
   475  func (m *Metrics) RecordSequencerInconsistentL1Origin(from eth.BlockID, to eth.BlockID) {
   476  	m.SequencerInconsistentL1Origin.Record()
   477  	m.RecordRef("l1_origin", "inconsistent_from", from.Number, 0, from.Hash)
   478  	m.RecordRef("l1_origin", "inconsistent_to", to.Number, 0, to.Hash)
   479  }
   480  
   481  func (m *Metrics) RecordSequencerReset() {
   482  	m.SequencerResets.Record()
   483  }
   484  
   485  func (m *Metrics) RecordGossipEvent(evType int32) {
   486  	m.GossipEventsTotal.WithLabelValues(pb.TraceEvent_Type_name[evType]).Inc()
   487  }
   488  
   489  func (m *Metrics) IncPeerCount() {
   490  	m.PeerCount.Inc()
   491  }
   492  
   493  func (m *Metrics) DecPeerCount() {
   494  	m.PeerCount.Dec()
   495  }
   496  
   497  func (m *Metrics) IncStreamCount() {
   498  	m.StreamCount.Inc()
   499  }
   500  
   501  func (m *Metrics) DecStreamCount() {
   502  	m.StreamCount.Dec()
   503  }
   504  
   505  func (m *Metrics) RecordBandwidth(ctx context.Context, bwc *libp2pmetrics.BandwidthCounter) {
   506  	tick := time.NewTicker(10 * time.Second)
   507  	defer tick.Stop()
   508  
   509  	for {
   510  		select {
   511  		case <-tick.C:
   512  			bwTotals := bwc.GetBandwidthTotals()
   513  			m.BandwidthTotal.WithLabelValues("in").Set(float64(bwTotals.TotalIn))
   514  			m.BandwidthTotal.WithLabelValues("out").Set(float64(bwTotals.TotalOut))
   515  		case <-ctx.Done():
   516  			return
   517  		}
   518  	}
   519  }
   520  
   521  // RecordL1RequestTime tracks the amount of time the derivation pipeline spent waiting for L1 data requests.
   522  func (m *Metrics) RecordL1RequestTime(method string, duration time.Duration) {
   523  	m.L1RequestDurationSeconds.WithLabelValues(method).Observe(float64(duration) / float64(time.Second))
   524  }
   525  
   526  // RecordSequencerBuildingDiffTime tracks the amount of time the sequencer was allowed between
   527  // start to finish, incl. sealing, minus the block time.
   528  // Ideally this is 0, realistically the sequencer scheduler may be busy with other jobs like syncing sometimes.
   529  func (m *Metrics) RecordSequencerBuildingDiffTime(duration time.Duration) {
   530  	m.SequencerBuildingDiffTotal.Inc()
   531  	m.SequencerBuildingDiffDurationSeconds.Observe(float64(duration) / float64(time.Second))
   532  }
   533  
   534  // RecordSequencerSealingTime tracks the amount of time the sequencer took to finish sealing the block.
   535  // Ideally this is 0, realistically it may take some time.
   536  func (m *Metrics) RecordSequencerSealingTime(duration time.Duration) {
   537  	m.SequencerSealingTotal.Inc()
   538  	m.SequencerSealingDurationSeconds.Observe(float64(duration) / float64(time.Second))
   539  }
   540  
   541  // StartServer starts the metrics server on the given hostname and port.
   542  func (m *Metrics) StartServer(hostname string, port int) (*ophttp.HTTPServer, error) {
   543  	addr := net.JoinHostPort(hostname, strconv.Itoa(port))
   544  	h := promhttp.InstrumentMetricHandler(
   545  		m.registry, promhttp.HandlerFor(m.registry, promhttp.HandlerOpts{}),
   546  	)
   547  	return ophttp.StartHTTPServer(addr, h)
   548  }
   549  
   550  func (m *Metrics) Document() []metrics.DocumentedMetric {
   551  	return m.factory.Document()
   552  }
   553  
   554  func (m *Metrics) ClientPayloadByNumberEvent(num uint64, resultCode byte, duration time.Duration) {
   555  	if resultCode > 4 { // summarize all high codes to reduce metrics overhead
   556  		resultCode = 5
   557  	}
   558  	code := strconv.FormatUint(uint64(resultCode), 10)
   559  	m.P2PReqTotal.WithLabelValues("client", "payload_by_number", code).Inc()
   560  	m.P2PReqDurationSeconds.WithLabelValues("client", "payload_by_number", code).Observe(float64(duration) / float64(time.Second))
   561  	m.P2PPayloadByNumber.WithLabelValues("client").Set(float64(num))
   562  }
   563  
   564  func (m *Metrics) ServerPayloadByNumberEvent(num uint64, resultCode byte, duration time.Duration) {
   565  	code := strconv.FormatUint(uint64(resultCode), 10)
   566  	m.P2PReqTotal.WithLabelValues("server", "payload_by_number", code).Inc()
   567  	m.P2PReqDurationSeconds.WithLabelValues("server", "payload_by_number", code).Observe(float64(duration) / float64(time.Second))
   568  	m.P2PPayloadByNumber.WithLabelValues("server").Set(float64(num))
   569  }
   570  
   571  func (m *Metrics) PayloadsQuarantineSize(n int) {
   572  	m.PayloadsQuarantineTotal.Set(float64(n))
   573  }
   574  
   575  func (m *Metrics) RecordChannelInputBytes(inputCompressedBytes int) {
   576  	m.ChannelInputBytes.Add(float64(inputCompressedBytes))
   577  }
   578  
   579  func (m *Metrics) RecordHeadChannelOpened() {
   580  	m.headChannelOpenedEvent.Record()
   581  }
   582  
   583  func (m *Metrics) RecordChannelTimedOut() {
   584  	m.channelTimedOutEvent.Record()
   585  }
   586  
   587  func (m *Metrics) RecordFrame() {
   588  	m.frameAddedEvent.Record()
   589  }
   590  
   591  func (m *Metrics) RecordPeerUnban() {
   592  	m.PeerUnbans.Inc()
   593  }
   594  
   595  func (m *Metrics) RecordIPUnban() {
   596  	m.IPUnbans.Inc()
   597  }
   598  
   599  func (m *Metrics) RecordDial(allow bool) {
   600  	if allow {
   601  		m.Dials.WithLabelValues("true").Inc()
   602  	} else {
   603  		m.Dials.WithLabelValues("false").Inc()
   604  	}
   605  }
   606  
   607  func (m *Metrics) RecordAccept(allow bool) {
   608  	if allow {
   609  		m.Accepts.WithLabelValues("true").Inc()
   610  	} else {
   611  		m.Accepts.WithLabelValues("false").Inc()
   612  	}
   613  }
   614  func (m *Metrics) ReportProtocolVersions(local, engine, recommended, required params.ProtocolVersion) {
   615  	m.ProtocolVersionDelta.WithLabelValues("local_recommended").Set(float64(local.Compare(recommended)))
   616  	m.ProtocolVersionDelta.WithLabelValues("local_required").Set(float64(local.Compare(required)))
   617  	m.ProtocolVersionDelta.WithLabelValues("engine_recommended").Set(float64(engine.Compare(recommended)))
   618  	m.ProtocolVersionDelta.WithLabelValues("engine_required").Set(float64(engine.Compare(required)))
   619  	m.ProtocolVersions.WithLabelValues(local.String(), engine.String(), recommended.String(), required.String()).Set(1)
   620  }
   621  
   622  type noopMetricer struct {
   623  	metrics.NoopRPCMetrics
   624  }
   625  
   626  var NoopMetrics Metricer = new(noopMetricer)
   627  
   628  func (n *noopMetricer) RecordInfo(version string) {
   629  }
   630  
   631  func (n *noopMetricer) RecordUp() {
   632  }
   633  
   634  func (n *noopMetricer) SetDerivationIdle(status bool) {
   635  }
   636  
   637  func (n *noopMetricer) RecordPipelineReset() {
   638  }
   639  
   640  func (n *noopMetricer) RecordSequencingError() {
   641  }
   642  
   643  func (n *noopMetricer) RecordPublishingError() {
   644  }
   645  
   646  func (n *noopMetricer) RecordDerivationError() {
   647  }
   648  
   649  func (n *noopMetricer) RecordReceivedUnsafePayload(payload *eth.ExecutionPayloadEnvelope) {
   650  }
   651  
   652  func (n *noopMetricer) RecordRef(layer string, name string, num uint64, timestamp uint64, h common.Hash) {
   653  }
   654  
   655  func (n *noopMetricer) RecordL1Ref(name string, ref eth.L1BlockRef) {
   656  }
   657  
   658  func (n *noopMetricer) RecordL2Ref(name string, ref eth.L2BlockRef) {
   659  }
   660  
   661  func (n *noopMetricer) RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next eth.BlockID) {
   662  }
   663  
   664  func (n *noopMetricer) RecordDerivedBatches(batchType string) {
   665  }
   666  
   667  func (n *noopMetricer) CountSequencedTxs(count int) {
   668  }
   669  
   670  func (n *noopMetricer) RecordL1ReorgDepth(d uint64) {
   671  }
   672  
   673  func (n *noopMetricer) RecordSequencerInconsistentL1Origin(from eth.BlockID, to eth.BlockID) {
   674  }
   675  
   676  func (n *noopMetricer) RecordSequencerReset() {
   677  }
   678  
   679  func (n *noopMetricer) RecordGossipEvent(evType int32) {
   680  }
   681  
   682  func (n *noopMetricer) SetPeerScores(allScores []store.PeerScores) {
   683  }
   684  
   685  func (n *noopMetricer) IncPeerCount() {
   686  }
   687  
   688  func (n *noopMetricer) DecPeerCount() {
   689  }
   690  
   691  func (n *noopMetricer) IncStreamCount() {
   692  }
   693  
   694  func (n *noopMetricer) DecStreamCount() {
   695  }
   696  
   697  func (n *noopMetricer) RecordBandwidth(ctx context.Context, bwc *libp2pmetrics.BandwidthCounter) {
   698  }
   699  
   700  func (n *noopMetricer) RecordSequencerBuildingDiffTime(duration time.Duration) {
   701  }
   702  
   703  func (n *noopMetricer) RecordSequencerSealingTime(duration time.Duration) {
   704  }
   705  
   706  func (n *noopMetricer) Document() []metrics.DocumentedMetric {
   707  	return nil
   708  }
   709  
   710  func (n *noopMetricer) ClientPayloadByNumberEvent(num uint64, resultCode byte, duration time.Duration) {
   711  }
   712  
   713  func (n *noopMetricer) ServerPayloadByNumberEvent(num uint64, resultCode byte, duration time.Duration) {
   714  }
   715  
   716  func (n *noopMetricer) PayloadsQuarantineSize(int) {
   717  }
   718  
   719  func (n *noopMetricer) RecordChannelInputBytes(int) {
   720  }
   721  
   722  func (n *noopMetricer) RecordHeadChannelOpened() {
   723  }
   724  
   725  func (n *noopMetricer) RecordChannelTimedOut() {
   726  }
   727  
   728  func (n *noopMetricer) RecordFrame() {
   729  }
   730  
   731  func (n *noopMetricer) RecordPeerUnban() {
   732  }
   733  
   734  func (n *noopMetricer) RecordIPUnban() {
   735  }
   736  
   737  func (n *noopMetricer) RecordDial(allow bool) {
   738  }
   739  
   740  func (n *noopMetricer) RecordAccept(allow bool) {
   741  }
   742  func (n *noopMetricer) ReportProtocolVersions(local, engine, recommended, required params.ProtocolVersion) {
   743  }