github.com/MetalBlockchain/subnet-evm@v0.4.9/metrics/prometheus/prometheus.go (about) 1 // (c) 2021, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package prometheus 5 6 import ( 7 "sort" 8 "strings" 9 10 "github.com/MetalBlockchain/subnet-evm/metrics" 11 12 "github.com/prometheus/client_golang/prometheus" 13 14 dto "github.com/prometheus/client_model/go" 15 ) 16 17 var ( 18 pv = []float64{.5, .75, .95, .99, .999, .9999} 19 pvShortPercent = []float64{50, 95, 99} 20 pvShort = []float64{.50, .95, .99} 21 ) 22 23 type gatherer struct { 24 reg metrics.Registry 25 } 26 27 func (g gatherer) Gather() ([]*dto.MetricFamily, error) { 28 // Gather and pre-sort the metrics to avoid random listings 29 var names []string 30 g.reg.Each(func(name string, i interface{}) { 31 names = append(names, name) 32 }) 33 sort.Strings(names) 34 35 mfs := make([]*dto.MetricFamily, 0, len(names)) 36 for _, name := range names { 37 mIntf := g.reg.Get(name) 38 name := strings.Replace(name, "/", "_", -1) 39 40 switch m := mIntf.(type) { 41 case metrics.Counter: 42 val := m.Snapshot().Count() 43 valFloat := float64(val) 44 mfs = append(mfs, &dto.MetricFamily{ 45 Name: &name, 46 Type: dto.MetricType_COUNTER.Enum(), 47 Metric: []*dto.Metric{{ 48 Counter: &dto.Counter{ 49 Value: &valFloat, 50 }, 51 }}, 52 }) 53 case metrics.Gauge: 54 val := m.Snapshot().Value() 55 valFloat := float64(val) 56 mfs = append(mfs, &dto.MetricFamily{ 57 Name: &name, 58 Type: dto.MetricType_GAUGE.Enum(), 59 Metric: []*dto.Metric{{ 60 Gauge: &dto.Gauge{ 61 Value: &valFloat, 62 }, 63 }}, 64 }) 65 case metrics.GaugeFloat64: 66 val := m.Snapshot().Value() 67 mfs = append(mfs, &dto.MetricFamily{ 68 Name: &name, 69 Type: dto.MetricType_GAUGE.Enum(), 70 Metric: []*dto.Metric{{ 71 Gauge: &dto.Gauge{ 72 Value: &val, 73 }, 74 }}, 75 }) 76 case metrics.Histogram: 77 snapshot := m.Snapshot() 78 count := snapshot.Count() 79 countUint := uint64(count) 80 sum := snapshot.Sum() 81 sumFloat := float64(sum) 82 83 ps := snapshot.Percentiles(pv) 84 qs := make([]*dto.Quantile, len(pv)) 85 for i := range ps { 86 v := pv[i] 87 s := ps[i] 88 qs[i] = &dto.Quantile{ 89 Quantile: &v, 90 Value: &s, 91 } 92 } 93 94 mfs = append(mfs, &dto.MetricFamily{ 95 Name: &name, 96 Type: dto.MetricType_SUMMARY.Enum(), 97 Metric: []*dto.Metric{{ 98 Summary: &dto.Summary{ 99 SampleCount: &countUint, 100 SampleSum: &sumFloat, 101 Quantile: qs, 102 }, 103 }}, 104 }) 105 case metrics.Meter: 106 val := m.Snapshot().Count() 107 valFloat := float64(val) 108 mfs = append(mfs, &dto.MetricFamily{ 109 Name: &name, 110 Type: dto.MetricType_GAUGE.Enum(), 111 Metric: []*dto.Metric{{ 112 Gauge: &dto.Gauge{ 113 Value: &valFloat, 114 }, 115 }}, 116 }) 117 case metrics.Timer: 118 snapshot := m.Snapshot() 119 count := snapshot.Count() 120 countUint := uint64(count) 121 sum := snapshot.Sum() 122 sumFloat := float64(sum) 123 124 ps := snapshot.Percentiles(pv) 125 qs := make([]*dto.Quantile, len(pv)) 126 for i := range ps { 127 v := pv[i] 128 s := ps[i] 129 qs[i] = &dto.Quantile{ 130 Quantile: &v, 131 Value: &s, 132 } 133 } 134 135 mfs = append(mfs, &dto.MetricFamily{ 136 Name: &name, 137 Type: dto.MetricType_SUMMARY.Enum(), 138 Metric: []*dto.Metric{{ 139 Summary: &dto.Summary{ 140 SampleCount: &countUint, 141 SampleSum: &sumFloat, 142 Quantile: qs, 143 }, 144 }}, 145 }) 146 case metrics.ResettingTimer: 147 snapshot := m.Snapshot() 148 149 vals := snapshot.Values() 150 count := uint64(len(vals)) 151 if count == 0 { 152 continue 153 } 154 155 ps := snapshot.Percentiles(pvShortPercent) 156 qs := make([]*dto.Quantile, len(pv)) 157 for i := range pvShort { 158 v := pv[i] 159 s := float64(ps[i]) 160 qs[i] = &dto.Quantile{ 161 Quantile: &v, 162 Value: &s, 163 } 164 } 165 166 mfs = append(mfs, &dto.MetricFamily{ 167 Name: &name, 168 Type: dto.MetricType_SUMMARY.Enum(), 169 Metric: []*dto.Metric{{ 170 Summary: &dto.Summary{ 171 SampleCount: &count, 172 // TODO: do we need to specify SampleSum here? and if so 173 // what should that be? 174 Quantile: qs, 175 }, 176 }}, 177 }) 178 } 179 } 180 181 return mfs, nil 182 } 183 184 func Gatherer(reg metrics.Registry) prometheus.Gatherer { 185 return gatherer{reg: reg} 186 }