Skip to content

Commit

Permalink
Support for single step metric query. (#3540)
Browse files Browse the repository at this point in the history
When splitting correctly steps in the frontend, some queries might be of a single step, e.g start == end.

This PR add supports for those queries, which are already supported by Cortex and Prometheus, but for some reason not Loki.

Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com>
  • Loading branch information
cyriltovena authored Mar 25, 2021
1 parent f49a510 commit 29a3240
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 32 deletions.
2 changes: 1 addition & 1 deletion pkg/loghttp/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func ParseRangeQuery(r *http.Request) (*RangeQuery, error) {
return nil, err
}

if result.End.Before(result.Start) || result.Start.Equal(result.End) {
if result.End.Before(result.Start) {
return nil, errEndBeforeStart
}

Expand Down
78 changes: 47 additions & 31 deletions pkg/loghttp/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,39 @@ func TestParseRangeQuery(t *testing.T) {
{"bad start", &http.Request{URL: mustParseURL(`?query={foo="bar"}&start=t`)}, nil, true},
{"bad end", &http.Request{URL: mustParseURL(`?query={foo="bar"}&end=t`)}, nil, true},
{"end before start", &http.Request{URL: mustParseURL(`?query={foo="bar"}&start=2016-06-10T21:42:24.760738998Z&end=2015-06-10T21:42:24.760738998Z`)}, nil, true},
{"end equal start", &http.Request{URL: mustParseURL(`?query={foo="bar"}&start=2016-06-10T21:42:24.760738998Z&end=2016-06-10T21:42:24.760738998Z`)}, nil, true},
{"bad limit", &http.Request{URL: mustParseURL(`?query={foo="bar"}&start=2016-06-10T21:42:24.760738998Z&end=2017-06-10T21:42:24.760738998Z&limit=h`)}, nil, true},
{"bad direction",
{
"bad direction",
&http.Request{
URL: mustParseURL(`?query={foo="bar"}&start=2016-06-10T21:42:24.760738998Z&end=2017-06-10T21:42:24.760738998Z&limit=100&direction=fw`),
}, nil, true},
{"bad step",
}, nil, true,
},
{
"bad step",
&http.Request{
URL: mustParseURL(`?query={foo="bar"}&start=2016-06-10T21:42:24.760738998Z&end=2017-06-10T21:42:24.760738998Z&limit=100&direction=FORWARD&step=h`),
}, nil, true},
{"negative step",
}, nil, true,
},
{
"negative step",
&http.Request{
URL: mustParseURL(`?query={foo="bar"}&start=2016-06-10T21:42:24.760738998Z&end=2017-06-10T21:42:24.760738998Z&limit=100&direction=BACKWARD&step=-1`),
}, nil, true},
{"too small step",
}, nil, true,
},
{
"too small step",
&http.Request{
URL: mustParseURL(`?query={foo="bar"}&start=2016-06-10T21:42:24.760738998Z&end=2017-06-10T21:42:24.760738998Z&limit=100&direction=BACKWARD&step=1`),
}, nil, true},
{"negative interval",
}, nil, true,
},
{
"negative interval",
&http.Request{
URL: mustParseURL(`?query={foo="bar"}&start=2016-06-10T21:42:24.760738998Z&end=2017-06-10T21:42:24.760738998Z&limit=100&direction=BACKWARD&step=1,interval=-1`),
}, nil, true},
{"good",
}, nil, true,
},
{
"good",
&http.Request{
URL: mustParseURL(`?query={foo="bar"}&start=2017-06-10T21:42:24.760738998Z&end=2017-07-10T21:42:24.760738998Z&limit=1000&direction=BACKWARD&step=3600`),
}, &RangeQuery{
Expand All @@ -56,7 +66,8 @@ func TestParseRangeQuery(t *testing.T) {
Start: time.Date(2017, 06, 10, 21, 42, 24, 760738998, time.UTC),
End: time.Date(2017, 07, 10, 21, 42, 24, 760738998, time.UTC),
Limit: 1000,
}, false},
}, false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -76,7 +87,6 @@ func TestParseRangeQuery(t *testing.T) {
}

func TestParseInstantQuery(t *testing.T) {

tests := []struct {
name string
r *http.Request
Expand All @@ -85,19 +95,23 @@ func TestParseInstantQuery(t *testing.T) {
}{
{"bad time", &http.Request{URL: mustParseURL(`?query={foo="bar"}&time=t`)}, nil, true},
{"bad limit", &http.Request{URL: mustParseURL(`?query={foo="bar"}&time=2016-06-10T21:42:24.760738998Z&limit=h`)}, nil, true},
{"bad direction",
{
"bad direction",
&http.Request{
URL: mustParseURL(`?query={foo="bar"}&time=2016-06-10T21:42:24.760738998Z&limit=100&direction=fw`),
}, nil, true},
{"good",
}, nil, true,
},
{
"good",
&http.Request{
URL: mustParseURL(`?query={foo="bar"}&time=2017-06-10T21:42:24.760738998Z&limit=1000&direction=BACKWARD`),
}, &InstantQuery{
Query: `{foo="bar"}`,
Direction: logproto.BACKWARD,
Ts: time.Date(2017, 06, 10, 21, 42, 24, 760738998, time.UTC),
Limit: 1000,
}, false},
}, false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -130,22 +144,24 @@ func TestStreams_ToProto(t *testing.T) {
want []logproto.Stream
}{
{"empty", nil, nil},
{"some", []Stream{
{
Labels: map[string]string{"foo": "bar"},
Entries: []Entry{
{Timestamp: time.Unix(0, 1), Line: "1"},
{Timestamp: time.Unix(0, 2), Line: "2"},
{
"some",
[]Stream{
{
Labels: map[string]string{"foo": "bar"},
Entries: []Entry{
{Timestamp: time.Unix(0, 1), Line: "1"},
{Timestamp: time.Unix(0, 2), Line: "2"},
},
},
},
{
Labels: map[string]string{"foo": "bar", "lvl": "error"},
Entries: []Entry{
{Timestamp: time.Unix(0, 3), Line: "3"},
{Timestamp: time.Unix(0, 4), Line: "4"},
{
Labels: map[string]string{"foo": "bar", "lvl": "error"},
Entries: []Entry{
{Timestamp: time.Unix(0, 3), Line: "3"},
{Timestamp: time.Unix(0, 4), Line: "4"},
},
},
},
},
[]logproto.Stream{
{
Labels: `{foo="bar"}`,
Expand Down

0 comments on commit 29a3240

Please sign in to comment.