Add support for lookbackdelta per query via the API

Signed-off-by: Julien Pivotto <roidelapluie@o11y.eu>
This commit is contained in:
Julien Pivotto 2023-03-08 00:28:31 +01:00
parent c4da9cd92f
commit db2d759b81
2 changed files with 81 additions and 4 deletions

View File

@ -413,7 +413,10 @@ func (api *API) query(r *http.Request) (result apiFuncResult) {
defer cancel()
}
opts := extractQueryOpts(r)
opts, err := extractQueryOpts(r)
if err != nil {
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
}
qry, err := api.QueryEngine.NewInstantQuery(api.Queryable, opts, r.FormValue("query"), ts)
if err != nil {
return invalidParamError(err, "query")
@ -458,10 +461,18 @@ func (api *API) formatQuery(r *http.Request) (result apiFuncResult) {
return apiFuncResult{expr.Pretty(0), nil, nil, nil}
}
func extractQueryOpts(r *http.Request) *promql.QueryOpts {
return &promql.QueryOpts{
func extractQueryOpts(r *http.Request) (*promql.QueryOpts, error) {
opts := &promql.QueryOpts{
EnablePerStepStats: r.FormValue("stats") == "all",
}
if strDuration := r.FormValue("lookback_delta"); strDuration != "" {
duration, err := parseDuration(strDuration)
if err != nil {
return nil, fmt.Errorf("error parsing lookback delta duration: %w", err)
}
opts.LookbackDelta = duration
}
return opts, nil
}
func (api *API) queryRange(r *http.Request) (result apiFuncResult) {
@ -505,7 +516,10 @@ func (api *API) queryRange(r *http.Request) (result apiFuncResult) {
defer cancel()
}
opts := extractQueryOpts(r)
opts, err := extractQueryOpts(r)
if err != nil {
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
}
qry, err := api.QueryEngine.NewRangeQuery(api.Queryable, opts, r.FormValue("query"), start, end, step)
if err != nil {
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}

View File

@ -3410,3 +3410,66 @@ func TestGetGlobalURL(t *testing.T) {
})
}
}
func TestExtractQueryOpts(t *testing.T) {
tests := []struct {
name string
form url.Values
expect *promql.QueryOpts
err error
}{
{
name: "with stats all",
form: url.Values{
"stats": []string{"all"},
},
expect: &promql.QueryOpts{
EnablePerStepStats: true,
},
err: nil,
},
{
name: "with stats none",
form: url.Values{
"stats": []string{"none"},
},
expect: &promql.QueryOpts{
EnablePerStepStats: false,
},
err: nil,
},
{
name: "with lookback delta",
form: url.Values{
"stats": []string{"all"},
"lookback_delta": []string{"30s"},
},
expect: &promql.QueryOpts{
EnablePerStepStats: true,
LookbackDelta: 30 * time.Second,
},
err: nil,
},
{
name: "with invalid lookback delta",
form: url.Values{
"lookback_delta": []string{"invalid"},
},
expect: nil,
err: errors.New(`error parsing lookback delta duration: cannot parse "invalid" to a valid duration`),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
req := &http.Request{Form: test.form}
opts, err := extractQueryOpts(req)
require.Equal(t, test.expect, opts)
if test.err == nil {
require.NoError(t, err)
} else {
require.Equal(t, test.err.Error(), err.Error())
}
})
}
}