| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | // Copyright 2019 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package prometheus | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"strconv" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/metrics" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	typeGaugeTpl           = "# TYPE %s gauge\n" | 
					
						
							|  |  |  | 	typeCounterTpl         = "# TYPE %s counter\n" | 
					
						
							|  |  |  | 	typeSummaryTpl         = "# TYPE %s summary\n" | 
					
						
							|  |  |  | 	keyValueTpl            = "%s %v\n\n" | 
					
						
							| 
									
										
										
										
											2020-05-26 11:00:09 +02:00
										 |  |  | 	keyQuantileTagValueTpl = "%s {quantile=\"%s\"} %v\n" | 
					
						
							| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // collector is a collection of byte buffers that aggregate Prometheus reports | 
					
						
							|  |  |  | // for different metric types. | 
					
						
							|  |  |  | type collector struct { | 
					
						
							|  |  |  | 	buff *bytes.Buffer | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-26 11:00:09 +02:00
										 |  |  | // newCollector creates a new Prometheus metric aggregator. | 
					
						
							| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | func newCollector() *collector { | 
					
						
							|  |  |  | 	return &collector{ | 
					
						
							|  |  |  | 		buff: &bytes.Buffer{}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) addCounter(name string, m metrics.Counter) { | 
					
						
							|  |  |  | 	c.writeGaugeCounter(name, m.Count()) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) addGauge(name string, m metrics.Gauge) { | 
					
						
							|  |  |  | 	c.writeGaugeCounter(name, m.Value()) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) addGaugeFloat64(name string, m metrics.GaugeFloat64) { | 
					
						
							|  |  |  | 	c.writeGaugeCounter(name, m.Value()) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) addHistogram(name string, m metrics.Histogram) { | 
					
						
							|  |  |  | 	pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999} | 
					
						
							|  |  |  | 	ps := m.Percentiles(pv) | 
					
						
							|  |  |  | 	c.writeSummaryCounter(name, m.Count()) | 
					
						
							| 
									
										
										
										
											2020-05-26 11:00:09 +02:00
										 |  |  | 	c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name))) | 
					
						
							| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | 	for i := range pv { | 
					
						
							|  |  |  | 		c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i]) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-05-26 11:00:09 +02:00
										 |  |  | 	c.buff.WriteRune('\n') | 
					
						
							| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) addMeter(name string, m metrics.Meter) { | 
					
						
							|  |  |  | 	c.writeGaugeCounter(name, m.Count()) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) addTimer(name string, m metrics.Timer) { | 
					
						
							|  |  |  | 	pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999} | 
					
						
							|  |  |  | 	ps := m.Percentiles(pv) | 
					
						
							|  |  |  | 	c.writeSummaryCounter(name, m.Count()) | 
					
						
							| 
									
										
										
										
											2020-05-26 11:00:09 +02:00
										 |  |  | 	c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name))) | 
					
						
							| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | 	for i := range pv { | 
					
						
							|  |  |  | 		c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i]) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-05-26 11:00:09 +02:00
										 |  |  | 	c.buff.WriteRune('\n') | 
					
						
							| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) addResettingTimer(name string, m metrics.ResettingTimer) { | 
					
						
							|  |  |  | 	if len(m.Values()) <= 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ps := m.Percentiles([]float64{50, 95, 99}) | 
					
						
							|  |  |  | 	val := m.Values() | 
					
						
							|  |  |  | 	c.writeSummaryCounter(name, len(val)) | 
					
						
							| 
									
										
										
										
											2020-05-26 11:00:09 +02:00
										 |  |  | 	c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, mutateKey(name))) | 
					
						
							| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | 	c.writeSummaryPercentile(name, "0.50", ps[0]) | 
					
						
							|  |  |  | 	c.writeSummaryPercentile(name, "0.95", ps[1]) | 
					
						
							|  |  |  | 	c.writeSummaryPercentile(name, "0.99", ps[2]) | 
					
						
							| 
									
										
										
										
											2020-05-26 11:00:09 +02:00
										 |  |  | 	c.buff.WriteRune('\n') | 
					
						
							| 
									
										
										
										
											2019-04-11 12:56:19 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) writeGaugeCounter(name string, value interface{}) { | 
					
						
							|  |  |  | 	name = mutateKey(name) | 
					
						
							|  |  |  | 	c.buff.WriteString(fmt.Sprintf(typeGaugeTpl, name)) | 
					
						
							|  |  |  | 	c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) writeSummaryCounter(name string, value interface{}) { | 
					
						
							|  |  |  | 	name = mutateKey(name + "_count") | 
					
						
							|  |  |  | 	c.buff.WriteString(fmt.Sprintf(typeCounterTpl, name)) | 
					
						
							|  |  |  | 	c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *collector) writeSummaryPercentile(name, p string, value interface{}) { | 
					
						
							|  |  |  | 	name = mutateKey(name) | 
					
						
							|  |  |  | 	c.buff.WriteString(fmt.Sprintf(keyQuantileTagValueTpl, name, p, value)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func mutateKey(key string) string { | 
					
						
							|  |  |  | 	return strings.Replace(key, "/", "_", -1) | 
					
						
							|  |  |  | } |