mirror of https://github.com/grafana/loki
feat: query persisted patterns (#17980)
Signed-off-by: Trevor Whitney <trevorjwhitney@gmail.com>pull/17990/head
parent
fd7321c88b
commit
fdcc12da4d
@ -0,0 +1,104 @@ |
|||||||
|
package querier |
||||||
|
|
||||||
|
import "time" |
||||||
|
|
||||||
|
type QueryInterval struct { |
||||||
|
start, end time.Time |
||||||
|
} |
||||||
|
|
||||||
|
func BuildQueryIntervalsWithLookback(cfg Config, queryStart, queryEnd time.Time, queryIngestersWithin time.Duration) (*QueryInterval, *QueryInterval) { |
||||||
|
// limitQueryInterval is a flag for whether store queries should be limited to start time of ingester queries.
|
||||||
|
limitQueryInterval := cfg.IngesterQueryStoreMaxLookback != 0 |
||||||
|
|
||||||
|
// ingesterMLB having -1 means query ingester for whole duration.
|
||||||
|
ingesterMLB := calculateIngesterMaxLookbackPeriod(cfg, queryIngestersWithin) |
||||||
|
|
||||||
|
// query ingester for whole duration.
|
||||||
|
if ingesterMLB == -1 { |
||||||
|
i := &QueryInterval{ |
||||||
|
start: queryStart, |
||||||
|
end: queryEnd, |
||||||
|
} |
||||||
|
|
||||||
|
if limitQueryInterval { |
||||||
|
// query only ingesters.
|
||||||
|
return i, nil |
||||||
|
} |
||||||
|
|
||||||
|
// query both stores and ingesters without limiting the query interval.
|
||||||
|
return i, i |
||||||
|
} |
||||||
|
|
||||||
|
ingesterQueryWithinRange := isWithinIngesterMaxLookbackPeriod(ingesterMLB, queryEnd) |
||||||
|
|
||||||
|
// see if there is an overlap between ingester query interval and actual query interval, if not just do the store query.
|
||||||
|
if !ingesterQueryWithinRange { |
||||||
|
return nil, &QueryInterval{ |
||||||
|
start: queryStart, |
||||||
|
end: queryEnd, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ingesterOldestStartTime := time.Now().Add(-ingesterMLB) |
||||||
|
|
||||||
|
// if there is an overlap and we are not limiting the query interval then do both store and ingester query for whole query interval.
|
||||||
|
if !limitQueryInterval { |
||||||
|
i := &QueryInterval{ |
||||||
|
start: queryStart, |
||||||
|
end: queryEnd, |
||||||
|
} |
||||||
|
return i, i |
||||||
|
} |
||||||
|
|
||||||
|
// since we are limiting the query interval, check if the query touches just the ingesters, if yes then query just the ingesters.
|
||||||
|
if ingesterOldestStartTime.Before(queryStart) { |
||||||
|
return &QueryInterval{ |
||||||
|
start: queryStart, |
||||||
|
end: queryEnd, |
||||||
|
}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// limit the start of ingester query interval to ingesterOldestStartTime.
|
||||||
|
ingesterQueryInterval := &QueryInterval{ |
||||||
|
start: ingesterOldestStartTime, |
||||||
|
end: queryEnd, |
||||||
|
} |
||||||
|
|
||||||
|
// limit the end of ingester query interval to ingesterOldestStartTime.
|
||||||
|
storeQueryInterval := &QueryInterval{ |
||||||
|
start: queryStart, |
||||||
|
end: ingesterOldestStartTime, |
||||||
|
} |
||||||
|
|
||||||
|
// query touches only ingester query interval so do not do store query.
|
||||||
|
if storeQueryInterval.start.After(storeQueryInterval.end) { |
||||||
|
storeQueryInterval = nil |
||||||
|
} |
||||||
|
|
||||||
|
return ingesterQueryInterval, storeQueryInterval |
||||||
|
} |
||||||
|
|
||||||
|
func calculateIngesterMaxLookbackPeriod(cfg Config, queryIngestersWithin time.Duration) time.Duration { |
||||||
|
mlb := time.Duration(-1) |
||||||
|
if cfg.IngesterQueryStoreMaxLookback != 0 { |
||||||
|
// IngesterQueryStoreMaxLookback takes the precedence over QueryIngestersWithin while also limiting the store query range.
|
||||||
|
mlb = cfg.IngesterQueryStoreMaxLookback |
||||||
|
} else if queryIngestersWithin != 0 { |
||||||
|
mlb = queryIngestersWithin |
||||||
|
} |
||||||
|
|
||||||
|
return mlb |
||||||
|
} |
||||||
|
|
||||||
|
func isWithinIngesterMaxLookbackPeriod(maxLookback time.Duration, queryEnd time.Time) bool { |
||||||
|
// if no lookback limits are configured, always consider this within the range of the lookback period
|
||||||
|
if maxLookback <= 0 { |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
// find the first instance that we would want to query the ingester from...
|
||||||
|
ingesterOldestStartTime := time.Now().Add(-maxLookback) |
||||||
|
|
||||||
|
// ...and if the query range ends before that, don't query the ingester
|
||||||
|
return queryEnd.After(ingesterOldestStartTime) |
||||||
|
} |
Loading…
Reference in new issue