Documentation ¶
Overview ¶
Package metric is a generic metric package for the standard metric types gauges/counters/timers/histograms. It ships with a statsd sink implementation, but can be extended with new sinks.
This implementation is aimed at being as fast as possible to not discourage metrics on values in hotpaths just because of locking overhead. This requires some client side buffering (and flusher go-routines) and, especially for the timer/histogram event type, a relatively large data structure to create a ring-buffer with mostly lock-free writes. (it uses condition variables for flushing). This design is for the use case where you have a lot of timer/histogram metric events going to a few buckets.
The API consists of 3 main types of objects:
- Meter - the object doing the actual measuring. (possibly buffering measurements)
- Sink - an object to which Meter readings can be sent. Sinks can have internal buffering which can be flushed
- Client - an object responsible for sending Meter readings to an assigned Sink, possibly at configured flushing intervals.
The API supports 3 approaches to maintaining your metrics:
Ad-hoc ¶
Ad-hoc generation of metric events without a Meter object (explicitly flushing the Client sink): This is a relative slow, but simple way to generate metric data. This allows for use cases where you don't have a small set of known metrics receiving many events, but rather many metrics receiving few events each:
metric.SetDefaultSink(sink) metric.AdhocGauge("gauge", 17, true)
Manually ¶
Manually making readings of a meter directly to a Sink. (use this only if strictly needed)
gauge := metric.NewGauge("gauge") gauge.Set(17) gauge.FlushReading(sink) sink.Flush()
Managed ¶
Registring a buffered Meter object with a client. This is the fastest method. The low latency API is accessed via Client objects. (There's a default global client). The speed is achieved by creating permanent buffering metrics objects for each metric.
client := metric.NewClient(sink, metric.FlushInterval(time.Second)) gauge := client.RegisterGauge("gauge") gauge.Set(17)
The statsd sink also does client side buffering before sending UDP packages and is flushed when asked, or when running full. You can set the max size of the UDP datagrams created.
Index ¶
- Constants
- func AdhocCount(name string, val int, flush bool)
- func AdhocGauge(name string, val uint64, flush bool)
- func AdhocSample(name string, val int64, flush bool)
- func AdhocSetMember(name string, member string, flush bool)
- func AdhocTime(name string, d time.Duration, flush bool)
- func Flush()
- func Mark(name string)
- func SetDefaultOptions(opts ...MOption)
- func SetDefaultSink(sink Sink)
- func Start()
- func Stop()
- type Client
- func (c *Client) AdhocCount(name string, val int, flush bool)
- func (c *Client) AdhocGauge(name string, val uint64, flush bool)
- func (c *Client) AdhocSample(name string, val int64, flush bool)
- func (c *Client) AdhocSetMember(name string, member string, flush bool)
- func (c *Client) AdhocTime(name string, d time.Duration, flush bool)
- func (c *Client) Deregister(m Meter) error
- func (c *Client) Flush()
- func (c *Client) Mark(name string)
- func (c *Client) Register(m Meter, opts ...MOption)
- func (c *Client) RegisterCounter(name string, opts ...MOption) *Counter
- func (c *Client) RegisterGauge(name string, opts ...MOption) *GaugeUint64
- func (c *Client) RegisterHistogram(name string, opts ...MOption) Histogram
- func (c *Client) RegisterSet(name string, opts ...MOption) *Set
- func (c *Client) RegisterTimer(name string, opts ...MOption) Timer
- func (c *Client) SetOptions(opts ...MOption)
- func (c *Client) SetSink(sink Sink)
- func (c *Client) Start()
- func (c *Client) Stop()
- type Counter
- type GaugeFloat64
- type GaugeInt64
- type GaugeUint64
- type Histogram
- type MConfig
- type MOption
- type Meter
- type Set
- type Sink
- type Timer
Examples ¶
Constants ¶
const ( MeterGauge = iota // A client side maintained value MeterCounter // A server side maintained value MeterHistogram // A general distribution of measurements events. MeterTimer // ... when those measurements are milliseconds MeterSet // free form string events )
Conceptual meter types Gauge: A client side maintained counter Counter: A server side maintained counter Historam: A series of events analyzed on the server Timer: A series of time.Duration events analyzed on the server Set: Discrete strings added to a set maintained on the server
Variables ¶
This section is empty.
Functions ¶
func AdhocCount ¶
AdhocCount creates an ad-hoc counter metric event at the default client. If flush is true, the sink will be instructed to flush data immediately
func AdhocGauge ¶
AdhocGauge creates an ad-hoc gauge metric event at the default client. If flush is true, the sink will be instructed to flush data immediately
func AdhocSample ¶
AdhocSample creates an ad-hoc histogram metric event at the default client. If flush is true, the sink will be instructed to flush data immediately
func AdhocSetMember ¶
AdhocSetMember generates an ad-hoc set membership event with the default client. If flush is true, the sink will be instructed to flush data immediately
func AdhocTime ¶
AdhocTime creates an ad-hoc timer metric event at the default client. If flush is true, the sink will be instructed to flush data immediately
func Mark ¶
func Mark(name string)
Mark - send a ad-hoc zero histogram event at the default client. - see Client.Mark()
func SetDefaultOptions ¶
func SetDefaultOptions(opts ...MOption)
SetDefaultOptions sets options on the default metric client
func SetDefaultSink ¶
func SetDefaultSink(sink Sink)
SetDefaultSink sets the sink for the default metics client The default client has no sink set initially. You need to set it calling this function.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the main object the applications holds to do metrics. It can be used directly for ad-hoc events, or be used to create persistent gauge/conter/timer/... objects optimised for bulk metric generation. A default metric Client with no FlushInterval set is Start()'ed by init()
func NewClient ¶
NewClient returns you a client handle directly if you do not want to use the global default client. This creates a new metric client with a factory object for the sink. If sink == nil, the client will not emit metrics until a Sink is set using SetSink.
Example ¶
package main import ( "github.com/One-com/gone/metric" "github.com/One-com/gone/metric/sink/statsd" "log" "time" "os" ) func main() { sink, err := statsd.New( statsd.Buffer(512), statsd.Output(os.Stdout), statsd.Prefix("prefix")) if err != nil { log.Fatal(err) } c := metric.NewClient(sink) gauge1 := c.RegisterGauge("gauge1") gauge2 := metric.NewGauge("gauge2") c.Register(gauge2) counter := c.RegisterCounter("counter") timer := c.RegisterTimer("timer") histo := c.RegisterHistogram("histo") gauge1.Set(17) gauge2.Set(18) counter.Inc(1) timer.Sample(time.Duration(10 * time.Millisecond)) histo.Sample(17) c.Flush() }
Output: prefix.gauge1:17|g prefix.gauge2:18|g prefix.counter:1|c prefix.timer:10|ms prefix.histo:17|ms
func (*Client) AdhocCount ¶
AdhocCount creates an ad-hoc counter metric event. If flush is true, the sink will be instructed to flush data immediately
func (*Client) AdhocGauge ¶
AdhocGauge creates an ad-hoc gauge metric event. If flush is true, the sink will be instructed to flush data immediately
func (*Client) AdhocSample ¶
AdhocSample creates an ad-hoc histogram metric event. If flush is true, the sink will be instructed to flush data immediately
func (*Client) AdhocSetMember ¶
AdhocSetMember creates an ad-hoc set membership event. If flush is true, the sink will be instructed to flush data immediately
func (*Client) AdhocTime ¶
AdhocTime creates an ad-hoc timer metric event. If flush is true, the sink will be instructed to flush data immediately
func (*Client) Deregister ¶
Deregister detaches a Meter (gauge/counter/timer...) from the client. It will no longer be flushed. An error is returned if the Meter was not registered.
func (*Client) Flush ¶
func (c *Client) Flush()
Flush the client default so no data is left in any pipeline buffers.
func (*Client) Mark ¶
Mark - send a ad-hoc zero histogram event immediately to allow the server side to indicate a unique event happened. This equivalent to calling Sample(name, 0, true) and can be used as a poor mans way to make qualitative events to be marked in the overall view of metrics. Like "process restart". Graphical views might allow you to draw these as special marks. For some sinks (like statsd) there's not dedicated way to send such events. Mark is equivalent to AdhocSample(name, 0, true)
func (*Client) Register ¶
Register a Meter with the client, finding a flusher with the appropriate interval, if possible, else create a new flusher.
func (*Client) RegisterCounter ¶
RegisterCounter is equivalent to Register(NewCounter(), opts) with the default Client.
func (*Client) RegisterGauge ¶
func (c *Client) RegisterGauge(name string, opts ...MOption) *GaugeUint64
RegisterGauge is equivalent to Register(NewGauge(), opts) with the default Client.
func (*Client) RegisterHistogram ¶
RegisterHistogram is equivalent to Register(NewHistogram(), opts) with the default Client.
func (*Client) RegisterTimer ¶
RegisterTimer is equivalent to Register(NewTimer(), opts) with the default Client.
func (*Client) SetOptions ¶
SetOptions sets options on a client - like the flush interval for metrics which haven't them selves a fixed flush interval
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
Counter is different from a GaugeInt64 in that it is reset to zero every time its flushed - and thus being server-side maintained.
func NewCounter ¶
NewCounter returns a client side buffered counter (a counter is a server side maintained value). "Server side" meaning that it's reset to 0 every time it's sent to the server and the total tally is kept on the server. This poses the risk of the server-side absolute value to drift in case of increments lost in transit. However, it also allows several distributed processes to update the same counter. If you want to have a pure client side counter, use GaugeInt64
func RegisterCounter ¶
RegisterCounter is equivalent to Register(NewCounter(), opts) with the default Client.
func (*Counter) FlushReading ¶
FlushReading flushes the accumulated counter value to the supplied Sink
type GaugeFloat64 ¶
type GaugeFloat64 struct {
// contains filtered or unexported fields
}
GaugeFloat64 is a float64 gauge which stores its value as a uint64 to implement FlushReading() fast (saving an interface allocation)
func NewGaugeFloat64 ¶
func NewGaugeFloat64(name string) *GaugeFloat64
NewGaugeFloat64 creates a gauge holding a Float64 value.
func (*GaugeFloat64) FlushReading ¶
func (g *GaugeFloat64) FlushReading(s Sink)
FlushReading sends the current gauge value to the Sink
func (*GaugeFloat64) Value ¶
func (g *GaugeFloat64) Value() float64
Value returns the gauge's current value.
type GaugeInt64 ¶
type GaugeInt64 struct {
// contains filtered or unexported fields
}
GaugeInt64 is a gauge using an int64 - meaning it can be decremented to negaive values
func NewGaugeInt64 ¶
func NewGaugeInt64(name string) *GaugeInt64
NewGaugeInt64 creates a int64 Gauge. Can be used as a go-metric client side gauge or counter
func (*GaugeInt64) Dec ¶
func (g *GaugeInt64) Dec(i int64)
Dec decrements the counter by the given amount.
func (*GaugeInt64) FlushReading ¶
func (g *GaugeInt64) FlushReading(s Sink)
FlushReading sends the gauge value to the sink
func (*GaugeInt64) Inc ¶
func (g *GaugeInt64) Inc(i int64)
Inc increments the counter by the given amount.
type GaugeUint64 ¶
type GaugeUint64 struct {
// contains filtered or unexported fields
}
GaugeUint64 is the default gauge type using a uint64
func NewGaugeUint64 ¶
func NewGaugeUint64(name string) *GaugeUint64
NewGaugeUint64 returns a standard gauge.
func RegisterGauge ¶
func RegisterGauge(name string, opts ...MOption) *GaugeUint64
RegisterGauge is equivalent to Register(NewGauge(), opts) with the default Client.
func (*GaugeUint64) FlushReading ¶
func (g *GaugeUint64) FlushReading(s Sink)
FlushReading to implement Meter interface
type Histogram ¶
type Histogram struct {
// contains filtered or unexported fields
}
Histogram is a series of int64 events all sent to the server
func NewHistogram ¶
NewHistogram creates a new persistent metric object measuring arbitrary sample values by allocating a client side FIFO buffer for recording and flushing measurements
func RegisterHistogram ¶
RegisterHistogram is equivalent to Register(NewHistogram(), opts) with the default Client.
func (Histogram) FlushReading ¶
func (e Histogram) FlushReading(s Sink)
FlushReading - flush as much as possible.
type MConfig ¶
type MConfig struct {
// contains filtered or unexported fields
}
MConfig holds configuration state for metric clients. This is an internal type.
type MOption ¶
type MOption func(MConfig)
MOption is a function manipulating configuration state for a metrics Client.
func FlushInterval ¶
FlushInterval returns a configuration option for a metrics Client. Provide this to NewClient or to Register*
type Meter ¶
type Meter interface { Name() string FlushReading(Sink) // Read the meter, by flushing all unread values. }
Meter is a measurement instrument - a named metric. It measures stuff and can be registered with a client to be periodically reported to the Sink. This interface doesn't describe how measurements are done. That depends on the specific meter it self. This interface only makes the Client able to flush/read the meter to a sink.
type Set ¶
type Set struct {
// contains filtered or unexported fields
}
Set is a not too efficient implementation of that statsd "set" concept. The client will send set membership notifications. Statsd will periodically further propagate the current set size as a gauge. It is client side buffered for the use cases where there will be a lot of membership Add events for the same Set member. This is often not the case, so the AdHocSetMember is often a simpler solution.
func (*Set) FlushReading ¶
Flush sends the current set members to the Sink and resets the Set to empty.
type Sink ¶
type Sink interface { // Record a named value of any time with the Sink Record(mtype int, name string, value interface{}) // RecordNumeric64 is a performance optimation for recording 64-bit values // using the num64 internal sub-package to create a "union" type for // int/uint/float 64 bit values. // Due to the nature of the metric event FIFO queue, using an interface{} // would have requires an additional heap-allocation due to escape analysis // not being able to guarantee the values can be stack allocated. RecordNumeric64(mtype int, name string, value num64.Numeric64) // Flush flushes the record values from the program internal Sink buffers. Flush() }
Sink is a sink for metrics data which methods need to be go-routine safe
type Timer ¶
type Timer struct {
// contains filtered or unexported fields
}
Timer is like Histogram, but the event is a time.Duration. values are remembered as milliseconds
func NewTimer ¶
NewTimer creates a new persistent metric object measuring timing values. by allocating a client side FIFO buffer for recording and flushing measurements
func RegisterTimer ¶
RegisterTimer is equivalent to Register(NewTimer(), opts) with the default Client.
func (Timer) FlushReading ¶
func (e Timer) FlushReading(s Sink)
FlushReading - flush as much as possible.