netdata/netdata

View on GitHub
src/go/collectors/go.d.plugin/pkg/metrics/summary.go

Summary

Maintainability
A
0 mins
Test Coverage
// SPDX-License-Identifier: GPL-3.0-or-later

package metrics

import (
    "math"

    "github.com/netdata/netdata/go/go.d.plugin/pkg/stm"
)

type (
    // A Summary captures individual observations from an event or sample stream and
    // summarizes them in a manner similar to traditional summary statistics:
    //   sum of observations
    //   observation count
    //   observation average.
    //
    // To create summary instances, use NewSummary.
    Summary interface {
        Observer
        Reset()
    }

    // SummaryVec is a Collector that bundles a set of Summary which have different values for their names.
    // This is used if you want to count the same thing partitioned by various dimensions
    // (e.g. number of HTTP response time, partitioned by response code and method).
    //
    // Create instances with NewSummaryVec.
    SummaryVec map[string]Summary

    summary struct {
        min   float64
        max   float64
        sum   float64
        count int64
    }
)

var (
    _ stm.Value = summary{}
    _ stm.Value = SummaryVec{}
)

// NewSummary creates a new Summary.
func NewSummary() Summary {
    return &summary{
        min: math.MaxFloat64,
        max: -math.MaxFloat64,
    }
}

// WriteTo writes its values into given map.
// It adds those key-value pairs:
//
//    ${key}_sum        gauge, for sum of it's observed values from last Reset calls
//    ${key}_count      counter, for count of it's observed values from last Reset calls
//    ${key}_min        gauge, for min of it's observed values from last Reset calls (only exists if count > 0)
//    ${key}_max        gauge, for max of it's observed values from last Reset calls (only exists if count > 0)
//    ${key}_avg        gauge, for avg of it's observed values from last Reset calls (only exists if count > 0)
func (s summary) WriteTo(rv map[string]int64, key string, mul, div int) {
    if s.count > 0 {
        rv[key+"_min"] = int64(s.min * float64(mul) / float64(div))
        rv[key+"_max"] = int64(s.max * float64(mul) / float64(div))
        rv[key+"_sum"] = int64(s.sum * float64(mul) / float64(div))
        rv[key+"_count"] = s.count
        rv[key+"_avg"] = int64(s.sum / float64(s.count) * float64(mul) / float64(div))
    } else {
        rv[key+"_count"] = 0
        rv[key+"_sum"] = 0
        delete(rv, key+"_min")
        delete(rv, key+"_max")
        delete(rv, key+"_avg")
    }
}

// Reset resets all of its counters.
// Call it before every scrape loop.
func (s *summary) Reset() {
    s.min = math.MaxFloat64
    s.max = -math.MaxFloat64
    s.sum = 0
    s.count = 0
}

// Observe observes a value
func (s *summary) Observe(v float64) {
    if v > s.max {
        s.max = v
    }
    if v < s.min {
        s.min = v
    }
    s.sum += v
    s.count++
}

// NewSummaryVec creates a new SummaryVec instance.
func NewSummaryVec() SummaryVec {
    return SummaryVec{}
}

// WriteTo writes its value into given map.
func (c SummaryVec) WriteTo(rv map[string]int64, key string, mul, div int) {
    for name, value := range c {
        value.WriteTo(rv, key+"_"+name, mul, div)
    }
}

// Get gets counter instance by name.
func (c SummaryVec) Get(name string) Summary {
    item, ok := c[name]
    if ok {
        return item
    }
    item = NewSummary()
    c[name] = item
    return item
}

// Reset resets its all summaries.
func (c SummaryVec) Reset() {
    for _, value := range c {
        value.Reset()
    }
}