Skip to content
Next Next commit
support max_source_resolution param for instant queries
This adds support for the ?max_source_resolution query
param for instant queries.

Instant queries had the issue that when there was a subquery requesting wide
data ranges e.g. sum_over_time(metric_name[30d])) and the retention of raw data
was for example only 7d, the query would (silently) only take data from the last
7 days into account (ignoring the downsampled 5m and 1h timeseries that were
available with longer retention).

We default to 1h max_source_resolution for now as this will cover
the highest/broadest resolution available and should include
all retention. It is configurable per query (although no known
clients send it).

Signed-off-by: Tim Reddehase <tim.reddehase@xing.com>
  • Loading branch information
0robustus1 committed Aug 27, 2019
commit eb5ee6b95790db154143ff1407edde54cc323c2d
17 changes: 14 additions & 3 deletions pkg/query/api/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,18 @@ func (api *API) parseEnableDedupParam(r *http.Request) (enableDeduplication bool
}

func (api *API) parseDownsamplingParamMillis(r *http.Request, step time.Duration) (maxResolutionMillis int64, _ *ApiError) {
// If no max_source_resolution is specified fit at least 5 samples between steps.
return api.parseDownsamplingParamMillisWithDefault(r, step/5)
}

func (api *API) parseDownsamplingParamMillisWithDefault(r *http.Request, defaultVal time.Duration) (maxResolutionMillis int64, _ *ApiError) {
const maxSourceResolutionParam = "max_source_resolution"
maxSourceResolution := 0 * time.Second

if api.enableAutodownsampling {
// If no max_source_resolution is specified fit at least 5 samples between steps.
maxSourceResolution = step / 5
maxSourceResolution = defaultVal
}

if val := r.FormValue(maxSourceResolutionParam); val != "" {
var err error
maxSourceResolution, err = parseDuration(val)
Expand Down Expand Up @@ -257,11 +262,17 @@ func (api *API) query(r *http.Request) (interface{}, []error, *ApiError) {
return nil, nil, apiErr
}

const defaultMaxSourceResolution = 3600 * time.Second
maxSourceResolution, apiErr := api.parseDownsamplingParamMillisWithDefault(r, defaultMaxSourceResolution)
if apiErr != nil {
return nil, nil, apiErr
}

// We are starting promQL tracing span here, because we have no control over promQL code.
span, ctx := tracing.StartSpan(ctx, "promql_instant_query")
defer span.Finish()

qry, err := api.queryEngine.NewInstantQuery(api.queryableCreate(enableDedup, 0, enablePartialResponse), r.FormValue("query"), ts)
qry, err := api.queryEngine.NewInstantQuery(api.queryableCreate(enableDedup, maxSourceResolution, enablePartialResponse), r.FormValue("query"), ts)
if err != nil {
return nil, nil, &ApiError{errorBadData, err}
}
Expand Down