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  }