github.com/go-graphite/carbonapi@v0.17.0/expr/functions/removeBetweenPercentile/function.go (about)

     1  package removeBetweenPercentile
     2  
     3  import (
     4  	"context"
     5  	"math"
     6  	"strconv"
     7  
     8  	"github.com/go-graphite/carbonapi/expr/consolidations"
     9  	"github.com/go-graphite/carbonapi/expr/helper"
    10  	"github.com/go-graphite/carbonapi/expr/interfaces"
    11  	"github.com/go-graphite/carbonapi/expr/types"
    12  	"github.com/go-graphite/carbonapi/pkg/parser"
    13  )
    14  
    15  type removeBetweenPercentile struct{}
    16  
    17  func GetOrder() interfaces.Order {
    18  	return interfaces.Any
    19  }
    20  
    21  func New(configFile string) []interfaces.FunctionMetadata {
    22  	res := make([]interfaces.FunctionMetadata, 0)
    23  	f := &removeBetweenPercentile{}
    24  	functions := []string{"removeBetweenPercentile"}
    25  	for _, n := range functions {
    26  		res = append(res, interfaces.FunctionMetadata{Name: n, F: f})
    27  	}
    28  	return res
    29  }
    30  
    31  // removeBetweenPercentile(seriesLists, percent)
    32  func (f *removeBetweenPercentile) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) {
    33  	if e.ArgsLen() < 2 {
    34  		return nil, parser.ErrMissingArgument
    35  	}
    36  
    37  	args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	number, err := e.GetFloatArg(1)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	var percentile float64
    48  	var results []*types.MetricData
    49  
    50  	if number < 50.0 {
    51  		percentile = 100.0 - number
    52  	} else {
    53  		percentile = number
    54  	}
    55  
    56  	var lowerThresholds []float64
    57  	var higherThresholds []float64
    58  
    59  	for i := range args[0].Values {
    60  		var values []float64
    61  		for _, arg := range args {
    62  			if !math.IsNaN(arg.Values[i]) {
    63  				values = append(values, arg.Values[i])
    64  			}
    65  		}
    66  		if len(values) > 0 {
    67  			lowerThresholds = append(lowerThresholds, consolidations.Percentile(values, (100.0-percentile), false))
    68  			higherThresholds = append(higherThresholds, consolidations.Percentile(values, percentile, false))
    69  		}
    70  	}
    71  
    72  	numberStr := strconv.FormatFloat(number, 'f', -1, 64)
    73  	for i, a := range args {
    74  		r := a.CopyLink()
    75  		r.Name = e.Target() + "(" + a.Name + ", " + numberStr + ")"
    76  
    77  		for _, v := range a.Values {
    78  			if !(v > lowerThresholds[i] && v < higherThresholds[i]) {
    79  				results = append(results, r)
    80  				break
    81  			}
    82  		}
    83  	}
    84  	return results, nil
    85  }
    86  
    87  // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web
    88  func (f *removeBetweenPercentile) Description() map[string]types.FunctionDescription {
    89  	return map[string]types.FunctionDescription{
    90  		"removeBetweenPercentile": {
    91  			Description: "Removes series that do not have an value lying in the x-percentile of all the values at a moment",
    92  			Function:    "removeBetweenPercentile(seriesList, n)",
    93  			Group:       "Filter Data",
    94  			Module:      "graphite.render.functions",
    95  			Name:        "removeBetweenPercentile",
    96  			Params: []types.FunctionParam{
    97  				{
    98  					Name:     "seriesList",
    99  					Required: true,
   100  					Type:     types.SeriesList,
   101  				},
   102  				{
   103  					Name:     "n",
   104  					Required: true,
   105  					Type:     types.Integer,
   106  				},
   107  			},
   108  		},
   109  	}
   110  }