Fix memory leak in metrics

Co-authored-by: Ludovic Fernandez <ldez@users.noreply.github.com>
This commit is contained in:
Julien Salleyron 2020-03-19 13:48:04 +01:00 committed by GitHub
parent 683d5d5a48
commit b40fa61783
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 13 additions and 31 deletions

View file

@ -191,36 +191,29 @@ func (r *standardRegistry) ServiceServerUpGauge() metrics.Gauge {
// used when producing observations without explicitly setting the observed value. // used when producing observations without explicitly setting the observed value.
type ScalableHistogram interface { type ScalableHistogram interface {
With(labelValues ...string) ScalableHistogram With(labelValues ...string) ScalableHistogram
StartAt(t time.Time)
Observe(v float64) Observe(v float64)
ObserveDuration() ObserveFromStart(start time.Time)
} }
// HistogramWithScale is a histogram that will convert its observed value to the specified unit. // HistogramWithScale is a histogram that will convert its observed value to the specified unit.
type HistogramWithScale struct { type HistogramWithScale struct {
histogram metrics.Histogram histogram metrics.Histogram
unit time.Duration unit time.Duration
start time.Time
} }
// With implements ScalableHistogram. // With implements ScalableHistogram.
func (s *HistogramWithScale) With(labelValues ...string) ScalableHistogram { func (s *HistogramWithScale) With(labelValues ...string) ScalableHistogram {
s.histogram = s.histogram.With(labelValues...) h, _ := NewHistogramWithScale(s.histogram.With(labelValues...), s.unit)
return s return h
} }
// StartAt implements ScalableHistogram. // ObserveFromStart implements ScalableHistogram.
func (s *HistogramWithScale) StartAt(t time.Time) { func (s *HistogramWithScale) ObserveFromStart(start time.Time) {
s.start = t
}
// ObserveDuration implements ScalableHistogram.
func (s *HistogramWithScale) ObserveDuration() {
if s.unit <= 0 { if s.unit <= 0 {
return return
} }
d := float64(time.Since(s.start).Nanoseconds()) / float64(s.unit) d := float64(time.Since(start).Nanoseconds()) / float64(s.unit)
if d < 0 { if d < 0 {
d = 0 d = 0
} }
@ -251,17 +244,10 @@ func NewMultiHistogram(h ...ScalableHistogram) MultiHistogram {
return MultiHistogram(h) return MultiHistogram(h)
} }
// StartAt implements ScalableHistogram. // ObserveFromStart implements ScalableHistogram.
func (h MultiHistogram) StartAt(t time.Time) { func (h MultiHistogram) ObserveFromStart(start time.Time) {
for _, histogram := range h { for _, histogram := range h {
histogram.StartAt(t) histogram.ObserveFromStart(start)
}
}
// ObserveDuration implements ScalableHistogram.
func (h MultiHistogram) ObserveDuration() {
for _, histogram := range h {
histogram.ObserveDuration()
} }
} }

View file

@ -19,9 +19,9 @@ func TestScalableHistogram(t *testing.T) {
ticker := time.NewTicker(500 * time.Millisecond) ticker := time.NewTicker(500 * time.Millisecond)
<-ticker.C <-ticker.C
sh.StartAt(time.Now()) start := time.Now()
<-ticker.C <-ticker.C
sh.ObserveDuration() sh.ObserveFromStart(start)
var b bytes.Buffer var b bytes.Buffer
h.Print(&b) h.Print(&b)
@ -99,9 +99,7 @@ func (c *histogramMock) With(labelValues ...string) ScalableHistogram {
func (c *histogramMock) Start() {} func (c *histogramMock) Start() {}
func (c *histogramMock) StartAt(t time.Time) {} func (c *histogramMock) ObserveFromStart(t time.Time) {}
func (c *histogramMock) ObserveDuration() {}
func (c *histogramMock) Observe(v float64) { func (c *histogramMock) Observe(v float64) {
c.lastHistogramValue = v c.lastHistogramValue = v

View file

@ -96,11 +96,9 @@ func (m *metricsMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request)
labels = append(labels, "code", strconv.Itoa(recorder.getCode())) labels = append(labels, "code", strconv.Itoa(recorder.getCode()))
histograms := m.reqDurationHistogram.With(labels...) histograms := m.reqDurationHistogram.With(labels...)
histograms.StartAt(start) histograms.ObserveFromStart(start)
m.reqsCounter.With(labels...).Add(1) m.reqsCounter.With(labels...).Add(1)
histograms.ObserveDuration()
} }
func getRequestProtocol(req *http.Request) string { func getRequestProtocol(req *http.Request) string {