mirror of https://github.com/grafana/loki
Feature/per tenant splitby (#1565)
* split by overrides by tenant * tenant aware metric query splitting * consistent split_queries_by_interval naming * updates readme * fixes rebase conflict * refactor to support limit based splitby intervals in all locations * simplifies limits cachesplitter * fixes commentpull/1616/head
parent
891eae9af8
commit
3e075497cd
@ -0,0 +1,56 @@ |
||||
package queryrange |
||||
|
||||
import ( |
||||
"fmt" |
||||
"time" |
||||
|
||||
"github.com/cortexproject/cortex/pkg/querier/queryrange" |
||||
) |
||||
|
||||
// Limits extends the cortex limits interface with support for per tenant splitby parameters
|
||||
type Limits interface { |
||||
queryrange.Limits |
||||
QuerySplitDuration(string) time.Duration |
||||
} |
||||
|
||||
type limits struct { |
||||
Limits |
||||
splitDuration time.Duration |
||||
} |
||||
|
||||
func (l limits) QuerySplitDuration(user string) time.Duration { |
||||
dur := l.Limits.QuerySplitDuration(user) |
||||
if dur == 0 { |
||||
return l.splitDuration |
||||
} |
||||
return dur |
||||
} |
||||
|
||||
// WithDefaults will construct a Limits with a default value for QuerySplitDuration when no overrides are present.
|
||||
func WithDefaultLimits(l Limits, conf queryrange.Config) Limits { |
||||
res := limits{ |
||||
Limits: l, |
||||
} |
||||
|
||||
if conf.SplitQueriesByDay { |
||||
res.splitDuration = 24 * time.Hour |
||||
} |
||||
|
||||
if conf.SplitQueriesByInterval != 0 { |
||||
res.splitDuration = conf.SplitQueriesByInterval |
||||
} |
||||
|
||||
return res |
||||
} |
||||
|
||||
// cacheKeyLimits intersects Limits and CacheSplitter
|
||||
type cacheKeyLimits struct { |
||||
Limits |
||||
} |
||||
|
||||
// GenerateCacheKey will panic if it encounters a 0 split duration. We ensure against this by requiring
|
||||
// a nonzero split interval when caching is enabled
|
||||
func (l cacheKeyLimits) GenerateCacheKey(userID string, r queryrange.Request) string { |
||||
currentInterval := r.GetStart() / int64(l.QuerySplitDuration(userID)/time.Millisecond) |
||||
return fmt.Sprintf("%s:%s:%d:%d", userID, r.GetQuery(), r.GetStep(), currentInterval) |
||||
} |
@ -0,0 +1,34 @@ |
||||
package queryrange |
||||
|
||||
import ( |
||||
"testing" |
||||
"time" |
||||
|
||||
"github.com/cortexproject/cortex/pkg/querier/queryrange" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
func TestWithDefaultLimits(t *testing.T) { |
||||
l := fakeLimits{ |
||||
splits: map[string]time.Duration{"a": time.Minute}, |
||||
} |
||||
|
||||
require.Equal(t, l.QuerySplitDuration("a"), time.Minute) |
||||
require.Equal(t, l.QuerySplitDuration("b"), time.Duration(0)) |
||||
|
||||
wrapped := WithDefaultLimits(l, queryrange.Config{ |
||||
SplitQueriesByDay: true, |
||||
}) |
||||
|
||||
require.Equal(t, wrapped.QuerySplitDuration("a"), time.Minute) |
||||
require.Equal(t, wrapped.QuerySplitDuration("b"), 24*time.Hour) |
||||
|
||||
wrapped = WithDefaultLimits(l, queryrange.Config{ |
||||
SplitQueriesByDay: true, // should be overridden by SplitQueriesByInterval
|
||||
SplitQueriesByInterval: time.Hour, |
||||
}) |
||||
|
||||
require.Equal(t, wrapped.QuerySplitDuration("a"), time.Minute) |
||||
require.Equal(t, wrapped.QuerySplitDuration("b"), time.Hour) |
||||
|
||||
} |
Loading…
Reference in new issue