From 5a4675c528ab48570708e27113a3723a6236fb68 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Mon, 20 Jul 2020 15:28:36 +0300 Subject: [PATCH] app/vmselect/prometheus: do not return time series with empty list of datapoints from /api/v1/query_range This matches Prometheus behaviour. This should fix https://github.com/jacksontj/promxy/issues/329 --- app/vmselect/prometheus/prometheus.go | 12 ++++++++++-- app/vmselect/prometheus/prometheus_test.go | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/vmselect/prometheus/prometheus.go b/app/vmselect/prometheus/prometheus.go index fecb30b62..04de32a64 100644 --- a/app/vmselect/prometheus/prometheus.go +++ b/app/vmselect/prometheus/prometheus.go @@ -797,14 +797,15 @@ func queryRangeHandler(w http.ResponseWriter, query string, start, end, step int // 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 @@ -816,6 +817,9 @@ func removeNaNValuesInplace(tss []netstorage.Result) { } if !hasNaNs { // Fast path: nothing to remove. + if len(ts.Values) > 0 { + dst = append(dst, *ts) + } continue } @@ -832,7 +836,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"}`) diff --git a/app/vmselect/prometheus/prometheus_test.go b/app/vmselect/prometheus/prometheus_test.go index a84028f92..c86734fb0 100644 --- a/app/vmselect/prometheus/prometheus_test.go +++ b/app/vmselect/prometheus/prometheus_test.go @@ -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) } @@ -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},