meter

package module
v0.0.0-...-74b93e4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 21, 2019 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Index

Examples

Constants

View Source
const DefaultHistogramSize = 1000

DefaultHistogramSize is used if Size is not set in Histogram.

Variables

View Source
var (
	// CarbonDialTimeout is the timeout value when dialing the remote carbon
	// host.
	CarbonDialTimeout = 1 * time.Second

	// CarbonMaxConnDelay is the maximum value of the exponential backoff scheme
	// when reconecting to a carbon host.
	CarbonMaxConnDelay = 1 * time.Minute
)

Functions

func Add

func Add(key string, meter Meter) bool

Add associates the given meter with the given key and begins to periodically poll the meter.

func Handle

func Handle(handler Handler)

Handle adds the given handler to the list of handlers to be executed after polling the meters.

func Join

func Join(items ...string) string

Join concatenates the given items with a '.' character where necessary.

func Load

func Load(obj interface{}, prefix string)

Load crawls the given object to register and instantiate any pointer to meters that it finds. The meter key will be derived from the name of the field that contains the meter and will be prefixed by the given prefix string. If a structure is encoutered then it will be recursively crawled with the name of the field appended to the given prefix.

func Poll

func Poll(prefix string, rate time.Duration)

Poll starts a background goroutine which will periodically poll the registered meters at the given rate and prepend all the polled keys with the given prefix.

func ProcessStats

func ProcessStats(prefix string)

ProcessStats registers various process metrics from the OS and the go runtime under the given prefix.

func Remove

func Remove(key string)

Remove removes any meters associated with the key which will no longer be polled.

func Unload

func Unload(obj interface{}, prefix string)

Unload crawls the given object and deregisters any pointer to meters that it finds. See Load for more details about the crawling and naming behaviour.

Types

type CarbonHandler

type CarbonHandler struct {

	// URLs contains the list of carbon hosts to connect to.
	URLs []string
	// contains filtered or unexported fields
}

CarbonHandler forwards a set of recorded meter values to multiple carbon hosts. Any values received while the connection to the carbon host is unavailable are dropped.

func NewCarbonHandler

func NewCarbonHandler(URL string) *CarbonHandler

NewCarbonHandler instantiates a new CarbonHandler which will log to the given URL.

func (*CarbonHandler) HandleMeters

func (carbon *CarbonHandler) HandleMeters(values map[string]float64)

HandleMeters forwards the given values to all the carbon host with a valid connection.

func (*CarbonHandler) Init

func (carbon *CarbonHandler) Init()

Init can be optionally used to initialize the object. Note that the handler will lazily initialize itself as needed.

type Counter

type Counter struct {
	// contains filtered or unexported fields
}

Counter counts the number of occurence of an event. Is also completely go-routine safe.

func GetCounter

func GetCounter(prefix string) *Counter

GetCounter returns the counter registered with the given key or creates a new one and registers it.

func (*Counter) Count

func (counter *Counter) Count(count uint64)

Count adds the given value to the counter.

func (*Counter) Hit

func (counter *Counter) Hit()

Hit adds 1 to the counter.

func (*Counter) ReadMeter

func (counter *Counter) ReadMeter(delta time.Duration) map[string]float64

ReadMeter returns the current count and resets the counter's value to 0. The returned value is normalized using the given delta to ensure that the value always represents a per second value.

type Gauge

type Gauge struct {

	// Value contains the initial value of the gauge. Should not be read or
	// written after construction.
	Value float64
	// contains filtered or unexported fields
}

Gauge reports a recorded value until a new value is recorded. This can be useful to record the result of rare or periodic events by ensuring that the results are always available and hard to miss.

func GetGauge

func GetGauge(prefix string) *Gauge

GetGauge returns the gauge registered with the given key or creates a new one and registers.

func (*Gauge) Change

func (gauge *Gauge) Change(value float64)

Change changes the recorded value.

func (*Gauge) ChangeDuration

func (gauge *Gauge) ChangeDuration(duration time.Duration)

ChangeDuration similar to Change but with a time.Duration value.

func (*Gauge) ChangeSince

func (gauge *Gauge) ChangeSince(t0 time.Time)

ChangeSince records a duration elapsed since the given time.

func (*Gauge) ReadMeter

func (gauge *Gauge) ReadMeter(_ time.Duration) map[string]float64

ReadMeter returns the currently set value if not equal to 0.

type Handler

type Handler interface {
	HandleMeters(map[string]float64)
}

Handler is used to periodically process the aggregated values of multiple meters.

type HandlerFunc

type HandlerFunc func(map[string]float64)

HandlerFunc is used to wrap a function as a Handler interface.

func (HandlerFunc) HandleMeters

func (fn HandlerFunc) HandleMeters(values map[string]float64)

HandleMeters forwards the call to the wrapped function.

type Histogram

type Histogram struct {

	// Size is maximum number of elements that the histogram can hold. Above
	// this amount, new values are sampled.
	Size int

	// SamplingSeed is the initial seed for the RNG used during sampling.
	SamplingSeed int64
	// contains filtered or unexported fields
}

Histogram aggregates metrics over a histogram of values.

Record will add up to a maximum of Size elements after which new elements will be randomly sampled with a probability that depends on the number of elements recorded. This schemes ensures that a histogram has a constant memory footprint and doesn't need to allocate for calls to Record.

ReadMeter will compute percentiles over the sampled histogram and the min and max value seen over the entire histogram.

Histogram is completely go-routine safe.

func GetHistogram

func GetHistogram(prefix string) *Histogram

GetHistogram returns the histogram registered with the given key or creates a new one and registers it.

func (*Histogram) ReadMeter

func (dist *Histogram) ReadMeter(_ time.Duration) map[string]float64

ReadMeter computes various statistic over the sampled histogram (50th, 90th and 99th percentile) and the count, min and max over the entire histogram. All recorded elements are then discarded from the histogram.

func (*Histogram) Record

func (dist *Histogram) Record(value float64)

Record adds the given value to the histogram with a probability based on the number of elements recorded since the last call to ReadMeter.

func (*Histogram) RecordDuration

func (dist *Histogram) RecordDuration(duration time.Duration)

RecordDuration similar to Record but with time.Duration values.

func (*Histogram) RecordSince

func (dist *Histogram) RecordSince(t0 time.Time)

RecordSince records a duration elapsed since the given time.

type Meter

type Meter interface {
	ReadMeter(time.Duration) map[string]float64
}

Meter represents a meter used to record various metrics which will be read periodically. The time.Duration parameter is used to normalize the values read by the meter so that they represent a per second values.

Example
package main

import (
	// "github.com/FrankBro/gometer/meter"

	"fmt"
	"meter"
	"sort"
	"time"
)

// Meters will usually be associated with a service or a component
type MyComponent struct {

	// Meters are crawled via the meter.Load function where the name of the
	// fields will be used as the name of the key for the meter.
	metrics struct {
		Gauge     *meter.Gauge
		State     *meter.State
		Counter   *meter.Counter
		Histogram *meter.Histogram

		// Nested structs are also supported and will lead to nested meters.
		Multi struct {
			Counter   *meter.MultiCounter
			Histogram *meter.MultiHistogram
			Gauge     *meter.MultiGauge
		}
	}
}

func (component *MyComponent) Init() {

	// Initializing and registering the various meters is accomplished via the
	// meter.Load function which will crawl the given object to fill and register
	// the various meters.
	meter.Load(&component.metrics, "myComponent")
}

func (component *MyComponent) Exec() {
	// The Counter is used to count the number of events that occured within a
	// second. Pretty straightforward.
	component.metrics.Counter.Hit()
	component.metrics.Counter.Count(10)

	// A MultiCounter can be used to seperate your counts into buckets
	// determined at runtime. Here we're indicating that we've seen one success
	// and one error.
	component.metrics.Multi.Counter.Hit("success")
	component.metrics.Multi.Counter.Hit("error")

	// A Gauge meter will output a given value until the value is
	// changed. Useful to record events that only happen occasionally and are
	// therefor not a good fit for histograms.
	component.metrics.Gauge.Change(5)

	// A State is similar to a gauge except that it will output the value 1 for
	// a given value.
	component.metrics.State.Change("happy")

	// Histograms are used to output the distribution of events that occured
	// within a second.
	for i := 0; i < 100; i++ {
		component.metrics.Histogram.Record(float64(i))
	}
}

func main() {

	// It's also to monitor various process metrics via the ProcessStats
	// function (disabled to keep the example's output simple).
	// meter.ProcessStats("")

	// Before we start polling we need to decide where our metrics will go. We
	// can either use one of the builtin handlers (eg. CarbonHandler,
	// RESTHandler, etc.)  or, for the sake of the example, we can create our
	// own which will log to a channel.
	resultC := make(chan map[string]float64)
	handler := func(values map[string]float64) { resultC <- values }
	meter.Handle(meter.HandlerFunc(handler))

	// Meter polling must be initiated via the Poll function.
	meter.Poll("myProcess", 1*time.Second)

	// Finally, let's instantiate our component and start logging some metrics.
	var component MyComponent
	component.Init()
	component.Exec()

	// Finally, we'll finish off the test by reading the value and printing them
	// out.
	SortAndPrint(<-resultC)

}

// SortAndPrint prints the map in a deterministic manner such that we can
// reliably check the output of our example. This is strictly boilerplate for
// the purpose of the example and is not required in actual code.
func SortAndPrint(values map[string]float64) {
	var keys []string

	for key := range values {
		keys = append(keys, key)
	}

	sort.Strings(keys)

	for _, key := range keys {
		fmt.Printf("%s: %f\n", key, values[key])
	}

}
Output:

myProcess.myComponent.Counter: 11.000000
myProcess.myComponent.Gauge: 5.000000
myProcess.myComponent.Histogram.avg: 49.500000
myProcess.myComponent.Histogram.count: 100.000000
myProcess.myComponent.Histogram.max: 99.000000
myProcess.myComponent.Histogram.min: 0.000000
myProcess.myComponent.Histogram.p50: 50.000000
myProcess.myComponent.Histogram.p90: 90.000000
myProcess.myComponent.Histogram.p99: 99.000000
myProcess.myComponent.Multi.Counter.error: 1.000000
myProcess.myComponent.Multi.Counter.success: 1.000000
myProcess.myComponent.State.happy: 1.000000

func Get

func Get(key string) Meter

Get returns the meter associated with the given key or nil if no such meter exists.

func GetOrAdd

func GetOrAdd(key string, meter Meter) Meter

GetOrAdd registers the given meter with the given key if it's not already registered or returns the meter associated with the given key.

type MultiCounter

type MultiCounter struct {
	// contains filtered or unexported fields
}

MultiCounter associates Counter objects to keys which can be selected when recording. Is completely go-routine safe.

func GetMultiCounter

func GetMultiCounter(prefix string) *MultiCounter

GetMultiCounter returns the counter registered with the given key or creates a new one and registers it.

func (*MultiCounter) Count

func (multi *MultiCounter) Count(key string, count uint64)

Count calls Count on the counter associated with the given key. New Keys are lazily created as required.

func (*MultiCounter) Hit

func (multi *MultiCounter) Hit(key string)

Hit calls Hit on the counter associated with the given key. New Keys are lazily created as required.

func (*MultiCounter) ReadMeter

func (multi *MultiCounter) ReadMeter(delta time.Duration) map[string]float64

ReadMeter calls ReadMeter on all underlying counters where all the keys are prefixed by the key name used in the calls to Record.

type MultiGauge

type MultiGauge struct {
	// contains filtered or unexported fields
}

MultiGauge associates Gauge objects to keys which can be selected when recording. Is completely go-routine safe.

func GetMultiGauge

func GetMultiGauge(prefix string) *MultiGauge

GetMultiGauge returns the gauge registered with the given key or creates a new one and registers it.

func (*MultiGauge) Change

func (multi *MultiGauge) Change(key string, value float64)

Change records the given value with the gauge associated with the given key. New Keys are lazily created as required.

func (*MultiGauge) ChangeDuration

func (multi *MultiGauge) ChangeDuration(key string, duration time.Duration)

ChangeDuration similar to Change but with a time.Duration value.

func (*MultiGauge) ChangeSince

func (multi *MultiGauge) ChangeSince(key string, t0 time.Time)

ChangeSince records a duration elapsed since the given time with the given key.

func (*MultiGauge) ReadMeter

func (multi *MultiGauge) ReadMeter(delta time.Duration) map[string]float64

ReadMeter calls ReadMeter on all underlying gauges where all the keys are prefixed by the key name used in the calls to Record.

type MultiHistogram

type MultiHistogram struct {

	// Size is used to initialize the Size member of the underlying Histogram
	// objects.
	Size int

	// SamplingSeed is used to initialize the SamplingSeed member of underlying
	// Histogram objects.
	SamplingSeed int64
	// contains filtered or unexported fields
}

MultiHistogram associates Histogram objects to keys which can be selected when recording. Is completely go-routine safe.

func GetMultiHistogram

func GetMultiHistogram(prefix string) *MultiHistogram

GetMultiHistogram returns the histogram registered with the given key or creates a new one and registers it.

func (*MultiHistogram) ReadMeter

func (multi *MultiHistogram) ReadMeter(delta time.Duration) map[string]float64

ReadMeter calls ReadMeter on all the underlying histograms where all the keys are prefixed by the key name used in the calls to Record.

func (*MultiHistogram) Record

func (multi *MultiHistogram) Record(key string, value float64)

Record adds the given value to the histogram associated with the given key. New keys are lazily created as required.

func (*MultiHistogram) RecordDuration

func (multi *MultiHistogram) RecordDuration(key string, value time.Duration)

RecordDuration similar to Record but with time.Duration values.

func (*MultiHistogram) RecordSince

func (multi *MultiHistogram) RecordSince(key string, t0 time.Time)

RecordSince records a duration elapsed since the given time for the given key.

type Pattern

type Pattern []string

func NewPattern

func NewPattern(pattern string) Pattern

func (Pattern) Match

func (pattern Pattern) Match(key string) (result []string, ok bool)

func (Pattern) String

func (pattern Pattern) String() string

type Poller

type Poller struct {

	// Meters contains the initial list of meters to be polled. Should not be
	// read or modified after calling Init.
	Meters map[string]Meter

	// Handlers contains the initial list of handlers. Should not be read or
	// modified after calling init.
	Handlers []Handler
	// contains filtered or unexported fields
}

Poller periodically calls ReadMeter on all the meters registered via the Add function and forwards the aggregated values to all the configured handlers.

var DefaultPoller Poller

DefaultPoller is the Poller object used by the global Add, Remove and Handle functions.

func (*Poller) Add

func (poller *Poller) Add(key string, meter Meter) bool

Add registers the given meter which will be polled periodically and associates it with the given key. If the key is already registered then the old meter will be replaced by the given meter.

func (*Poller) Get

func (poller *Poller) Get(key string) Meter

Get returns the meter associated with the given key or nil if no such meter exists.

func (*Poller) Handle

func (poller *Poller) Handle(handler Handler)

Handle adds the given handler to the list of handler to execute.

func (*Poller) Poll

func (poller *Poller) Poll(prefix string, rate time.Duration)

Poll starts a background goroutine which will periodically poll the registered meters at the given rate and prepend all the polled keys with the given prefix.

func (*Poller) Remove

func (poller *Poller) Remove(key string)

Remove unregisters the given meter which will no longer be polled periodically.

type State

type State struct {
	// contains filtered or unexported fields
}

State reports the value 1.0 for a given state until a new state is recorded. This can be useful to record infrequent changes in program state.

func GetState

func GetState(prefix string) *State

GetState returns the state registered with the given key or creates a new one and registers it.

func (*State) Change

func (state *State) Change(value string)

Change changes the recorded state. An empty string will not output any values.

func (*State) ReadMeter

func (state *State) ReadMeter(delta time.Duration) map[string]float64

ReadMeter returns the currently set state with a value of 1.0 or nothing if the state is an empty string.

func (*State) Reset

func (state *State) Reset()

Reset disables any values outputed by this state.

type TranslationHandler

type TranslationHandler struct {
	// contains filtered or unexported fields
}

func NewTranslationHandler

func NewTranslationHandler(patterns map[string]string) *TranslationHandler

func (*TranslationHandler) HandleMeters

func (handler *TranslationHandler) HandleMeters(values map[string]float64)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL