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  }