From eb780f4caabb70180a60645959e3997aa5ce071f Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Mon, 25 Nov 2019 13:01:23 +0200 Subject: [PATCH] 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 --- set.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/set.go b/set.go index fad7b09..dfc0042 100644 --- a/set.go +++ b/set.go @@ -1,6 +1,7 @@ package metrics import ( + "bytes" "fmt" "io" "sort" @@ -29,6 +30,8 @@ func NewSet() *Set { // WritePrometheus writes all the metrics from s to w in Prometheus format. 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 { 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) } for _, nm := range s.a { - nm.metric.marshalTo(nm.name, w) + nm.metric.marshalTo(nm.name, &bb) } s.mu.Unlock() + w.Write(bb.Bytes()) } // NewHistogram creates and returns new histogram in s with the given name.