Buffer all the output in memory before writing it to the provided io.Writer in WritePrometheus

This should prevent from indefinite locking of internal structures in the case of laggy io.Writer
This commit is contained in:
Aliaksandr Valialkin 2019-11-25 13:01:23 +02:00
parent 839018719c
commit eb780f4caa

6
set.go
View File

@ -1,6 +1,7 @@
package metrics package metrics
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"sort" "sort"
@ -29,6 +30,8 @@ func NewSet() *Set {
// WritePrometheus writes all the metrics from s to w in Prometheus format. // WritePrometheus writes all the metrics from s to w in Prometheus format.
func (s *Set) WritePrometheus(w io.Writer) { func (s *Set) WritePrometheus(w io.Writer) {
// Collect all the metrics in in-memory buffer in order to prevent from long locking due to slow w.
var bb bytes.Buffer
lessFunc := func(i, j int) bool { lessFunc := func(i, j int) bool {
return s.a[i].name < s.a[j].name return s.a[i].name < s.a[j].name
} }
@ -40,9 +43,10 @@ func (s *Set) WritePrometheus(w io.Writer) {
sort.Slice(s.a, lessFunc) sort.Slice(s.a, lessFunc)
} }
for _, nm := range s.a { for _, nm := range s.a {
nm.metric.marshalTo(nm.name, w) nm.metric.marshalTo(nm.name, &bb)
} }
s.mu.Unlock() s.mu.Unlock()
w.Write(bb.Bytes())
} }
// NewHistogram creates and returns new histogram in s with the given name. // NewHistogram creates and returns new histogram in s with the given name.