Skip to content

Commit

Permalink
app/vmselect/prometheus: do not return time series with empty list of…
Browse files Browse the repository at this point in the history
… datapoints from /api/v1/query_range

This matches Prometheus behaviour.

This should fix jacksontj/promxy#329
  • Loading branch information
valyala committed Jul 20, 2020
1 parent 4d2011a commit 141e84b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
12 changes: 10 additions & 2 deletions app/vmselect/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -883,14 +883,15 @@ func queryRangeHandler(at *auth.Token, w http.ResponseWriter, query string, star

// Remove NaN values as Prometheus does.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/153
removeNaNValuesInplace(result)
result = removeEmptyValuesAndTimeseries(result)

w.Header().Set("Content-Type", "application/json")
WriteQueryRangeResponse(w, result)
return nil
}

func removeNaNValuesInplace(tss []netstorage.Result) {
func removeEmptyValuesAndTimeseries(tss []netstorage.Result) []netstorage.Result {
dst := tss[:0]
for i := range tss {
ts := &tss[i]
hasNaNs := false
Expand All @@ -902,6 +903,9 @@ func removeNaNValuesInplace(tss []netstorage.Result) {
}
if !hasNaNs {
// Fast path: nothing to remove.
if len(ts.Values) > 0 {
dst = append(dst, *ts)
}
continue
}

Expand All @@ -918,7 +922,11 @@ func removeNaNValuesInplace(tss []netstorage.Result) {
}
ts.Values = dstValues
ts.Timestamps = dstTimestamps
if len(ts.Values) > 0 {
dst = append(dst, *ts)
}
}
return dst
}

var queryRangeDuration = metrics.NewSummary(`vm_request_duration_seconds{path="/api/v1/query_range"}`)
Expand Down
12 changes: 10 additions & 2 deletions app/vmselect/prometheus/prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
)

func TestRemoveNaNValuesInplace(t *testing.T) {
func TestRemoveEmptyValuesAndTimeseries(t *testing.T) {
f := func(tss []netstorage.Result, tssExpected []netstorage.Result) {
t.Helper()
removeNaNValuesInplace(tss)
tss = removeEmptyValuesAndTimeseries(tss)
if !reflect.DeepEqual(tss, tssExpected) {
t.Fatalf("unexpected result; got %v; want %v", tss, tssExpected)
}
Expand All @@ -30,6 +30,14 @@ func TestRemoveNaNValuesInplace(t *testing.T) {
Timestamps: []int64{100, 200, 300, 400},
Values: []float64{nan, nan, 3, nan},
},
{
Timestamps: []int64{1, 2},
Values: []float64{nan, nan},
},
{
Timestamps: nil,
Values: nil,
},
}, []netstorage.Result{
{
Timestamps: []int64{100, 200, 300},
Expand Down

0 comments on commit 141e84b

Please sign in to comment.