@@ -19,6 +19,7 @@ import (
19
19
"github.com/prometheus/prometheus/promql/parser"
20
20
"github.com/prometheus/prometheus/storage"
21
21
"github.com/prometheus/prometheus/util/annotations"
22
+ v1 "github.com/prometheus/prometheus/web/api/v1"
22
23
"github.com/thanos-io/promql-engine/engine"
23
24
"github.com/thanos-io/promql-engine/logicalplan"
24
25
"github.com/thanos-io/thanos/pkg/strutil"
@@ -27,6 +28,7 @@ import (
27
28
"github.com/cortexproject/cortex/pkg/querier/batch"
28
29
"github.com/cortexproject/cortex/pkg/querier/lazyquery"
29
30
"github.com/cortexproject/cortex/pkg/querier/partialdata"
31
+ seriesset "github.com/cortexproject/cortex/pkg/querier/series"
30
32
querier_stats "github.com/cortexproject/cortex/pkg/querier/stats"
31
33
"github.com/cortexproject/cortex/pkg/tenant"
32
34
"github.com/cortexproject/cortex/pkg/util"
@@ -304,11 +306,12 @@ type querier struct {
304
306
ignoreMaxQueryLength bool
305
307
}
306
308
307
- func (q querier ) setupFromCtx (ctx context.Context ) (context.Context , * querier_stats.QueryStats , string , int64 , int64 , storage.Querier , []storage.Querier , error ) {
309
+ func (q querier ) setupFromCtx (ctx context.Context ) (context.Context , * querier_stats.QueryStats , string , int64 , int64 , storage.Querier , []storage.Querier , annotations. Annotations , error ) {
308
310
stats := querier_stats .FromContext (ctx )
309
311
userID , err := tenant .TenantID (ctx )
312
+ warnings := annotations .Annotations (nil )
310
313
if err != nil {
311
- return ctx , stats , userID , 0 , 0 , nil , nil , err
314
+ return ctx , stats , userID , 0 , 0 , nil , nil , warnings , err
312
315
}
313
316
314
317
q .limiterHolder .limiterInitializer .Do (func () {
@@ -317,14 +320,14 @@ func (q querier) setupFromCtx(ctx context.Context) (context.Context, *querier_st
317
320
318
321
ctx = limiter .AddQueryLimiterToContext (ctx , q .limiterHolder .limiter )
319
322
320
- mint , maxt , err := validateQueryTimeRange (ctx , userID , q .mint , q .maxt , q .limits , q .maxQueryIntoFuture )
323
+ mint , maxt , warnings , err := validateQueryTimeRange (ctx , userID , q .mint , q .maxt , q .limits , q .maxQueryIntoFuture )
321
324
if err != nil {
322
- return ctx , stats , userID , 0 , 0 , nil , nil , err
325
+ return ctx , stats , userID , 0 , 0 , nil , nil , warnings , err
323
326
}
324
327
325
328
dqr , err := q .distributor .Querier (mint , maxt )
326
329
if err != nil {
327
- return ctx , stats , userID , 0 , 0 , nil , nil , err
330
+ return ctx , stats , userID , 0 , 0 , nil , nil , warnings , err
328
331
}
329
332
metadataQuerier := dqr
330
333
@@ -340,18 +343,18 @@ func (q querier) setupFromCtx(ctx context.Context) (context.Context, *querier_st
340
343
341
344
cqr , err := s .Querier (mint , maxt )
342
345
if err != nil {
343
- return ctx , stats , userID , 0 , 0 , nil , nil , err
346
+ return ctx , stats , userID , 0 , 0 , nil , nil , warnings , err
344
347
}
345
348
346
349
queriers = append (queriers , cqr )
347
350
}
348
- return ctx , stats , userID , mint , maxt , metadataQuerier , queriers , nil
351
+ return ctx , stats , userID , mint , maxt , metadataQuerier , queriers , warnings , nil
349
352
}
350
353
351
354
// Select implements storage.Querier interface.
352
355
// The bool passed is ignored because the series is always sorted.
353
356
func (q querier ) Select (ctx context.Context , sortSeries bool , sp * storage.SelectHints , matchers ... * labels.Matcher ) storage.SeriesSet {
354
- ctx , stats , userID , mint , maxt , metadataQuerier , queriers , err := q .setupFromCtx (ctx )
357
+ ctx , stats , userID , mint , maxt , metadataQuerier , queriers , warnings , err := q .setupFromCtx (ctx )
355
358
if err == errEmptyTimeRange {
356
359
return storage .EmptySeriesSet ()
357
360
} else if err != nil {
@@ -370,7 +373,8 @@ func (q querier) Select(ctx context.Context, sortSeries bool, sp *storage.Select
370
373
}
371
374
372
375
if sp == nil {
373
- mint , maxt , err = validateQueryTimeRange (ctx , userID , mint , maxt , q .limits , q .maxQueryIntoFuture )
376
+ mint , maxt , newWarnings , err := validateQueryTimeRange (ctx , userID , mint , maxt , q .limits , q .maxQueryIntoFuture )
377
+ warnings .Merge (newWarnings )
374
378
if err == errEmptyTimeRange {
375
379
return storage .EmptySeriesSet ()
376
380
} else if err != nil {
@@ -383,7 +387,8 @@ func (q querier) Select(ctx context.Context, sortSeries bool, sp *storage.Select
383
387
// Validate query time range. Even if the time range has already been validated when we created
384
388
// the querier, we need to check it again here because the time range specified in hints may be
385
389
// different.
386
- startMs , endMs , err := validateQueryTimeRange (ctx , userID , sp .Start , sp .End , q .limits , q .maxQueryIntoFuture )
390
+ startMs , endMs , newWarnings , err := validateQueryTimeRange (ctx , userID , sp .Start , sp .End , q .limits , q .maxQueryIntoFuture )
391
+ warnings .Merge (newWarnings )
387
392
if err == errEmptyTimeRange {
388
393
return storage .NoopSeriesSet ()
389
394
} else if err != nil {
@@ -437,12 +442,12 @@ func (q querier) Select(ctx context.Context, sortSeries bool, sp *storage.Select
437
442
}
438
443
}
439
444
440
- return storage .NewMergeSeriesSet (result , 0 , storage .ChainedSeriesMerge )
445
+ return seriesset . NewSeriesSetWithWarnings ( storage .NewMergeSeriesSet (result , 0 , storage .ChainedSeriesMerge ), warnings )
441
446
}
442
447
443
448
// LabelValues implements storage.Querier.
444
449
func (q querier ) LabelValues (ctx context.Context , name string , hints * storage.LabelHints , matchers ... * labels.Matcher ) ([]string , annotations.Annotations , error ) {
445
- ctx , stats , userID , mint , maxt , _ , queriers , err := q .setupFromCtx (ctx )
450
+ ctx , stats , userID , mint , maxt , _ , queriers , warnings , err := q .setupFromCtx (ctx )
446
451
if err == errEmptyTimeRange {
447
452
return nil , nil , nil
448
453
} else if err != nil {
@@ -456,7 +461,8 @@ func (q querier) LabelValues(ctx context.Context, name string, hints *storage.La
456
461
startTime := model .Time (mint )
457
462
endTime := model .Time (maxt )
458
463
459
- if maxQueryLength := q .limits .MaxQueryLength (userID ); maxQueryLength > 0 && endTime .Sub (startTime ) > maxQueryLength {
464
+ maxQueryLength := q .limits .MaxQueryLength (userID )
465
+ if maxQueryLength > 0 && endTime .Sub (startTime ) > maxQueryLength {
460
466
limitErr := validation .LimitError (fmt .Sprintf (validation .ErrQueryTooLong , endTime .Sub (startTime ), maxQueryLength ))
461
467
return nil , nil , limitErr
462
468
}
@@ -466,9 +472,8 @@ func (q querier) LabelValues(ctx context.Context, name string, hints *storage.La
466
472
}
467
473
468
474
var (
469
- g , _ = errgroup .WithContext (ctx )
470
- sets = [][]string {}
471
- warnings = annotations .Annotations (nil )
475
+ g , _ = errgroup .WithContext (ctx )
476
+ sets = [][]string {}
472
477
473
478
resMtx sync.Mutex
474
479
)
@@ -505,7 +510,7 @@ func (q querier) LabelValues(ctx context.Context, name string, hints *storage.La
505
510
}
506
511
507
512
func (q querier ) LabelNames (ctx context.Context , hints * storage.LabelHints , matchers ... * labels.Matcher ) ([]string , annotations.Annotations , error ) {
508
- ctx , stats , userID , mint , maxt , _ , queriers , err := q .setupFromCtx (ctx )
513
+ ctx , stats , userID , mint , maxt , _ , queriers , warnings , err := q .setupFromCtx (ctx )
509
514
if err == errEmptyTimeRange {
510
515
return nil , nil , nil
511
516
} else if err != nil {
@@ -519,7 +524,8 @@ func (q querier) LabelNames(ctx context.Context, hints *storage.LabelHints, matc
519
524
startTime := model .Time (mint )
520
525
endTime := model .Time (maxt )
521
526
522
- if maxQueryLength := q .limits .MaxQueryLength (userID ); maxQueryLength > 0 && endTime .Sub (startTime ) > maxQueryLength {
527
+ maxQueryLength := q .limits .MaxQueryLength (userID )
528
+ if maxQueryLength > 0 && endTime .Sub (startTime ) > maxQueryLength {
523
529
limitErr := validation .LimitError (fmt .Sprintf (validation .ErrQueryTooLong , endTime .Sub (startTime ), maxQueryLength ))
524
530
return nil , nil , limitErr
525
531
}
@@ -529,9 +535,8 @@ func (q querier) LabelNames(ctx context.Context, hints *storage.LabelHints, matc
529
535
}
530
536
531
537
var (
532
- g , _ = errgroup .WithContext (ctx )
533
- sets = [][]string {}
534
- warnings = annotations .Annotations (nil )
538
+ g , _ = errgroup .WithContext (ctx )
539
+ sets = [][]string {}
535
540
536
541
resMtx sync.Mutex
537
542
)
@@ -622,11 +627,26 @@ func UseBeforeTimestampQueryable(queryable storage.Queryable, ts time.Time) Quer
622
627
}
623
628
}
624
629
625
- func validateQueryTimeRange (ctx context.Context , userID string , startMs , endMs int64 , limits * validation.Overrides , maxQueryIntoFuture time.Duration ) (int64 , int64 , error ) {
630
+ func validateQueryTimeRange (ctx context.Context , userID string , startMs , endMs int64 , limits * validation.Overrides , maxQueryIntoFuture time.Duration ) (int64 , int64 , annotations.Annotations , error ) {
631
+ warnings := annotations .Annotations (nil )
626
632
now := model .Now ()
627
633
startTime := model .Time (startMs )
628
634
endTime := model .Time (endMs )
629
635
636
+ // Truncate time range to MaxQueryLength if time parameters are unspecified
637
+ maxQueryLength := limits .MaxQueryLength (userID )
638
+ if maxQueryLength > 0 && (util .TimeToMillis (v1 .MinTime ) == startMs || util .TimeToMillis (v1 .MaxTime ) == endMs ) {
639
+ startTime = now .Add (- maxQueryLength )
640
+ endTime = now
641
+ warnings .Add (validation .LimitError (fmt .Sprintf (validation .WarningTruncatedQueryLength , maxQueryLength )))
642
+
643
+ // Make sure to log it in traces to ease debugging.
644
+ level .Debug (spanlogger .FromContext (ctx )).Log (
645
+ "msg" , "no time range specified, response truncated to maximum query length" ,
646
+ "updatedStart" , util .FormatTimeModel (startTime ),
647
+ "updatedEnd" , util .FormatTimeModel (endTime ))
648
+ }
649
+
630
650
// Clamp time range based on max query into future.
631
651
if maxQueryIntoFuture > 0 && endTime .After (now .Add (maxQueryIntoFuture )) {
632
652
origEndTime := endTime
@@ -639,7 +659,7 @@ func validateQueryTimeRange(ctx context.Context, userID string, startMs, endMs i
639
659
"updated" , util .FormatTimeModel (endTime ))
640
660
641
661
if endTime .Before (startTime ) {
642
- return 0 , 0 , errEmptyTimeRange
662
+ return 0 , 0 , warnings , errEmptyTimeRange
643
663
}
644
664
}
645
665
@@ -655,7 +675,7 @@ func validateQueryTimeRange(ctx context.Context, userID string, startMs, endMs i
655
675
"updated" , util .FormatTimeModel (startTime ))
656
676
657
677
if endTime .Before (startTime ) {
658
- return 0 , 0 , errEmptyTimeRange
678
+ return 0 , 0 , warnings , errEmptyTimeRange
659
679
}
660
680
}
661
681
@@ -664,7 +684,7 @@ func validateQueryTimeRange(ctx context.Context, userID string, startMs, endMs i
664
684
startTime = 0
665
685
}
666
686
667
- return int64 (startTime ), int64 (endTime ), nil
687
+ return int64 (startTime ), int64 (endTime ), warnings , nil
668
688
}
669
689
670
690
func EnableExperimentalPromQLFunctions (enablePromQLExperimentalFunctions , enableHoltWinters bool ) {
0 commit comments