github.com/MetalBlockchain/subnet-evm@v0.6.3/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.CounterFloat64:
    54  			val := m.Snapshot().Count()
    55  			mfs = append(mfs, &dto.MetricFamily{
    56  				Name: &name,
    57  				Type: dto.MetricType_COUNTER.Enum(),
    58  				Metric: []*dto.Metric{{
    59  					Counter: &dto.Counter{
    60  						Value: &val,
    61  					},
    62  				}},
    63  			})
    64  		case metrics.Gauge:
    65  			val := m.Snapshot().Value()
    66  			valFloat := float64(val)
    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: &valFloat,
    73  					},
    74  				}},
    75  			})
    76  		case metrics.GaugeFloat64:
    77  			val := m.Snapshot().Value()
    78  			mfs = append(mfs, &dto.MetricFamily{
    79  				Name: &name,
    80  				Type: dto.MetricType_GAUGE.Enum(),
    81  				Metric: []*dto.Metric{{
    82  					Gauge: &dto.Gauge{
    83  						Value: &val,
    84  					},
    85  				}},
    86  			})
    87  		case metrics.Histogram:
    88  			snapshot := m.Snapshot()
    89  			count := snapshot.Count()
    90  			countUint := uint64(count)
    91  			sum := snapshot.Sum()
    92  			sumFloat := float64(sum)
    93  
    94  			ps := snapshot.Percentiles(pv)
    95  			qs := make([]*dto.Quantile, len(pv))
    96  			for i := range ps {
    97  				v := pv[i]
    98  				s := ps[i]
    99  				qs[i] = &dto.Quantile{
   100  					Quantile: &v,
   101  					Value:    &s,
   102  				}
   103  			}
   104  
   105  			mfs = append(mfs, &dto.MetricFamily{
   106  				Name: &name,
   107  				Type: dto.MetricType_SUMMARY.Enum(),
   108  				Metric: []*dto.Metric{{
   109  					Summary: &dto.Summary{
   110  						SampleCount: &countUint,
   111  						SampleSum:   &sumFloat,
   112  						Quantile:    qs,
   113  					},
   114  				}},
   115  			})
   116  		case metrics.Meter:
   117  			val := m.Snapshot().Count()
   118  			valFloat := float64(val)
   119  			mfs = append(mfs, &dto.MetricFamily{
   120  				Name: &name,
   121  				Type: dto.MetricType_GAUGE.Enum(),
   122  				Metric: []*dto.Metric{{
   123  					Gauge: &dto.Gauge{
   124  						Value: &valFloat,
   125  					},
   126  				}},
   127  			})
   128  		case metrics.Timer:
   129  			snapshot := m.Snapshot()
   130  			count := snapshot.Count()
   131  			countUint := uint64(count)
   132  			sum := snapshot.Sum()
   133  			sumFloat := float64(sum)
   134  
   135  			ps := snapshot.Percentiles(pv)
   136  			qs := make([]*dto.Quantile, len(pv))
   137  			for i := range ps {
   138  				v := pv[i]
   139  				s := ps[i]
   140  				qs[i] = &dto.Quantile{
   141  					Quantile: &v,
   142  					Value:    &s,
   143  				}
   144  			}
   145  
   146  			mfs = append(mfs, &dto.MetricFamily{
   147  				Name: &name,
   148  				Type: dto.MetricType_SUMMARY.Enum(),
   149  				Metric: []*dto.Metric{{
   150  					Summary: &dto.Summary{
   151  						SampleCount: &countUint,
   152  						SampleSum:   &sumFloat,
   153  						Quantile:    qs,
   154  					},
   155  				}},
   156  			})
   157  		case metrics.ResettingTimer:
   158  			snapshot := m.Snapshot()
   159  
   160  			vals := snapshot.Values()
   161  			count := uint64(len(vals))
   162  			if count == 0 {
   163  				continue
   164  			}
   165  
   166  			ps := snapshot.Percentiles(pvShortPercent)
   167  			qs := make([]*dto.Quantile, len(pv))
   168  			for i := range pvShort {
   169  				v := pv[i]
   170  				s := float64(ps[i])
   171  				qs[i] = &dto.Quantile{
   172  					Quantile: &v,
   173  					Value:    &s,
   174  				}
   175  			}
   176  
   177  			mfs = append(mfs, &dto.MetricFamily{
   178  				Name: &name,
   179  				Type: dto.MetricType_SUMMARY.Enum(),
   180  				Metric: []*dto.Metric{{
   181  					Summary: &dto.Summary{
   182  						SampleCount: &count,
   183  						// TODO: do we need to specify SampleSum here? and if so
   184  						// what should that be?
   185  						Quantile: qs,
   186  					},
   187  				}},
   188  			})
   189  		}
   190  	}
   191  
   192  	return mfs, nil
   193  }
   194  
   195  func Gatherer(reg metrics.Registry) prometheus.Gatherer {
   196  	return gatherer{reg: reg}
   197  }