mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmalert:fix query request using rfc3339 format (#4577)
vmalert: consistently use time.RFC3339 format for time in queries Co-authored-by: hagen1778 <roman@victoriametrics.com>
This commit is contained in:
parent
1df3e548c1
commit
bca8ae034f
3 changed files with 42 additions and 32 deletions
|
@ -168,7 +168,7 @@ func (s *VMStorage) setPrometheusInstantReqParams(r *http.Request, query string,
|
||||||
// see https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1232
|
// see https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1232
|
||||||
timestamp = timestamp.Truncate(s.evaluationInterval)
|
timestamp = timestamp.Truncate(s.evaluationInterval)
|
||||||
}
|
}
|
||||||
q.Set("time", fmt.Sprintf("%d", timestamp.Unix()))
|
q.Set("time", timestamp.Format(time.RFC3339))
|
||||||
if !*disableStepParam && s.evaluationInterval > 0 { // set step as evaluationInterval by default
|
if !*disableStepParam && s.evaluationInterval > 0 { // set step as evaluationInterval by default
|
||||||
// always convert to seconds to keep compatibility with older
|
// always convert to seconds to keep compatibility with older
|
||||||
// Prometheus versions. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1943
|
// Prometheus versions. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1943
|
||||||
|
@ -191,8 +191,8 @@ func (s *VMStorage) setPrometheusRangeReqParams(r *http.Request, query string, s
|
||||||
r.URL.Path += "/api/v1/query_range"
|
r.URL.Path += "/api/v1/query_range"
|
||||||
}
|
}
|
||||||
q := r.URL.Query()
|
q := r.URL.Query()
|
||||||
q.Add("start", fmt.Sprintf("%d", start.Unix()))
|
q.Add("start", start.Format(time.RFC3339))
|
||||||
q.Add("end", fmt.Sprintf("%d", end.Unix()))
|
q.Add("end", end.Format(time.RFC3339))
|
||||||
if s.evaluationInterval > 0 { // set step as evaluationInterval by default
|
if s.evaluationInterval > 0 { // set step as evaluationInterval by default
|
||||||
// always convert to seconds to keep compatibility with older
|
// always convert to seconds to keep compatibility with older
|
||||||
// Prometheus versions. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1943
|
// Prometheus versions. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1943
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -50,8 +49,8 @@ func TestVMInstantQuery(t *testing.T) {
|
||||||
if timeParam == "" {
|
if timeParam == "" {
|
||||||
t.Errorf("expected 'time' in query param, got nil instead")
|
t.Errorf("expected 'time' in query param, got nil instead")
|
||||||
}
|
}
|
||||||
if _, err := strconv.ParseInt(timeParam, 10, 64); err != nil {
|
if _, err := time.Parse(time.RFC3339, timeParam); err != nil {
|
||||||
t.Errorf("failed to parse 'time' query param: %s", err)
|
t.Errorf("failed to parse 'time' query param %q: %s", timeParam, err)
|
||||||
}
|
}
|
||||||
switch c {
|
switch c {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -193,7 +192,6 @@ func TestVMInstantQuery(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
metricsEqual(t, res.Data, exp)
|
metricsEqual(t, res.Data, exp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVMInstantQueryWithRetry(t *testing.T) {
|
func TestVMInstantQueryWithRetry(t *testing.T) {
|
||||||
|
@ -309,14 +307,14 @@ func TestVMRangeQuery(t *testing.T) {
|
||||||
if startTS == "" {
|
if startTS == "" {
|
||||||
t.Errorf("expected 'start' in query param, got nil instead")
|
t.Errorf("expected 'start' in query param, got nil instead")
|
||||||
}
|
}
|
||||||
if _, err := strconv.ParseInt(startTS, 10, 64); err != nil {
|
if _, err := time.Parse(time.RFC3339, startTS); err != nil {
|
||||||
t.Errorf("failed to parse 'start' query param: %s", err)
|
t.Errorf("failed to parse 'start' query param: %s", err)
|
||||||
}
|
}
|
||||||
endTS := r.URL.Query().Get("end")
|
endTS := r.URL.Query().Get("end")
|
||||||
if endTS == "" {
|
if endTS == "" {
|
||||||
t.Errorf("expected 'end' in query param, got nil instead")
|
t.Errorf("expected 'end' in query param, got nil instead")
|
||||||
}
|
}
|
||||||
if _, err := strconv.ParseInt(endTS, 10, 64); err != nil {
|
if _, err := time.Parse(time.RFC3339, endTS); err != nil {
|
||||||
t.Errorf("failed to parse 'end' query param: %s", err)
|
t.Errorf("failed to parse 'end' query param: %s", err)
|
||||||
}
|
}
|
||||||
step := r.URL.Query().Get("step")
|
step := r.URL.Query().Get("step")
|
||||||
|
@ -455,8 +453,8 @@ func TestRequestParams(t *testing.T) {
|
||||||
false,
|
false,
|
||||||
&VMStorage{},
|
&VMStorage{},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
exp := fmt.Sprintf("query=%s&time=%d", query, timestamp.Unix())
|
exp := url.Values{"query": {query}, "time": {timestamp.Format(time.RFC3339)}}
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -464,8 +462,9 @@ func TestRequestParams(t *testing.T) {
|
||||||
true,
|
true,
|
||||||
&VMStorage{},
|
&VMStorage{},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
exp := fmt.Sprintf("end=%d&query=%s&start=%d", timestamp.Unix(), query, timestamp.Unix())
|
ts := timestamp.Format(time.RFC3339)
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
exp := url.Values{"query": {query}, "start": {ts}, "end": {ts}}
|
||||||
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -495,8 +494,8 @@ func TestRequestParams(t *testing.T) {
|
||||||
lookBack: time.Minute,
|
lookBack: time.Minute,
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
exp := fmt.Sprintf("query=%s&time=%d", query, timestamp.Add(-time.Minute).Unix())
|
exp := url.Values{"query": {query}, "time": {timestamp.Add(-time.Minute).Format(time.RFC3339)}}
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -508,8 +507,8 @@ func TestRequestParams(t *testing.T) {
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
evalInterval := 15 * time.Second
|
evalInterval := 15 * time.Second
|
||||||
tt := timestamp.Truncate(evalInterval)
|
tt := timestamp.Truncate(evalInterval)
|
||||||
exp := fmt.Sprintf("query=%s&step=%v&time=%d", query, evalInterval, tt.Unix())
|
exp := url.Values{"query": {query}, "step": {evalInterval.String()}, "time": {tt.Format(time.RFC3339)}}
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -523,8 +522,8 @@ func TestRequestParams(t *testing.T) {
|
||||||
evalInterval := 15 * time.Second
|
evalInterval := 15 * time.Second
|
||||||
tt := timestamp.Add(-time.Minute)
|
tt := timestamp.Add(-time.Minute)
|
||||||
tt = tt.Truncate(evalInterval)
|
tt = tt.Truncate(evalInterval)
|
||||||
exp := fmt.Sprintf("query=%s&step=%v&time=%d", query, evalInterval, tt.Unix())
|
exp := url.Values{"query": {query}, "step": {evalInterval.String()}, "time": {tt.Format(time.RFC3339)}}
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -534,8 +533,12 @@ func TestRequestParams(t *testing.T) {
|
||||||
queryStep: time.Minute,
|
queryStep: time.Minute,
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
exp := fmt.Sprintf("query=%s&step=%ds&time=%d", query, int(time.Minute.Seconds()), timestamp.Unix())
|
exp := url.Values{
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
"query": {query},
|
||||||
|
"step": {fmt.Sprintf("%ds", int(time.Minute.Seconds()))},
|
||||||
|
"time": {timestamp.Format(time.RFC3339)},
|
||||||
|
}
|
||||||
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -547,8 +550,8 @@ func TestRequestParams(t *testing.T) {
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
evalInterval := 3 * time.Hour
|
evalInterval := 3 * time.Hour
|
||||||
tt := timestamp.Truncate(evalInterval)
|
tt := timestamp.Truncate(evalInterval)
|
||||||
exp := fmt.Sprintf("query=%s&step=%ds&time=%d", query, int(evalInterval.Seconds()), tt.Unix())
|
exp := url.Values{"query": {query}, "step": {fmt.Sprintf("%ds", int(evalInterval.Seconds()))}, "time": {tt.Format(time.RFC3339)}}
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -558,8 +561,8 @@ func TestRequestParams(t *testing.T) {
|
||||||
extraParams: url.Values{"round_digits": {"10"}},
|
extraParams: url.Values{"round_digits": {"10"}},
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
exp := fmt.Sprintf("query=%s&round_digits=10&time=%d", query, timestamp.Unix())
|
exp := url.Values{"query": {query}, "round_digits": {"10"}, "time": {timestamp.Format(time.RFC3339)}}
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -572,9 +575,14 @@ func TestRequestParams(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
exp := fmt.Sprintf("end=%d&max_lookback=1h&nocache=1&query=%s&start=%d",
|
exp := url.Values{
|
||||||
timestamp.Unix(), query, timestamp.Unix())
|
"query": {query},
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
"end": {timestamp.Format(time.RFC3339)},
|
||||||
|
"start": {timestamp.Format(time.RFC3339)},
|
||||||
|
"nocache": {"1"},
|
||||||
|
"max_lookback": {"1h"},
|
||||||
|
}
|
||||||
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -584,8 +592,8 @@ func TestRequestParams(t *testing.T) {
|
||||||
QueryParams: url.Values{"round_digits": {"2"}},
|
QueryParams: url.Values{"round_digits": {"2"}},
|
||||||
}),
|
}),
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
exp := fmt.Sprintf("query=%s&round_digits=2&time=%d", query, timestamp.Unix())
|
exp := url.Values{"query": {query}, "round_digits": {"2"}, "time": {timestamp.Format(time.RFC3339)}}
|
||||||
checkEqualString(t, exp, r.URL.RawQuery)
|
checkEqualString(t, exp.Encode(), r.URL.RawQuery)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -627,7 +635,7 @@ func TestRequestParams(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHeaders(t *testing.T) {
|
func TestHeaders(t *testing.T) {
|
||||||
var testCases = []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
vmFn func() *VMStorage
|
vmFn func() *VMStorage
|
||||||
checkFn func(t *testing.T, r *http.Request)
|
checkFn func(t *testing.T, r *http.Request)
|
||||||
|
@ -692,7 +700,8 @@ func TestHeaders(t *testing.T) {
|
||||||
authCfg: cfg,
|
authCfg: cfg,
|
||||||
extraHeaders: []keyValue{
|
extraHeaders: []keyValue{
|
||||||
{key: "Authorization", value: "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="},
|
{key: "Authorization", value: "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="},
|
||||||
}}
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
checkFn: func(t *testing.T, r *http.Request) {
|
checkFn: func(t *testing.T, r *http.Request) {
|
||||||
u, p, _ := r.BasicAuth()
|
u, p, _ := r.BasicAuth()
|
||||||
|
|
|
@ -49,6 +49,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
|
||||||
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix application routing issues and problems with manual URL changes. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4408).
|
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix application routing issues and problems with manual URL changes. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4408).
|
||||||
* BUGFIX: add validation for invalid [partial RFC3339 timestamp formats](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#timestamp-formats) in query and export APIs.
|
* BUGFIX: add validation for invalid [partial RFC3339 timestamp formats](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#timestamp-formats) in query and export APIs.
|
||||||
* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): interrupt explore procedure in influx mode if vmctl found no numeric fields.
|
* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): interrupt explore procedure in influx mode if vmctl found no numeric fields.
|
||||||
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): use RFC3339 time format in query args instead of unix timestamp for all issued queries to Prometheus-like datasources.
|
||||||
|
|
||||||
## [v1.91.3](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.91.3)
|
## [v1.91.3](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.91.3)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue