github.com/go-graphite/carbonapi@v0.17.0/expr/functions/aggregateSeriesLists/function.go (about) 1 package aggregateSeriesLists 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/go-graphite/carbonapi/expr/consolidations" 8 "github.com/go-graphite/carbonapi/expr/helper" 9 "github.com/go-graphite/carbonapi/expr/interfaces" 10 "github.com/go-graphite/carbonapi/expr/types" 11 "github.com/go-graphite/carbonapi/pkg/parser" 12 ) 13 14 type aggregateSeriesLists struct{} 15 16 func GetOrder() interfaces.Order { 17 return interfaces.Any 18 } 19 20 func New(_ string) []interfaces.FunctionMetadata { 21 f := &aggregateSeriesLists{} 22 res := make([]interfaces.FunctionMetadata, 0) 23 for _, n := range []string{"aggregateSeriesLists"} { 24 res = append(res, interfaces.FunctionMetadata{Name: n, F: f}) 25 } 26 return res 27 } 28 29 func (f *aggregateSeriesLists) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { 30 if e.ArgsLen() < 3 { 31 return nil, parser.ErrMissingArgument 32 } 33 34 seriesList1, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) 35 if err != nil { 36 return nil, err 37 } 38 seriesList2, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) 39 if err != nil { 40 return nil, err 41 } 42 43 if len(seriesList1) != len(seriesList2) { 44 return nil, fmt.Errorf("seriesListFirstPos and seriesListSecondPos must have equal length") 45 } else if len(seriesList1) == 0 { 46 return make([]*types.MetricData, 0, 0), nil 47 } 48 49 aggFuncStr, err := e.GetStringArg(2) 50 if err != nil { 51 return nil, err 52 } 53 aggFunc, ok := consolidations.ConsolidationToFunc[aggFuncStr] 54 if !ok { 55 return nil, fmt.Errorf("unsupported consolidation function %s", aggFuncStr) 56 } 57 58 xFilesFactor, err := e.GetFloatArgDefault(3, float64(seriesList1[0].XFilesFactor)) 59 if err != nil { 60 return nil, err 61 } 62 63 results := make([]*types.MetricData, 0, len(seriesList1)) 64 65 for i, series1 := range seriesList1 { 66 series2 := seriesList2[i] 67 68 r, err := helper.AggregateSeries(e, []*types.MetricData{series1.CopyLink(), series2.CopyLink()}, aggFunc, xFilesFactor, false) 69 if err != nil { 70 return nil, err 71 } 72 73 results = append(results, r[0]) 74 } 75 76 return results, nil 77 } 78 79 func (f *aggregateSeriesLists) Description() map[string]types.FunctionDescription { 80 return map[string]types.FunctionDescription{ 81 "aggregateSeriesLists": { 82 Name: "aggregateSeriesLists", 83 Function: "aggregateSeriesLists(seriesListFirstPos, seriesListSecondPos, func, xFilesFactor=None)", 84 Description: "Iterates over a two lists and aggregates using specified function list1[0] to list2[0], list1[1] to list2[1] and so on. The lists will need to be the same length.", 85 Module: "graphite.render.functions", 86 Group: "Combine", 87 Params: []types.FunctionParam{ 88 { 89 Name: "seriesListFirstPos", 90 Type: types.SeriesList, 91 Required: true, 92 }, 93 { 94 Name: "seriesListSecondPos", 95 Type: types.SeriesList, 96 Required: true, 97 }, 98 { 99 Name: "func", 100 Type: types.AggFunc, 101 Required: true, 102 }, 103 { 104 Name: "xFilesFactor", 105 Type: types.Float, 106 Required: false, 107 }, 108 }, 109 }, 110 } 111 }