metrics.go 4.43 KB
Newer Older
1 2 3
package metrics

import (
4
	"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
5 6 7 8 9 10 11 12 13 14 15 16 17
	"github.com/prometheus/client_golang/prometheus"

	opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
)

const Namespace = "op_supervisor"

type Metricer interface {
	RecordInfo(version string)
	RecordUp()

	opmetrics.RPCMetricer

18 19
	CacheAdd(chainID types.ChainID, label string, cacheSize int, evicted bool)
	CacheGet(chainID types.ChainID, label string, hit bool)
20

21 22
	RecordDBEntryCount(chainID types.ChainID, count int64)
	RecordDBSearchEntriesRead(chainID types.ChainID, count int64)
23

24 25 26 27 28 29 30 31 32 33
	Document() []opmetrics.DocumentedMetric
}

type Metrics struct {
	ns       string
	registry *prometheus.Registry
	factory  opmetrics.Factory

	opmetrics.RPCMetrics

34 35 36 37 38 39
	CacheSizeVec *prometheus.GaugeVec
	CacheGetVec  *prometheus.CounterVec
	CacheAddVec  *prometheus.CounterVec

	DBEntryCountVec        *prometheus.GaugeVec
	DBSearchEntriesReadVec *prometheus.HistogramVec
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
	info prometheus.GaugeVec
	up   prometheus.Gauge
}

var _ Metricer = (*Metrics)(nil)

// implements the Registry getter, for metrics HTTP server to hook into
var _ opmetrics.RegistryMetricer = (*Metrics)(nil)

func NewMetrics(procName string) *Metrics {
	if procName == "" {
		procName = "default"
	}
	ns := Namespace + "_" + procName

	registry := opmetrics.NewRegistry()
	factory := opmetrics.With(registry)

	return &Metrics{
		ns:       ns,
		registry: registry,
		factory:  factory,

		RPCMetrics: opmetrics.MakeRPCMetrics(ns, factory),

		info: *factory.NewGaugeVec(prometheus.GaugeOpts{
			Namespace: ns,
			Name:      "info",
			Help:      "Pseudo-metric tracking version and config info",
		}, []string{
			"version",
		}),
		up: factory.NewGauge(prometheus.GaugeOpts{
			Namespace: ns,
			Name:      "up",
			Help:      "1 if the op-supervisor has finished starting up",
		}),
78

79
		CacheSizeVec: factory.NewGaugeVec(prometheus.GaugeOpts{
80 81
			Namespace: ns,
			Name:      "source_rpc_cache_size",
82
			Help:      "Source rpc cache cache size",
83 84 85 86
		}, []string{
			"chain",
			"type",
		}),
87
		CacheGetVec: factory.NewCounterVec(prometheus.CounterOpts{
88 89
			Namespace: ns,
			Name:      "source_rpc_cache_get",
90
			Help:      "Source rpc cache lookups, hitting or not",
91 92 93 94 95
		}, []string{
			"chain",
			"type",
			"hit",
		}),
96
		CacheAddVec: factory.NewCounterVec(prometheus.CounterOpts{
97 98
			Namespace: ns,
			Name:      "source_rpc_cache_add",
99
			Help:      "Source rpc cache additions, evicting previous values or not",
100 101 102 103 104
		}, []string{
			"chain",
			"type",
			"evicted",
		}),
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

		DBEntryCountVec: factory.NewGaugeVec(prometheus.GaugeOpts{
			Namespace: ns,
			Name:      "logdb_entries_current",
			Help:      "Current number of entries in the log database by chain ID",
		}, []string{
			"chain",
		}),
		DBSearchEntriesReadVec: factory.NewHistogramVec(prometheus.HistogramOpts{
			Namespace: ns,
			Name:      "logdb_search_entries_read",
			Help:      "Entries read per search of the log database",
			Buckets:   []float64{1, 2, 5, 10, 100, 200, 256},
		}, []string{
			"chain",
		}),
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
	}
}

func (m *Metrics) Registry() *prometheus.Registry {
	return m.registry
}

func (m *Metrics) Document() []opmetrics.DocumentedMetric {
	return m.factory.Document()
}

// RecordInfo sets a pseudo-metric that contains versioning and config info for the op-supervisor.
func (m *Metrics) RecordInfo(version string) {
	m.info.WithLabelValues(version).Set(1)
}

// RecordUp sets the up metric to 1.
func (m *Metrics) RecordUp() {
	prometheus.MustRegister()
	m.up.Set(1)
}
142

143
func (m *Metrics) CacheAdd(chainID types.ChainID, label string, cacheSize int, evicted bool) {
144 145
	chain := chainIDLabel(chainID)
	m.CacheSizeVec.WithLabelValues(chain, label).Set(float64(cacheSize))
146
	if evicted {
147
		m.CacheAddVec.WithLabelValues(chain, label, "true").Inc()
148
	} else {
149
		m.CacheAddVec.WithLabelValues(chain, label, "false").Inc()
150 151 152
	}
}

153
func (m *Metrics) CacheGet(chainID types.ChainID, label string, hit bool) {
154
	chain := chainIDLabel(chainID)
155
	if hit {
156
		m.CacheGetVec.WithLabelValues(chain, label, "true").Inc()
157
	} else {
158
		m.CacheGetVec.WithLabelValues(chain, label, "false").Inc()
159 160
	}
}
161

162
func (m *Metrics) RecordDBEntryCount(chainID types.ChainID, count int64) {
163 164 165
	m.DBEntryCountVec.WithLabelValues(chainIDLabel(chainID)).Set(float64(count))
}

166
func (m *Metrics) RecordDBSearchEntriesRead(chainID types.ChainID, count int64) {
167 168 169
	m.DBSearchEntriesReadVec.WithLabelValues(chainIDLabel(chainID)).Observe(float64(count))
}

170 171
func chainIDLabel(chainID types.ChainID) string {
	return chainID.String()
172
}