github.com/go-graphite/carbonapi@v0.17.0/expr/functions/scale/function.go (about) 1 package scale 2 3 import ( 4 "context" 5 "strconv" 6 7 "github.com/go-graphite/carbonapi/expr/helper" 8 "github.com/go-graphite/carbonapi/expr/interfaces" 9 "github.com/go-graphite/carbonapi/expr/types" 10 "github.com/go-graphite/carbonapi/pkg/parser" 11 ) 12 13 type scale struct{} 14 15 func GetOrder() interfaces.Order { 16 return interfaces.Any 17 } 18 19 func New(configFile string) []interfaces.FunctionMetadata { 20 res := make([]interfaces.FunctionMetadata, 0) 21 f := &scale{} 22 functions := []string{"scale", "scaleAfterTimestamp"} 23 for _, n := range functions { 24 res = append(res, interfaces.FunctionMetadata{Name: n, F: f}) 25 } 26 return res 27 } 28 29 // scale(seriesList, factor) 30 func (f *scale) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { 31 if e.ArgsLen() < 2 { 32 return nil, parser.ErrMissingArgument 33 } 34 35 arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) 36 if err != nil { 37 return nil, err 38 } 39 scale, err := e.GetFloatArg(1) 40 if err != nil { 41 return nil, err 42 } 43 scaleStr := strconv.FormatFloat(scale, 'g', -1, 64) 44 timestamp, err := e.GetIntArgDefault(2, 0) 45 if err != nil { 46 return nil, err 47 } 48 49 results := make([]*types.MetricData, len(arg)) 50 for j, a := range arg { 51 r := a.CopyLink() 52 if timestamp == 0 { 53 r.Name = "scale(" + a.Name + "," + scaleStr + ")" 54 } else { 55 r.Name = "scale(" + a.Name + "," + scaleStr + "," + e.Arg(2).StringValue() + ")" 56 } 57 r.Values = make([]float64, len(a.Values)) 58 r.Tags["scale"] = scaleStr 59 60 currentTimestamp := a.StartTime 61 for i, v := range a.Values { 62 r.Values[i] = v 63 if currentTimestamp >= int64(timestamp) { 64 r.Values[i] *= scale 65 } 66 67 currentTimestamp += a.StepTime 68 } 69 70 results[j] = r 71 } 72 return results, nil 73 } 74 75 // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web 76 func (f *scale) Description() map[string]types.FunctionDescription { 77 return map[string]types.FunctionDescription{ 78 "scale": { 79 Description: "Takes one metric or a wildcard seriesList followed by a constant, and multiplies the datapoint\n" + 80 "by the constant provided at each point.\n" + 81 "carbonapi extends this function by optional 3-rd parameter that accepts unix-timestamp. If provided, only values with timestamp newer than it will be scaled\n\n" + 82 "Example:\n\n.. code-block:: none\n\n &target=scale(Server.instance01.threads.busy,10)\n &target=scale(Server.instance*.threads.busy,10)\n\n" + 83 "Alias: scaleAfterTimestamp", 84 Function: "scale(seriesList, factor)", 85 Group: "Transform", 86 Module: "graphite.render.functions", 87 Name: "scale", 88 Params: []types.FunctionParam{ 89 { 90 Name: "seriesList", 91 Required: true, 92 Type: types.SeriesList, 93 }, 94 { 95 Name: "factor", 96 Required: true, 97 Type: types.Float, 98 }, 99 { 100 Name: "timestamp", 101 Required: false, 102 Type: types.Integer, 103 Default: types.NewSuggestion(0), 104 }, 105 }, 106 NameChange: true, // name changed 107 ValuesChange: true, // values changed 108 }, 109 "scaleAfterTimestamp": { 110 Description: "Takes one metric or a wildcard seriesList followed by a constant, and multiplies the datapoint\n" + 111 "by the constant provided at each point.\n" + 112 "carbonapi extends this function by optional 3-rd parameter that accepts unix-timestamp. If provided, only values with timestamp newer than it will be scaled\n\n" + 113 "Example:\n\n.. code-block:: none\n\n &target=scale(Server.instance01.threads.busy,10)\n &target=scale(Server.instance*.threads.busy,10)", 114 Function: "scaleAfterTimestamp(seriesList, factor)", 115 Group: "Transform", 116 Module: "graphite.render.functions", 117 Name: "scaleAfterTimestamp", 118 Params: []types.FunctionParam{ 119 { 120 Name: "seriesList", 121 Required: true, 122 Type: types.SeriesList, 123 }, 124 { 125 Name: "factor", 126 Required: true, 127 Type: types.Float, 128 }, 129 { 130 Name: "timestamp", 131 Required: false, 132 Type: types.Integer, 133 Default: types.NewSuggestion(0), 134 }, 135 }, 136 NameChange: true, // name changed 137 ValuesChange: true, // values changed 138 }, 139 } 140 }