tester/metric.go (83 lines of code) (raw):

/* Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. */ package tester import ( "errors" "time" ) // DataPoint represents a sample of data. type DataPoint struct { Time time.Time Value float64 } // Metric provides a function to get data points of this metric. type Metric interface { // Setup is used to setup the metric before the test Setup(options interface{}) error // Fetch is used to get metric measures. Fetch(start time.Time, duration time.Duration) ([]DataPoint, error) // Name is used to serialize metrics. Name() string } // Aggregator provides a function to aggregate data points. type Aggregator interface { // Aggregate calculates a single value for a metric datapoints. Aggregate([]DataPoint) float64 // Name is used to serialize metrics. Name() string } type metricAggregator struct { repr string aggr func([]DataPoint) float64 } func (m *metricAggregator) Aggregate(points []DataPoint) float64 { return m.aggr(points) } func (m *metricAggregator) Name() string { return m.repr } // MinimumAggregator returns the smallest datapoint value. //nolint:gochecknoglobals var MinimumAggregator Aggregator = &metricAggregator{ repr: "MIN", aggr: func(points []DataPoint) float64 { if len(points) == 0 { return 0. } x := points[0].Value for _, point := range points { if point.Value < x { x = point.Value } } return x }, } // MaximumAggregator returns the smallest datapoint value. //nolint:gochecknoglobals var MaximumAggregator Aggregator = &metricAggregator{ repr: "MAX", aggr: func(points []DataPoint) float64 { if len(points) == 0 { return 0. } x := points[0].Value for _, point := range points { if point.Value > x { x = point.Value } } return x }, } // AverageAggregator returns the average data point value. //nolint:gochecknoglobals var AverageAggregator Aggregator = &metricAggregator{ repr: "AVG", aggr: func(points []DataPoint) float64 { if len(points) == 0 { return 0. } sum := 0. for _, point := range points { sum = sum + point.Value } return sum / float64(len(points)) }, } // Aggregators is a map of aggregators representation to the actual aggregator. //nolint:gochecknoglobals var Aggregators = map[string]Aggregator{ MinimumAggregator.Name(): MinimumAggregator, MaximumAggregator.Name(): MaximumAggregator, AverageAggregator.Name(): AverageAggregator, } // ErrInvalidAggregator is returned when a metric aggregator cannot be found. var ErrInvalidAggregator = errors.New("invalid aggregator") // ParseAggregator returns metric aggregator from its name. func ParseAggregator(name string) (Aggregator, error) { if aggregator, ok := Aggregators[name]; ok { return aggregator, nil } return nil, ErrInvalidAggregator }