|
|
- package stats
-
- import "fmt"
-
- // Type is the type of aggregation of apply
- type Type int
-
- const (
- AggregateAvg Type = iota
- AggregateSum
- AggregateHistogram
- )
-
- var (
- // HistogramPercentiles is used to determine which percentiles to return for
- // SimpleCounter.Aggregate
- HistogramPercentiles = map[string]float64{
- "p50": 0.5,
- "p95": 0.95,
- "p99": 0.99,
- }
-
- // MinSamplesForPercentiles is used by SimpleCounter.Aggregate to determine
- // what the minimum number of samples is required for percentile analysis
- MinSamplesForPercentiles = 10
- )
-
- // Aggregates can be used to merge counters together. This is not goroutine safe
- type Aggregates map[string]Counter
-
- // Add adds the counter for aggregation. This is not goroutine safe
- func (a Aggregates) Add(c Counter) error {
- key := c.FullKey()
- if counter, ok := a[key]; ok {
- if counter.GetType() != c.GetType() {
- return fmt.Errorf("stats: mismatched aggregation type for: %s", key)
- }
- counter.AddValues(c.GetValues()...)
- } else {
- a[key] = c
- }
- return nil
- }
-
- // Counter is the interface used by Aggregates to merge counters together
- type Counter interface {
- // FullKey is used to uniquely identify the counter
- FullKey() string
-
- // AddValues adds values for aggregation
- AddValues(...float64)
-
- // GetValues returns the values for aggregation
- GetValues() []float64
-
- // GetType returns the type of aggregation to apply
- GetType() Type
- }
-
- // SimpleCounter is a basic implementation of the Counter interface
- type SimpleCounter struct {
- Key string
- Values []float64
- Type Type
- }
-
- // FullKey is part of the Counter interace
- func (s *SimpleCounter) FullKey() string {
- return s.Key
- }
-
- // GetValues is part of the Counter interface
- func (s *SimpleCounter) GetValues() []float64 {
- return s.Values
- }
-
- // AddValues is part of the Counter interface
- func (s *SimpleCounter) AddValues(vs ...float64) {
- s.Values = append(s.Values, vs...)
- }
-
- // GetType is part of the Counter interface
- func (s *SimpleCounter) GetType() Type {
- return s.Type
- }
-
- // Aggregate aggregates the provided values appropriately, returning a map
- // from key to value. If AggregateHistogram is specified, the map will contain
- // the relevant percentiles as specified by HistogramPercentiles
- func (s *SimpleCounter) Aggregate() map[string]float64 {
- switch s.Type {
- case AggregateAvg:
- return map[string]float64{
- s.Key: Average(s.Values),
- }
- case AggregateSum:
- return map[string]float64{
- s.Key: Sum(s.Values),
- }
- case AggregateHistogram:
- histogram := map[string]float64{
- s.Key: Average(s.Values),
- }
- if len(s.Values) > MinSamplesForPercentiles {
- for k, v := range Percentiles(s.Values, HistogramPercentiles) {
- histogram[fmt.Sprintf("%s.%s", s.Key, k)] = v
- }
- }
- return histogram
- }
- panic("stats: unsupported aggregation type")
- }
|