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 }