github.com/go-graphite/carbonapi@v0.17.0/expr/functions/filter/function.go (about) 1 package filter 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 filterSeries struct{} 15 16 func GetOrder() interfaces.Order { 17 return interfaces.Any 18 } 19 20 func New(configFile string) []interfaces.FunctionMetadata { 21 f := &filterSeries{} 22 res := make([]interfaces.FunctionMetadata, 0) 23 for _, n := range []string{"filterSeries"} { 24 res = append(res, interfaces.FunctionMetadata{Name: n, F: f}) 25 } 26 return res 27 } 28 29 var supportedOperators = map[string]struct{}{ 30 "=": struct{}{}, 31 "!=": struct{}{}, 32 ">": struct{}{}, 33 ">=": struct{}{}, 34 "<": struct{}{}, 35 "<=": struct{}{}, 36 } 37 38 // filterSeries(*seriesLists) 39 func (f *filterSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { 40 if e.ArgsLen() < 4 { 41 return nil, parser.ErrMissingArgument 42 } 43 44 args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) 45 if err != nil { 46 return nil, err 47 } 48 49 callback, err := e.GetStringArg(1) 50 if err != nil { 51 return nil, err 52 } 53 54 operator, err := e.GetStringArg(2) 55 if err != nil { 56 return nil, err 57 } 58 59 if _, ok := supportedOperators[operator]; !ok { 60 return nil, fmt.Errorf("unsupported operator %v, supported operators: %v", operator, supportedOperators) 61 } 62 63 threshold, err := e.GetFloatArg(3) 64 if err != nil { 65 return nil, err 66 } 67 68 aggFunc, ok := consolidations.ConsolidationToFunc[callback] 69 if !ok { 70 return nil, fmt.Errorf("unsupported consolidation function %s", callback) 71 } 72 73 results := make([]*types.MetricData, 0, len(args)) 74 for _, a := range args { 75 val := aggFunc(a.Values) 76 keepSeries := false 77 switch operator { 78 case "=": 79 if val == threshold { 80 keepSeries = true 81 } 82 case "!=": 83 if val != threshold { 84 keepSeries = true 85 } 86 case ">": 87 if val > threshold { 88 keepSeries = true 89 } 90 case ">=": 91 if val >= threshold { 92 keepSeries = true 93 } 94 case "<": 95 if val < threshold { 96 keepSeries = true 97 } 98 case "<=": 99 if val <= threshold { 100 keepSeries = true 101 } 102 } 103 if !keepSeries { 104 continue 105 } 106 107 results = append(results, a) 108 } 109 110 return results, nil 111 } 112 113 // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web 114 func (f *filterSeries) Description() map[string]types.FunctionDescription { 115 return map[string]types.FunctionDescription{ 116 "filterSeries": { 117 Name: "filterSeries", 118 Function: "filterSeries(seriesList, func, operator, threshold)", 119 Description: "Takes one metric or a wildcard seriesList followed by a consolidation function, an operator and a threshold.\nDraws only the metrics which match the filter expression.\n\nExample:\n\n.. code-block:: none\n\n &target=filterSeries(system.interface.eth*.packetsSent, 'max', '>', 1000)\n\nThis would only display interfaces which has a peak throughput higher than 1000 packets/min.\n\nSupported aggregation functions: ``average``, ``median``, ``sum``, ``min``,\n``max``, ``diff``, ``stddev``, ``range``, ``multiply`` & ``last``.\n\nSupported operators: ``=``, ``!=``, ``>``, ``>=``, ``<`` & ``<=``.", 120 Module: "graphite.render.functions", 121 Group: "Filter Series", 122 Params: []types.FunctionParam{ 123 { 124 Name: "seriesList", 125 Type: types.SeriesList, 126 Required: true, 127 }, 128 { 129 Name: "func", 130 Type: types.AggFunc, 131 Required: true, 132 Options: types.StringsToSuggestionList(consolidations.AvailableConsolidationFuncs()), 133 }, 134 { 135 Name: "operator", 136 Type: types.String, 137 Required: true, 138 Options: types.StringsToSuggestionList([]string{ 139 "!=", 140 "<", 141 "<=", 142 "=", 143 ">", 144 ">=", 145 }), 146 }, 147 { 148 Name: "threshold", 149 Type: types.Float, 150 Required: true, 151 }, 152 }, 153 }, 154 } 155 }