collector.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. package prometheus
  17. import (
  18. "bytes"
  19. "fmt"
  20. "strconv"
  21. "strings"
  22. "github.com/ethereum/go-ethereum/metrics"
  23. )
  24. var (
  25. typeGaugeTpl = "# TYPE %s gauge\n"
  26. typeCounterTpl = "# TYPE %s counter\n"
  27. typeSummaryTpl = "# TYPE %s summary\n"
  28. keyValueTpl = "%s %v\n\n"
  29. keyQuantileTagValueTpl = "%s {quantile=\"%s\"} %v\n"
  30. )
  31. // collector is a collection of byte buffers that aggregate Prometheus reports
  32. // for different metric types.
  33. type collector struct {
  34. buff *bytes.Buffer
  35. }
  36. // newCollector creates a new Prometheus metric aggregator.
  37. func newCollector() *collector {
  38. return &collector{
  39. buff: &bytes.Buffer{},
  40. }
  41. }
  42. func (c *collector) addCounter(name string, m metrics.Counter) {
  43. c.writeGaugeCounter(name, m.Count())
  44. }
  45. func (c *collector) addGauge(name string, m metrics.Gauge) {
  46. c.writeGaugeCounter(name, m.Value())
  47. }
  48. func (c *collector) addGaugeFloat64(name string, m metrics.GaugeFloat64) {
  49. c.writeGaugeCounter(name, m.Value())
  50. }
  51. func (c *collector) addHistogram(name string, m metrics.Histogram) {
  52. pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999}
  53. ps := m.Percentiles(pv)
  54. c.writeSummaryCounter(name, m.Count())
  55. c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name)))
  56. for i := range pv {
  57. c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i])
  58. }
  59. c.buff.WriteRune('\n')
  60. }
  61. func (c *collector) addMeter(name string, m metrics.Meter) {
  62. c.writeGaugeCounter(name, m.Count())
  63. }
  64. func (c *collector) addTimer(name string, m metrics.Timer) {
  65. pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999}
  66. ps := m.Percentiles(pv)
  67. c.writeSummaryCounter(name, m.Count())
  68. c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name)))
  69. for i := range pv {
  70. c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i])
  71. }
  72. c.buff.WriteRune('\n')
  73. }
  74. func (c *collector) addResettingTimer(name string, m metrics.ResettingTimer) {
  75. if len(m.Values()) <= 0 {
  76. return
  77. }
  78. ps := m.Percentiles([]float64{50, 95, 99})
  79. val := m.Values()
  80. c.writeSummaryCounter(name, len(val))
  81. c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name)))
  82. c.writeSummaryPercentile(name, "0.50", ps[0])
  83. c.writeSummaryPercentile(name, "0.95", ps[1])
  84. c.writeSummaryPercentile(name, "0.99", ps[2])
  85. c.buff.WriteRune('\n')
  86. }
  87. func (c *collector) writeGaugeCounter(name string, value interface{}) {
  88. name = mutateKey(name)
  89. c.buff.WriteString(fmt.Sprintf(typeGaugeTpl, name))
  90. c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value))
  91. }
  92. func (c *collector) writeSummaryCounter(name string, value interface{}) {
  93. name = mutateKey(name + "_count")
  94. c.buff.WriteString(fmt.Sprintf(typeCounterTpl, name))
  95. c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value))
  96. }
  97. func (c *collector) writeSummaryPercentile(name, p string, value interface{}) {
  98. name = mutateKey(name)
  99. c.buff.WriteString(fmt.Sprintf(keyQuantileTagValueTpl, name, p, value))
  100. }
  101. func mutateKey(key string) string {
  102. return strings.Replace(key, "/", "_", -1)
  103. }