metrics/prometheus: minor cleanups

This commit is contained in:
Péter Szilágyi 2019-04-05 10:27:21 +03:00
parent ae5c0fc0e4
commit 8e8d55ed8e
No known key found for this signature in database
GPG key ID: E9AE538CEDF8293D
2 changed files with 35 additions and 31 deletions

View file

@ -13,6 +13,7 @@
//
// 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 (
@ -43,21 +44,26 @@ var (
nameQuantileTagTemplate = "{name=\"%s\",quantile=\"%s\"} %v\n"
)
// bufPool is a global pool of byte buffers to avoid constant reallocations.
var bufPool sync.Pool
// getBuf retrieves a new empty (but possibly non-0 capacity) buffer.
func getBuf() *bytes.Buffer {
buf := bufPool.Get()
if buf == nil {
if item := bufPool.Get(); item != nil {
buf := item.(*bytes.Buffer)
buf.Reset()
return buf
}
return &bytes.Buffer{}
}
return buf.(*bytes.Buffer)
}
// giveBuf returns a used byte buffer to the pool.
func giveBuf(buf *bytes.Buffer) {
buf.Reset()
bufPool.Put(buf)
}
// collector is a collection of byte buffers that aggregate Prometheus reports
// for different metric types.
type collector struct {
counters *bytes.Buffer
gauges *bytes.Buffer
@ -67,6 +73,7 @@ type collector struct {
resettingTimers *bytes.Buffer
}
// newCollector createa a new Prometheus metric aggregator.
func newCollector() *collector {
return &collector{
counters: getBuf(),
@ -78,7 +85,9 @@ func newCollector() *collector {
}
}
func (c *collector) reset() {
// close releases all internally held byte buffers to be reused by subsequent
// metrics collection runs.
func (c *collector) close() {
giveBuf(c.counters)
giveBuf(c.gauges)
giveBuf(c.histograms)
@ -87,38 +96,34 @@ func (c *collector) reset() {
giveBuf(c.resettingTimers)
}
func (c *collector) result() *bytes.Buffer {
// aggregate iterates over the different metric types and aggregates them into
// a single byte buffer.
func (c *collector) aggregate() *bytes.Buffer {
buf := getBuf()
if c.counters.Len() > 0 {
buf.Write(countersHeader)
buf.Write(c.counters.Bytes())
}
if c.gauges.Len() > 0 {
buf.Write(gaugesHeader)
buf.Write(c.gauges.Bytes())
}
if c.meters.Len() > 0 {
buf.Write(meterHeader)
buf.Write(c.meters.Bytes())
}
if c.histograms.Len() > 0 {
buf.Write(histogramHeader)
buf.Write(c.histograms.Bytes())
}
if c.timers.Len() > 0 {
buf.Write(timerHeader)
buf.Write(c.timers.Bytes())
}
if c.resettingTimers.Len() > 0 {
buf.Write(resettingTimerHeader)
buf.Write(c.resettingTimers.Bytes())
}
return buf
}

View file

@ -13,48 +13,47 @@
//
// 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 exposes go-metrics into a Prometheus format.
package prometheus
import (
"fmt"
"net/http"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
)
// Handler returns http handler which dump metrics in prometheus format
// Handler returns an HTTP handler which dump metrics in Prometheus format.
func Handler(reg metrics.Registry) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Aggregate all the metris into a Prometheus collector
c := newCollector()
defer c.reset()
defer c.close()
reg.Each(func(name string, i interface{}) {
switch m := i.(type) {
case metrics.Counter:
ms := m.Snapshot()
c.addCounter(name, ms)
c.addCounter(name, m.Snapshot())
case metrics.Gauge:
ms := m.Snapshot()
c.addGuage(name, ms)
c.addGuage(name, m.Snapshot())
case metrics.GaugeFloat64:
ms := m.Snapshot()
c.addGuageFloat64(name, ms)
c.addGuageFloat64(name, m.Snapshot())
case metrics.Histogram:
ms := m.Snapshot()
c.addHistogram(name, ms)
c.addHistogram(name, m.Snapshot())
case metrics.Meter:
ms := m.Snapshot()
c.addMeter(name, ms)
c.addMeter(name, m.Snapshot())
case metrics.Timer:
ms := m.Snapshot()
c.addTimer(name, ms)
c.addTimer(name, m.Snapshot())
case metrics.ResettingTimer:
ms := m.Snapshot()
c.addResettingTimer(name, ms)
c.addResettingTimer(name, m.Snapshot())
default:
log.Warn("Unknown Prometheus metric type", "type", fmt.Sprintf("%T", i))
}
})
res := c.result()
// Aggregate the results into a single buffer and send to the user
res := c.aggregate()
defer giveBuf(res)
w.Header().Add("Content-Type", "text/plain")