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

     1  package stdev
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math"
     7  
     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 stdev struct{}
    15  
    16  func GetOrder() interfaces.Order {
    17  	return interfaces.Any
    18  }
    19  
    20  func New(configFile string) []interfaces.FunctionMetadata {
    21  	res := make([]interfaces.FunctionMetadata, 0)
    22  	f := &stdev{}
    23  	res = append(res, interfaces.FunctionMetadata{Name: "stdev", F: f})
    24  	return res
    25  }
    26  
    27  // stdev(seriesList, points, missingThreshold=0.1)
    28  // Alias: stddev
    29  func (f *stdev) 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() < 2 {
    31  		return nil, parser.ErrMissingArgument
    32  	}
    33  
    34  	arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  
    39  	points, err := e.GetIntArg(1)
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  	pointsStr := e.Arg(1).StringValue()
    44  
    45  	missingThreshold, err := e.GetFloatArgDefault(2, 0.1)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	minLen := int((1 - missingThreshold) * float64(points))
    51  
    52  	result := make([]*types.MetricData, len(arg))
    53  
    54  	for n, a := range arg {
    55  		w := &types.Windowed{Data: make([]float64, points)}
    56  
    57  		r := a.CopyLink()
    58  		r.Name = "stdev(" + a.Name + "," + pointsStr + ")"
    59  		r.Values = make([]float64, len(a.Values))
    60  		r.Tags["stdev"] = fmt.Sprintf("%d", points)
    61  
    62  		for i, v := range a.Values {
    63  			w.Push(v)
    64  			if !math.IsNaN(v) {
    65  				r.Values[i] = w.Stdev()
    66  			} else {
    67  				r.Values[i] = math.NaN()
    68  			}
    69  			if math.IsNaN(r.Values[i]) || (i >= minLen && w.Len() < minLen) {
    70  				r.Values[i] = math.NaN()
    71  			}
    72  		}
    73  		result[n] = r
    74  	}
    75  	return result, nil
    76  }
    77  
    78  // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web
    79  func (f *stdev) Description() map[string]types.FunctionDescription {
    80  	return map[string]types.FunctionDescription{
    81  		"stdev": {
    82  			Description: "Takes one metric or a wildcard seriesList followed by an integer N.\nDraw the Standard Deviation of all metrics passed for the past N datapoints.\nIf the ratio of null points in the window is greater than windowTolerance,\nskip the calculation. The default for windowTolerance is 0.1 (up to 10% of points\nin the window can be missing). Note that if this is set to 0.0, it will cause large\ngaps in the output anywhere a single point is missing.\n\nExample:\n\n.. code-block:: none\n\n  &target=stdev(server*.instance*.threads.busy,30)\n  &target=stdev(server*.instance*.cpu.system,30,0.0)",
    83  			Function:    "stdev(seriesList, points, windowTolerance=0.1)",
    84  			Group:       "Calculate",
    85  			Module:      "graphite.render.functions",
    86  			Name:        "stdev",
    87  			Params: []types.FunctionParam{
    88  				{
    89  					Name:     "seriesList",
    90  					Required: true,
    91  					Type:     types.SeriesList,
    92  				},
    93  				{
    94  					Name:     "points",
    95  					Required: true,
    96  					Type:     types.Integer,
    97  				},
    98  				{
    99  					Default: types.NewSuggestion(0.1),
   100  					Name:    "windowTolerance",
   101  					Type:    types.Float,
   102  				},
   103  			},
   104  		},
   105  	}
   106  }