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

     1  package rangeOfSeries
     2  
     3  import (
     4  	"context"
     5  	"math"
     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 rangeOfSeries 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 := &rangeOfSeries{}
    22  	functions := []string{"rangeOfSeries"}
    23  	for _, n := range functions {
    24  		res = append(res, interfaces.FunctionMetadata{Name: n, F: f})
    25  	}
    26  	return res
    27  }
    28  
    29  // rangeOfSeries(*seriesLists)
    30  func (f *rangeOfSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) {
    31  	series, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	if len(series) == 0 {
    36  		return []*types.MetricData{}, nil
    37  	}
    38  
    39  	r := series[0].CopyLinkTags()
    40  	r.Name = e.Target() + "(" + e.RawArgs() + ")"
    41  	r.Values = make([]float64, len(series[0].Values))
    42  
    43  	commonTags := helper.GetCommonTags(series)
    44  
    45  	if _, ok := commonTags["name"]; !ok {
    46  		commonTags["name"] = r.Name
    47  	}
    48  	r.Tags = commonTags
    49  
    50  	for i := range series[0].Values {
    51  		var min, max float64
    52  		count := 0
    53  		for _, s := range series {
    54  			if math.IsNaN(s.Values[i]) {
    55  				continue
    56  			}
    57  
    58  			if count == 0 {
    59  				min = s.Values[i]
    60  				max = s.Values[i]
    61  			} else {
    62  				min = math.Min(min, s.Values[i])
    63  				max = math.Max(max, s.Values[i])
    64  			}
    65  
    66  			count++
    67  		}
    68  
    69  		if count >= 2 {
    70  			r.Values[i] = max - min
    71  		} else {
    72  			r.Values[i] = math.NaN()
    73  		}
    74  	}
    75  	return []*types.MetricData{r}, err
    76  }
    77  
    78  // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web
    79  func (f *rangeOfSeries) Description() map[string]types.FunctionDescription {
    80  	return map[string]types.FunctionDescription{
    81  		"rangeOfSeries": {
    82  			Description: "Takes a wildcard seriesList.\nDistills down a set of inputs into the range of the series\n\nExample:\n\n.. code-block:: none\n\n    &target=rangeOfSeries(Server*.connections.total)\n\nThis is an alias for :py:func:`aggregate <aggregate>` with aggregation ``rangeOf``.",
    83  			Function:    "rangeOfSeries(*seriesLists)",
    84  			Group:       "Combine",
    85  			Module:      "graphite.render.functions",
    86  			Name:        "rangeOfSeries",
    87  			Params: []types.FunctionParam{
    88  				{
    89  					Multiple: true,
    90  					Name:     "seriesLists",
    91  					Required: true,
    92  					Type:     types.SeriesList,
    93  				},
    94  			},
    95  		},
    96  	}
    97  }