github.com/amazechain/amc@v0.1.3/internal/metrics/prometheus/collector.go (about) 1 package prometheus 2 3 import ( 4 "bytes" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/VictoriaMetrics/metrics" 10 ) 11 12 var ( 13 typeGaugeTpl = "\n# TYPE %s gauge\n" 14 typeCounterTpl = "\n# TYPE %s counter\n" 15 typeSummaryTpl = "\n# TYPE %s summary\n" 16 keyValueTpl = "%s %v\n" 17 keyCounterTpl = "%s %v\n" 18 keyQuantileTagValueTpl = "%s {quantile=\"%s\"} %v\n" 19 keyQuantileTagValueWithLabelsTpl = "%s,quantile=\"%s\"} %v\n" 20 ) 21 22 // collector is a collection of byte buffers that aggregate Prometheus reports 23 // for different metric types. 24 type collector struct { 25 buff *bytes.Buffer 26 } 27 28 // newCollector creates a new Prometheus metric aggregator. 29 func newCollector() *collector { 30 return &collector{ 31 buff: &bytes.Buffer{}, 32 } 33 } 34 35 func (c *collector) writeFloatCounter(name string, m *metrics.FloatCounter, withType bool) { 36 c.writeCounter(name, m.Get(), withType) 37 } 38 39 func (c *collector) writeHistogram(name string, m *metrics.Histogram, withType bool) { 40 if withType { 41 c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, stripLabels(name))) 42 } 43 44 c.writeSummarySum(name, fmt.Sprintf("%f", m.GetSum())) 45 c.writeSummaryCounter(name, len(m.GetDecimalBuckets())) 46 } 47 48 func (c *collector) writeTimer(name string, m *metrics.Summary, withType bool) { 49 pv := m.GetQuantiles() 50 ps := m.GetQuantileValues() 51 52 var sum float64 = 0 53 if withType { 54 c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, stripLabels(name))) 55 } 56 57 for i := range pv { 58 c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i]) 59 sum += ps[i] 60 } 61 62 c.writeSummaryTime(name, fmt.Sprintf("%f", m.GetTime().Seconds())) 63 c.writeSummarySum(name, fmt.Sprintf("%f", sum)) 64 c.writeSummaryCounter(name, len(ps)) 65 } 66 67 func (c *collector) writeGauge(name string, value interface{}, withType bool) { 68 if withType { 69 c.buff.WriteString(fmt.Sprintf(typeGaugeTpl, stripLabels(name))) 70 } 71 c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value)) 72 } 73 74 func (c *collector) writeCounter(name string, value interface{}, withType bool) { 75 if withType { 76 c.buff.WriteString(fmt.Sprintf(typeCounterTpl, stripLabels(name))) 77 } 78 c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value)) 79 } 80 81 func stripLabels(name string) string { 82 if labelsIndex := strings.IndexByte(name, '{'); labelsIndex >= 0 { 83 return name[0:labelsIndex] 84 } 85 86 return name 87 } 88 89 func splitLabels(name string) (string, string) { 90 if labelsIndex := strings.IndexByte(name, '{'); labelsIndex >= 0 { 91 return name[0:labelsIndex], name[labelsIndex:] 92 } 93 94 return name, "" 95 } 96 97 func (c *collector) writeSummaryCounter(name string, value interface{}) { 98 name, labels := splitLabels(name) 99 name = name + "_count" 100 c.buff.WriteString(fmt.Sprintf(keyCounterTpl, name+labels, value)) 101 } 102 103 func (c *collector) writeSummaryPercentile(name, p string, value interface{}) { 104 name, labels := splitLabels(name) 105 106 if len(labels) > 0 { 107 c.buff.WriteString(fmt.Sprintf(keyQuantileTagValueWithLabelsTpl, name+strings.TrimSuffix(labels, "}"), p, value)) 108 } else { 109 c.buff.WriteString(fmt.Sprintf(keyQuantileTagValueTpl, name, p, value)) 110 } 111 } 112 113 func (c *collector) writeSummarySum(name string, value string) { 114 name, labels := splitLabels(name) 115 name = name + "_sum" 116 c.buff.WriteString(fmt.Sprintf(keyCounterTpl, name+labels, value)) 117 } 118 119 func (c *collector) writeSummaryTime(name string, value string) { 120 name, labels := splitLabels(name) 121 name = name + "_time" 122 c.buff.WriteString(fmt.Sprintf(keyCounterTpl, name+labels, value)) 123 }