github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/logql/syntax/extractor.go (about)

     1  package syntax
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  
     7  	"github.com/grafana/loki/pkg/logql/log"
     8  )
     9  
    10  const UnsupportedErr = "unsupported range vector aggregation operation: %s"
    11  
    12  func (r RangeAggregationExpr) Extractor() (log.SampleExtractor, error) {
    13  	return r.extractor(nil)
    14  }
    15  
    16  // extractor creates a SampleExtractor but allows for the grouping to be overridden.
    17  func (r RangeAggregationExpr) extractor(override *Grouping) (log.SampleExtractor, error) {
    18  	if err := r.validate(); err != nil {
    19  		return nil, err
    20  	}
    21  	var groups []string
    22  	var without bool
    23  	var noLabels bool
    24  
    25  	if r.Grouping != nil {
    26  		groups = r.Grouping.Groups
    27  		without = r.Grouping.Without
    28  		if len(groups) == 0 {
    29  			noLabels = true
    30  		}
    31  	}
    32  
    33  	// uses override if it exists
    34  	if override != nil {
    35  		groups = override.Groups
    36  		without = override.Without
    37  		if len(groups) == 0 {
    38  			noLabels = true
    39  		}
    40  	}
    41  
    42  	// absent_over_time cannot be grouped (yet?), so set noLabels=true
    43  	// to make extraction more efficient and less likely to strip per query series limits.
    44  	if r.Operation == OpRangeTypeAbsent {
    45  		noLabels = true
    46  	}
    47  
    48  	sort.Strings(groups)
    49  
    50  	var stages []log.Stage
    51  	if p, ok := r.Left.Left.(*PipelineExpr); ok {
    52  		// if the expression is a pipeline then take all stages into account first.
    53  		st, err := p.MultiStages.stages()
    54  		if err != nil {
    55  			return nil, err
    56  		}
    57  		stages = st
    58  	}
    59  	// unwrap...means we want to extract metrics from labels.
    60  	if r.Left.Unwrap != nil {
    61  		var convOp string
    62  		switch r.Left.Unwrap.Operation {
    63  		case OpConvBytes:
    64  			convOp = log.ConvertBytes
    65  		case OpConvDuration, OpConvDurationSeconds:
    66  			convOp = log.ConvertDuration
    67  		default:
    68  			convOp = log.ConvertFloat
    69  		}
    70  
    71  		return log.LabelExtractorWithStages(
    72  			r.Left.Unwrap.Identifier,
    73  			convOp, groups, without, noLabels, stages,
    74  			log.ReduceAndLabelFilter(r.Left.Unwrap.PostFilters),
    75  		)
    76  	}
    77  	// otherwise we extract metrics from the log line.
    78  	switch r.Operation {
    79  	case OpRangeTypeRate, OpRangeTypeCount, OpRangeTypeAbsent:
    80  		return log.NewLineSampleExtractor(log.CountExtractor, stages, groups, without, noLabels)
    81  	case OpRangeTypeBytes, OpRangeTypeBytesRate:
    82  		return log.NewLineSampleExtractor(log.BytesExtractor, stages, groups, without, noLabels)
    83  	default:
    84  		return nil, fmt.Errorf(UnsupportedErr, r.Operation)
    85  	}
    86  }