github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/metrics/prometheus/collector.go (about)

     1  // Copyright 2019 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package prometheus
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"strconv"
    23  	"strings"
    24  
    25  	"github.com/ethereum/go-ethereum/metrics"
    26  )
    27  
    28  var (
    29  	typeGaugeTpl           = "# TYPE %s gauge\n"
    30  	typeCounterTpl         = "# TYPE %s counter\n"
    31  	typeSummaryTpl         = "# TYPE %s summary\n"
    32  	keyValueTpl            = "%s %v\n\n"
    33  	keyCounterTpl          = "%s %v\n"
    34  	keyQuantileTagValueTpl = "%s {quantile=\"%s\"} %v\n"
    35  )
    36  
    37  // collector is a collection of byte buffers that aggregate Prometheus reports
    38  // for different metric types.
    39  type collector struct {
    40  	buff *bytes.Buffer
    41  }
    42  
    43  // newCollector creates a new Prometheus metric aggregator.
    44  func newCollector() *collector {
    45  	return &collector{
    46  		buff: &bytes.Buffer{},
    47  	}
    48  }
    49  
    50  func (c *collector) addCounter(name string, m metrics.Counter) {
    51  	c.writeGaugeCounter(name, m.Count())
    52  }
    53  
    54  func (c *collector) addGauge(name string, m metrics.Gauge) {
    55  	c.writeGaugeCounter(name, m.Value())
    56  }
    57  
    58  func (c *collector) addGaugeFloat64(name string, m metrics.GaugeFloat64) {
    59  	c.writeGaugeCounter(name, m.Value())
    60  }
    61  
    62  func (c *collector) addHistogram(name string, m metrics.Histogram) {
    63  	pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999}
    64  	ps := m.Percentiles(pv)
    65  
    66  	var sum float64 = 0
    67  	c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name)))
    68  	for i := range pv {
    69  		c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i])
    70  		sum += ps[i]
    71  	}
    72  
    73  	c.writeSummarySum(name, fmt.Sprintf("%f", sum))
    74  	c.writeSummaryCounter(name, len(ps))
    75  	c.buff.WriteRune('\n')
    76  }
    77  
    78  func (c *collector) addMeter(name string, m metrics.Meter) {
    79  	c.writeGaugeCounter(name, m.Count())
    80  }
    81  
    82  func (c *collector) addTimer(name string, m metrics.Timer) {
    83  	pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999}
    84  	ps := m.Percentiles(pv)
    85  	c.writeCounter(name, m.Count())
    86  	c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name)))
    87  	for i := range pv {
    88  		c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i])
    89  	}
    90  	c.buff.WriteRune('\n')
    91  }
    92  
    93  func (c *collector) addResettingTimer(name string, m metrics.ResettingTimer) {
    94  	if len(m.Values()) <= 0 {
    95  		return
    96  	}
    97  	ps := m.Percentiles([]float64{50, 95, 99})
    98  	val := m.Values()
    99  	c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name)))
   100  	c.writeSummaryPercentile(name, "0.50", ps[0])
   101  	c.writeSummaryPercentile(name, "0.95", ps[1])
   102  	c.writeSummaryPercentile(name, "0.99", ps[2])
   103  
   104  	var sum int64 = 0
   105  
   106  	for _, v := range val {
   107  		sum += v
   108  	}
   109  
   110  	c.writeSummarySum(name, fmt.Sprintf("%d", sum))
   111  	c.writeSummaryCounter(name, len(val))
   112  	c.buff.WriteRune('\n')
   113  }
   114  
   115  func (c *collector) writeGaugeCounter(name string, value interface{}) {
   116  	name = mutateKey(name)
   117  	c.buff.WriteString(fmt.Sprintf(typeGaugeTpl, name))
   118  	c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value))
   119  }
   120  
   121  func (c *collector) writeCounter(name string, value interface{}) {
   122  	name = mutateKey(name + "_count")
   123  	c.buff.WriteString(fmt.Sprintf(typeCounterTpl, name))
   124  	c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value))
   125  }
   126  
   127  func (c *collector) writeSummaryCounter(name string, value interface{}) {
   128  	name = mutateKey(name + "_count")
   129  	c.buff.WriteString(fmt.Sprintf(keyCounterTpl, name, value))
   130  }
   131  
   132  func (c *collector) writeSummaryPercentile(name, p string, value interface{}) {
   133  	name = mutateKey(name)
   134  	c.buff.WriteString(fmt.Sprintf(keyQuantileTagValueTpl, name, p, value))
   135  }
   136  
   137  func (c *collector) writeSummarySum(name string, value string) {
   138  	name = mutateKey(name + "_sum")
   139  	c.buff.WriteString(fmt.Sprintf(keyCounterTpl, name, value))
   140  }
   141  
   142  func mutateKey(key string) string {
   143  	return strings.Replace(key, "/", "_", -1)
   144  }