github.com/go-graphite/carbonapi@v0.17.0/expr/functions/holtWintersForecast/function.go (about) 1 package holtWintersForecast 2 3 import ( 4 "context" 5 6 "github.com/go-graphite/carbonapi/expr/helper" 7 "github.com/go-graphite/carbonapi/expr/holtwinters" 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 pb "github.com/go-graphite/protocol/carbonapi_v3_pb" 12 ) 13 14 type holtWintersForecast 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 := &holtWintersForecast{} 23 functions := []string{"holtWintersForecast"} 24 for _, n := range functions { 25 res = append(res, interfaces.FunctionMetadata{Name: n, F: f}) 26 } 27 return res 28 } 29 30 func (f *holtWintersForecast) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { 31 bootstrapInterval, err := e.GetIntervalNamedOrPosArgDefault("bootstrapInterval", 1, 1, holtwinters.DefaultBootstrapInterval) 32 if err != nil { 33 return nil, err 34 } 35 36 args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from-bootstrapInterval, until, values) 37 if err != nil { 38 return nil, err 39 } 40 41 seasonality, err := e.GetIntervalNamedOrPosArgDefault("seasonality", 2, 1, holtwinters.DefaultSeasonality) 42 if err != nil { 43 return nil, err 44 } 45 46 var predictionsOfInterest []float64 47 results := make([]*types.MetricData, len(args)) 48 for i, arg := range args { 49 stepTime := arg.StepTime 50 51 predictions, _ := holtwinters.HoltWintersAnalysis(arg.Values, stepTime, seasonality) 52 53 windowPoints := int(bootstrapInterval / stepTime) 54 if len(predictions) < windowPoints { 55 predictionsOfInterest = predictions 56 } else { 57 predictionsOfInterest = predictions[windowPoints:] 58 } 59 60 name := "holtWintersForecast(" + arg.Name + ")" 61 r := &types.MetricData{ 62 FetchResponse: pb.FetchResponse{ 63 Name: name, 64 Values: predictionsOfInterest, 65 StepTime: arg.StepTime, 66 StartTime: arg.StartTime + bootstrapInterval, 67 StopTime: arg.StopTime, 68 PathExpression: name, 69 XFilesFactor: arg.XFilesFactor, 70 ConsolidationFunc: arg.ConsolidationFunc, 71 }, 72 Tags: helper.CopyTags(arg), 73 } 74 r.Tags["holtWintersForecast"] = "1" 75 results[i] = r 76 } 77 return results, nil 78 } 79 80 // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web 81 func (f *holtWintersForecast) Description() map[string]types.FunctionDescription { 82 return map[string]types.FunctionDescription{ 83 "holtWintersForecast": { 84 Description: "Performs a Holt-Winters forecast using the series as input data. Data from\n`bootstrapInterval` (one week by default) previous to the series is used to bootstrap the initial forecast.", 85 Function: "holtWintersForecast(seriesList, bootstrapInterval='7d')", 86 Group: "Calculate", 87 Module: "graphite.render.functions", 88 Name: "holtWintersForecast", 89 Params: []types.FunctionParam{ 90 { 91 Name: "seriesList", 92 Required: true, 93 Type: types.SeriesList, 94 }, 95 { 96 Default: types.NewSuggestion("7d"), 97 Name: "bootstrapInterval", 98 Suggestions: types.NewSuggestions( 99 "7d", 100 "30d", 101 ), 102 Type: types.Interval, 103 }, 104 }, 105 NameChange: true, // name changed 106 TagsChange: true, // name tag changed 107 ValuesChange: true, // values changed 108 }, 109 } 110 }