forked from mirror/client_golang
Return NaN when summaries have no observations yet.
Also, properly handle decay upon Write(). This fixes https://github.com/prometheus/client_golang/issues/85 .
This commit is contained in:
parent
7af92a21b3
commit
715be73ac9
|
@ -16,6 +16,7 @@ package prometheus
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -277,10 +278,8 @@ func (s *summary) Write(out *dto.Metric) error {
|
||||||
|
|
||||||
s.bufMtx.Lock()
|
s.bufMtx.Lock()
|
||||||
s.mtx.Lock()
|
s.mtx.Lock()
|
||||||
|
// Swap bufs even if hotBuf is empty to set new hotBufExpTime.
|
||||||
if len(s.hotBuf) != 0 {
|
s.swapBufs(time.Now())
|
||||||
s.swapBufs(time.Now())
|
|
||||||
}
|
|
||||||
s.bufMtx.Unlock()
|
s.bufMtx.Unlock()
|
||||||
|
|
||||||
s.flushColdBuf()
|
s.flushColdBuf()
|
||||||
|
@ -288,9 +287,15 @@ func (s *summary) Write(out *dto.Metric) error {
|
||||||
sum.SampleSum = proto.Float64(s.sum)
|
sum.SampleSum = proto.Float64(s.sum)
|
||||||
|
|
||||||
for _, rank := range s.sortedObjectives {
|
for _, rank := range s.sortedObjectives {
|
||||||
|
var q float64
|
||||||
|
if s.headStream.Count() == 0 {
|
||||||
|
q = math.NaN()
|
||||||
|
} else {
|
||||||
|
q = s.headStream.Query(rank)
|
||||||
|
}
|
||||||
qs = append(qs, &dto.Quantile{
|
qs = append(qs, &dto.Quantile{
|
||||||
Quantile: proto.Float64(rank),
|
Quantile: proto.Float64(rank),
|
||||||
Value: proto.Float64(s.headStream.Query(rank)),
|
Value: proto.Float64(q),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,11 @@ func TestSummaryVecConcurrency(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSummaryDecay(t *testing.T) {
|
func TestSummaryDecay(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping test in short mode.")
|
||||||
|
// More because it depends on timing than because it is particularly long...
|
||||||
|
}
|
||||||
|
|
||||||
sum := NewSummary(SummaryOpts{
|
sum := NewSummary(SummaryOpts{
|
||||||
Name: "test_summary",
|
Name: "test_summary",
|
||||||
Help: "helpless",
|
Help: "helpless",
|
||||||
|
@ -315,6 +320,12 @@ func TestSummaryDecay(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tick.Stop()
|
tick.Stop()
|
||||||
|
// Wait for MaxAge without observations and make sure quantiles are NaN.
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
sum.Write(m)
|
||||||
|
if got := *m.Summary.Quantile[0].Value; !math.IsNaN(got) {
|
||||||
|
t.Errorf("got %f, want NaN after expiration", got)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBounds(vars []float64, q, ε float64) (min, max float64) {
|
func getBounds(vars []float64, q, ε float64) (min, max float64) {
|
||||||
|
|
Loading…
Reference in New Issue