@@ -33,6 +33,7 @@ import (
33
33
"github.com/prometheus/prometheus/storage"
34
34
"github.com/prometheus/prometheus/util/annotations"
35
35
"github.com/prometheus/prometheus/util/stats"
36
+ "github.com/thanos-io/promql-engine/tracing"
36
37
)
37
38
38
39
type QueryType int
@@ -50,6 +51,16 @@ const (
50
51
stepsBatch = 10
51
52
)
52
53
54
+ func (q QueryType ) String () string {
55
+ switch q {
56
+ case InstantQuery :
57
+ return "InstantQuery"
58
+ case RangeQuery :
59
+ return "RangeQuery"
60
+ }
61
+
62
+ return "Unknown"
63
+ }
53
64
func IsUnimplemented (err error ) bool {
54
65
return errors .Is (err , parse .ErrNotSupportedExpr ) || errors .Is (err , parse .ErrNotImplemented )
55
66
}
@@ -237,14 +248,21 @@ type Engine struct {
237
248
}
238
249
239
250
func (e * Engine ) MakeInstantQuery (ctx context.Context , q storage.Queryable , opts * QueryOpts , qs string , ts time.Time ) (promql.Query , error ) {
251
+ span , ctx := tracing .StartSpanFromContext (ctx , "engine.MakeInstantQuery" )
252
+ defer span .Finish ()
253
+ span .SetTag ("query" , qs )
254
+ span .SetTag ("timestamp" , ts .Unix ())
255
+
240
256
idx , err := e .activeQueryTracker .Insert (ctx , qs )
241
257
if err != nil {
258
+ tracing .LogError (span , err )
242
259
return nil , err
243
260
}
244
261
defer e .activeQueryTracker .Delete (idx )
245
262
246
263
expr , err := parser .NewParser (qs , parser .WithFunctions (e .functions )).ParseExpr ()
247
264
if err != nil {
265
+ tracing .LogError (span , err )
248
266
return nil , err
249
267
}
250
268
// determine sorting order before optimizers run, we do this by looking for "sort"
@@ -254,23 +272,35 @@ func (e *Engine) MakeInstantQuery(ctx context.Context, q storage.Queryable, opts
254
272
255
273
qOpts := e .makeQueryOpts (ts , ts , 0 , opts )
256
274
if qOpts .StepsBatch > 64 {
257
- return nil , ErrStepsBatchTooLarge
275
+ err := ErrStepsBatchTooLarge
276
+ tracing .LogError (span , err )
277
+ return nil , err
258
278
}
259
279
260
280
planOpts := logicalplan.PlanOptions {
261
281
DisableDuplicateLabelCheck : e .disableDuplicateLabelChecks ,
262
282
}
283
+
284
+ optimizeSpan := tracing .ChildSpan (span , "optimize_plan" )
263
285
lplan , warns := logicalplan .NewFromAST (expr , qOpts , planOpts ).Optimize (e .getLogicalOptimizers (opts ))
286
+ optimizeSpan .Finish ()
287
+
288
+ ctx = warnings .NewContext (ctx )
289
+ defer func () { warns .Merge (warnings .FromContext (ctx )) }()
264
290
291
+ scannersSpan := tracing .ChildSpan (span , "create_storage_scanners" )
265
292
scanners , err := e .storageScanners (q , qOpts , lplan )
293
+ scannersSpan .Finish ()
266
294
if err != nil {
295
+ tracing .LogError (span , err )
267
296
return nil , errors .Wrap (err , "creating storage scanners" )
268
297
}
269
298
270
- ctx = warnings .NewContext (ctx )
271
- defer func () { warns .Merge (warnings .FromContext (ctx )) }()
299
+ execSpan := tracing .ChildSpan (span , "create_execution" )
272
300
exec , err := execution .New (ctx , lplan .Root (), scanners , qOpts )
301
+ execSpan .Finish ()
273
302
if err != nil {
303
+ tracing .LogError (span , err )
274
304
return nil , err
275
305
}
276
306
e .metrics .totalQueries .Inc ()
@@ -336,39 +366,62 @@ func (e *Engine) MakeInstantQueryFromPlan(ctx context.Context, q storage.Queryab
336
366
}
337
367
338
368
func (e * Engine ) MakeRangeQuery (ctx context.Context , q storage.Queryable , opts * QueryOpts , qs string , start , end time.Time , step time.Duration ) (promql.Query , error ) {
369
+ span , ctx := tracing .StartSpanFromContext (ctx , "engine.MakeRangeQuery" )
370
+ defer span .Finish ()
371
+ span .SetTag ("query" , qs )
372
+ span .SetTag ("start" , start .Unix ())
373
+ span .SetTag ("end" , end .Unix ())
374
+ span .SetTag ("step" , step .String ())
375
+
339
376
idx , err := e .activeQueryTracker .Insert (ctx , qs )
340
377
if err != nil {
378
+ tracing .LogError (span , err )
341
379
return nil , err
342
380
}
343
381
defer e .activeQueryTracker .Delete (idx )
344
382
345
383
expr , err := parser .NewParser (qs , parser .WithFunctions (e .functions )).ParseExpr ()
346
384
if err != nil {
385
+ tracing .LogError (span , err )
347
386
return nil , err
348
387
}
349
388
350
389
// Use same check as Prometheus for range queries.
351
390
if expr .Type () != parser .ValueTypeVector && expr .Type () != parser .ValueTypeScalar {
352
- return nil , errors .Newf ("invalid expression type %q for range query, must be Scalar or instant Vector" , parser .DocumentedType (expr .Type ()))
391
+ err := errors .Newf ("invalid expression type %q for range query, must be Scalar or instant Vector" , parser .DocumentedType (expr .Type ()))
392
+ tracing .LogError (span , err )
393
+ return nil , err
353
394
}
354
395
qOpts := e .makeQueryOpts (start , end , step , opts )
355
396
if qOpts .StepsBatch > 64 {
356
- return nil , ErrStepsBatchTooLarge
397
+ err := ErrStepsBatchTooLarge
398
+ tracing .LogError (span , err )
399
+ return nil , err
357
400
}
358
401
planOpts := logicalplan.PlanOptions {
359
402
DisableDuplicateLabelCheck : e .disableDuplicateLabelChecks ,
360
403
}
404
+
405
+ optimizeSpan := tracing .ChildSpan (span , "optimize_plan" )
361
406
lplan , warns := logicalplan .NewFromAST (expr , qOpts , planOpts ).Optimize (e .getLogicalOptimizers (opts ))
407
+ optimizeSpan .Finish ()
362
408
363
409
ctx = warnings .NewContext (ctx )
364
410
defer func () { warns .Merge (warnings .FromContext (ctx )) }()
411
+
412
+ scannersSpan := tracing .ChildSpan (span , "create_storage_scanners" )
365
413
scnrs , err := e .storageScanners (q , qOpts , lplan )
414
+ scannersSpan .Finish ()
366
415
if err != nil {
416
+ tracing .LogError (span , err )
367
417
return nil , errors .Wrap (err , "creating storage scanners" )
368
418
}
369
419
420
+ execSpan := tracing .ChildSpan (span , "create_execution" )
370
421
exec , err := execution .New (ctx , lplan .Root (), scnrs , qOpts )
422
+ execSpan .Finish ()
371
423
if err != nil {
424
+ tracing .LogError (span , err )
372
425
return nil , err
373
426
}
374
427
e .metrics .totalQueries .Inc ()
@@ -528,8 +581,21 @@ type compatibilityQuery struct {
528
581
}
529
582
530
583
func (q * compatibilityQuery ) Exec (ctx context.Context ) (ret * promql.Result ) {
584
+ span , ctx := tracing .StartSpanFromContext (ctx , "compatibilityQuery.Exec" )
585
+ defer span .Finish ()
586
+ span .SetTag ("query_type" , q .t .String ())
587
+ span .SetTag ("query_string" , q .String ())
588
+ if q .t == RangeQuery {
589
+ span .SetTag ("start" , q .start )
590
+ span .SetTag ("end" , q .end )
591
+ span .SetTag ("step" , q .step )
592
+ } else {
593
+ span .SetTag ("timestamp" , q .ts )
594
+ }
595
+
531
596
idx , err := q .engine .activeQueryTracker .Insert (ctx , q .String ())
532
597
if err != nil {
598
+ tracing .LogError (span , err )
533
599
return & promql.Result {Err : err }
534
600
}
535
601
defer q .engine .activeQueryTracker .Delete (idx )
@@ -557,23 +623,32 @@ func (q *compatibilityQuery) Exec(ctx context.Context) (ret *promql.Result) {
557
623
defer cancel ()
558
624
q .cancel = cancel
559
625
626
+ seriesSpan := tracing .ChildSpan (span , "get_series" )
560
627
resultSeries , err := q .Query .exec .Series (ctx )
628
+ seriesSpan .Finish ()
561
629
if err != nil {
630
+ tracing .LogError (span , err )
562
631
return newErrResult (ret , err )
563
632
}
564
633
565
634
series := make ([]promql.Series , len (resultSeries ))
566
635
for i , s := range resultSeries {
567
636
series [i ].Metric = s
568
637
}
638
+
639
+ samplesSpan := tracing .ChildSpan (span , "collect_samples" )
569
640
loop:
570
641
for {
571
642
select {
572
643
case <- ctx .Done ():
644
+ tracing .LogError (samplesSpan , ctx .Err ())
645
+ samplesSpan .Finish ()
573
646
return newErrResult (ret , ctx .Err ())
574
647
default :
575
648
r , err := q .Query .exec .Next (ctx )
576
649
if err != nil {
650
+ tracing .LogError (samplesSpan , err )
651
+ samplesSpan .Finish ()
577
652
return newErrResult (ret , err )
578
653
}
579
654
if r == nil {
@@ -610,6 +685,10 @@ loop:
610
685
q .Query .exec .GetPool ().PutVectors (r )
611
686
}
612
687
}
688
+ samplesSpan .Finish ()
689
+
690
+ resultSpan := tracing .ChildSpan (span , "prepare_result" )
691
+ defer resultSpan .Finish ()
613
692
614
693
// For range Query we expect always a Matrix value type.
615
694
if q .t == RangeQuery {
@@ -623,7 +702,9 @@ loop:
623
702
sort .Sort (matrix )
624
703
ret .Value = matrix
625
704
if matrix .ContainsSameLabelset () {
626
- return newErrResult (ret , extlabels .ErrDuplicateLabelSet )
705
+ err := extlabels .ErrDuplicateLabelSet
706
+ tracing .LogError (resultSpan , err )
707
+ return newErrResult (ret , err )
627
708
}
628
709
return ret
629
710
}
@@ -657,7 +738,9 @@ loop:
657
738
}
658
739
sort .Slice (vector , q .resultSort .comparer (& vector ))
659
740
if vector .ContainsSameLabelset () {
660
- return newErrResult (ret , extlabels .ErrDuplicateLabelSet )
741
+ err := extlabels .ErrDuplicateLabelSet
742
+ tracing .LogError (resultSpan , err )
743
+ return newErrResult (ret , err )
661
744
}
662
745
result = vector
663
746
case parser .ValueTypeScalar :
@@ -667,7 +750,9 @@ loop:
667
750
}
668
751
result = promql.Scalar {V : v , T : q .ts .UnixMilli ()}
669
752
default :
670
- panic (errors .Newf ("new.Engine.exec: unexpected expression type %q" , q .plan .Root ().ReturnType ()))
753
+ err := errors .Newf ("new.Engine.exec: unexpected expression type %q" , q .plan .Root ().ReturnType ())
754
+ tracing .LogError (resultSpan , err )
755
+ panic (err )
671
756
}
672
757
673
758
ret .Value = result
0 commit comments