mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
metrics/prometheus: minor cleanups
This commit is contained in:
parent
ae5c0fc0e4
commit
8e8d55ed8e
2 changed files with 35 additions and 31 deletions
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
Loading…
Reference in a new issue