github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/monitoring/prometheus/apdapter.go (about)

     1  package prometheus
     2  
     3  import (
     4  	"strconv"
     5  
     6  	"github.com/prometheus/client_golang/prometheus"
     7  	dto "github.com/prometheus/client_model/go"
     8  	"github.com/unicornultrafoundation/go-u2u/metrics"
     9  )
    10  
    11  // NewCollector constructor.
    12  func PrometheusCollector(opts prometheus.Opts, metric interface{}, fields ...string) *Collector {
    13  	return &Collector{
    14  		Metric: &Metric{
    15  			desc: prometheus.NewDesc(
    16  				prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
    17  				"",
    18  				fields,
    19  				nil,
    20  			),
    21  			m: metric,
    22  		},
    23  	}
    24  }
    25  
    26  // Collector collects ethereum metrics data.
    27  type Collector struct {
    28  	*Metric
    29  }
    30  
    31  // Describe implements prometheus.Collector interface.
    32  func (c *Collector) Describe(out chan<- *prometheus.Desc) {
    33  	out <- c.Metric.Desc()
    34  }
    35  
    36  // Collect implements prometheus.Collector interface.
    37  func (c *Collector) Collect(out chan<- prometheus.Metric) {
    38  	out <- c.Metric
    39  }
    40  
    41  type Metric struct {
    42  	desc *prometheus.Desc
    43  	m    interface{}
    44  }
    45  
    46  func (m *Metric) Desc() *prometheus.Desc {
    47  	return m.desc
    48  }
    49  
    50  func (m *Metric) Write(out *dto.Metric) error {
    51  	switch metric := m.m.(type) {
    52  
    53  	case metrics.Meter:
    54  		t := metric.Snapshot()
    55  
    56  		sum := &dto.Summary{
    57  			SampleCount: new(uint64),
    58  		}
    59  		*sum.SampleCount = uint64(t.Count())
    60  
    61  		out.Summary = sum
    62  		out.Label = []*dto.LabelPair{
    63  			pairF("rate1m", t.Rate1()),
    64  			pairF("rate5m", t.Rate5()),
    65  			pairF("rate15m", t.Rate15()),
    66  			pairF("rate", t.RateMean()),
    67  		}
    68  
    69  	case metrics.Histogram:
    70  		t := metric.Snapshot()
    71  
    72  		sum := &dto.Summary{
    73  			SampleCount: new(uint64),
    74  			SampleSum:   new(float64),
    75  		}
    76  		*sum.SampleCount = uint64(t.Count())
    77  		*sum.SampleSum = float64(t.Sum())
    78  
    79  		qq := []float64{0.5, 0.75, 0.95, 0.99, 0.999}
    80  		ps := t.Percentiles(qq)
    81  
    82  		for i := range qq {
    83  			sum.Quantile = append(sum.Quantile, quantile(qq[i], ps[i]))
    84  		}
    85  
    86  		out.Summary = sum
    87  		out.Label = []*dto.LabelPair{
    88  			pairI("min", t.Min()),
    89  			pairI("max", t.Max()),
    90  			pairF("mean", t.Mean()),
    91  		}
    92  
    93  	case metrics.Timer:
    94  		t := metric.Snapshot()
    95  
    96  		sum := &dto.Summary{
    97  			SampleCount: new(uint64),
    98  			SampleSum:   new(float64),
    99  		}
   100  		*sum.SampleCount = uint64(t.Count())
   101  		*sum.SampleSum = float64(t.Sum())
   102  
   103  		qq := []float64{0.5, 0.75, 0.95, 0.99, 0.999}
   104  		ps := t.Percentiles(qq)
   105  
   106  		for i := range qq {
   107  			sum.Quantile = append(sum.Quantile, quantile(qq[i], ps[i]))
   108  		}
   109  
   110  		out.Summary = sum
   111  		out.Label = []*dto.LabelPair{
   112  			pairI("min", t.Min()),
   113  			pairI("max", t.Max()),
   114  			pairF("mean", t.Mean()),
   115  			pairF("rate1m", t.Rate1()),
   116  			pairF("rate5m", t.Rate5()),
   117  			pairF("rate15m", t.Rate15()),
   118  			pairF("rate", t.RateMean()),
   119  		}
   120  
   121  	case metrics.ResettingTimer:
   122  		t := metric.Snapshot()
   123  
   124  		sum := &dto.Summary{}
   125  
   126  		qq := []float64{0.5, 0.75, 0.95, 0.99, 0.999}
   127  		ps := t.Percentiles(qq)
   128  
   129  		for i := range qq {
   130  			sum.Quantile = append(sum.Quantile, quantile(qq[i], float64(ps[i])))
   131  		}
   132  
   133  		out.Summary = sum
   134  	}
   135  	return nil
   136  }
   137  
   138  func quantile(q, v float64) *dto.Quantile {
   139  	return &dto.Quantile{
   140  		Quantile: &q,
   141  		Value:    &v,
   142  	}
   143  }
   144  
   145  func pairI(name string, val int64) *dto.LabelPair {
   146  	s := strconv.FormatInt(val, 10)
   147  	return &dto.LabelPair{
   148  		Name:  &name,
   149  		Value: &s,
   150  	}
   151  }
   152  
   153  func pairF(name string, val float64) *dto.LabelPair {
   154  	s := strconv.FormatFloat(val, 'g', -1, 64)
   155  	return &dto.LabelPair{
   156  		Name:  &name,
   157  		Value: &s,
   158  	}
   159  }