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

     1  package timeSlice
     2  
     3  import (
     4  	"context"
     5  	"math"
     6  	"strconv"
     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 timeSlice 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 := &timeSlice{}
    23  	functions := []string{"timeSlice"}
    24  	for _, n := range functions {
    25  		res = append(res, interfaces.FunctionMetadata{Name: n, F: f})
    26  	}
    27  	return res
    28  }
    29  
    30  func (f *timeSlice) 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  	start32, err := e.GetIntervalArg(1, 1)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	start := int64(start32)
    40  
    41  	end, err := e.GetIntervalNamedOrPosArgDefault("endSliceAt", 2, 1, 0)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	startStr := strconv.FormatInt(start, 10)
    47  	endStr := strconv.FormatInt(end, 10)
    48  
    49  	arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	results := make([]*types.MetricData, len(arg))
    55  
    56  	for n, a := range arg {
    57  		r := a.CopyLink()
    58  		r.Name = "timeSlice(" + a.Name + "," + startStr + "," + endStr + ")"
    59  		r.Values = make([]float64, len(a.Values))
    60  		r.Tags["timeSliceStart"] = startStr
    61  		r.Tags["timeSliceEnd"] = endStr
    62  
    63  		current := from
    64  		for i, v := range a.Values {
    65  			if current < start || current > end {
    66  				r.Values[i] = math.NaN()
    67  			} else {
    68  				r.Values[i] = v
    69  			}
    70  			current += a.StepTime
    71  		}
    72  
    73  		results[n] = r
    74  	}
    75  
    76  	return results, nil
    77  }
    78  
    79  // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web
    80  func (f *timeSlice) Description() map[string]types.FunctionDescription {
    81  	return map[string]types.FunctionDescription{
    82  		"timeSlice": {
    83  			Name:        "timeSlice",
    84  			Function:    "timeSlice(seriesList, startSliceAt, endSliceAt='now')",
    85  			Description: "Takes one metric or a wildcard metric, followed by a quoted string with the\ntime to start the line and another quoted string with the time to end the line.\nThe start and end times are inclusive. See ``from / until`` in the render\\_api_\nfor examples of time formats.\n\nUseful for filtering out a part of a series of data from a wider range of\ndata.\n\nExample:\n\n.. code-block:: none\n\n  &target=timeSlice(network.core.port1,\"00:00 20140101\",\"11:59 20140630\")\n  &target=timeSlice(network.core.port1,\"12:00 20140630\",\"now\")",
    86  			Module:      "graphite.render.functions",
    87  			Group:       "Transform",
    88  			Params: []types.FunctionParam{
    89  				{
    90  					Name:     "seriesList",
    91  					Type:     types.SeriesList,
    92  					Required: true,
    93  				},
    94  				{
    95  					Name:     "startSliceAt",
    96  					Type:     types.Date,
    97  					Required: true,
    98  				},
    99  				{
   100  					Name:    "endSliceAt",
   101  					Type:    types.Interval,
   102  					Default: types.NewSuggestion("now"),
   103  				},
   104  			},
   105  			NameChange:   true, // name changed
   106  			ValuesChange: true, // values changed
   107  		},
   108  	}
   109  }