README
✔️ tally

Fast, buffered, hierarchical stats collection in Go.
Installation
go get -u github.com/uber-go/tally
Abstract
Tally provides a common interface for emitting metrics, while letting you not worry about the velocity of metrics emission.
By default it buffers counters and gauges at a specified interval but does not buffer timer values. This is primarily so timer values can have all their values sampled if desired and if not they can be sampled as histograms.
Structure
- Scope: Keeps track of metrics, and their common metadata.
- Metrics: Counters, Gauges, Timers.
- Reporter: Implemented by you. Accepts aggregated values from the scope. Forwards the aggregated values to your metrics ingestion pipeline.
Acquire a Scope
reporter = NewMyStatsReporter() // Implement as you will
tags := map[string]string{
"dc": "east-1",
"type": "master",
}
reportEvery := 1 * time.Second
scope := tally.NewRootScope("some_prefix", tags, reporter, reportEvery, tally.DefaultSeparator)
Get/Create a metric, use it
// Get a counter, increment a counter
reqCounter := scope.Counter("requests") // cache me
reqCounter.Inc(1)
queueGauge := scope.Gauge("queue_length") // cache me
queueGauge.Update(42)
Report your metrics
Use the inbuilt statsd reporter:
import (
"github.com/cactus/go-statsd-client/statsd"
"github.com/uber-go/tally"
tallystatsd "github.com/uber-go/tally/statsd"
// ...
)
client, err := statsd.NewClient("statsd.aggregator.local:1234", "")
// ...
opts := tallystatsd.NewOptions().SetSampleRate(1.0)
reporter = tallystatsd.NewStatsdReporter(client, opts)
tags := map[string]string{
"dc": "east-1",
"type": "master",
}
reportEvery := 1 * time.Second
scope := tally.NewRootScope("some_prefix", tags, reporter, reportEvery, tally.DefaultSeparator)
Implement your own reporter using the StatsReporter
interface:
type StatsReporter interface {
// ReportCounter reports a counter value
ReportCounter(name string, tags map[string]string, value int64)
// ReportGauge reports a gauge value
ReportGauge(name string, tags map[string]string, value float64)
// ReportTimer reports a timer value
ReportTimer(name string, tags map[string]string, interval time.Duration)
// Capabilities returns a description of metrics reporting capabilities
Capabilities() Capabilities
// Flush is expected to be called by a Scope when it completes a round or reporting
Flush()
}
Or implement your own metrics implementation that matches the tally Scope
interface to use different buffering semantics:
type Scope interface {
// Counter returns the Counter object corresponding to the name
Counter(name string) Counter
// Gauge returns the Gauge object corresponding to the name
Gauge(name string) Gauge
// Timer returns the Timer object corresponding to the name
Timer(name string) Timer
// Tagged returns a new child scope with the given tags and current tags
Tagged(tags map[string]string) Scope
// SubScope returns a new child scope appending a further name prefix
SubScope(name string) Scope
// Capabilities returns a description of metrics reporting capabilities
Capabilities() Capabilities
}
Performance
This stuff needs to be fast. With that in mind, we avoid locks and unnecessary memory allocations.
BenchmarkCounterInc-8 200000000 7.68 ns/op
BenchmarkReportCounterNoData-8 300000000 4.88 ns/op
BenchmarkReportCounterWithData-8 100000000 21.6 ns/op
BenchmarkGaugeSet-8 100000000 16.0 ns/op
BenchmarkReportGaugeNoData-8 100000000 10.4 ns/op
BenchmarkReportGaugeWithData-8 50000000 27.6 ns/op
BenchmarkTimerInterval-8 50000000 37.7 ns/op
BenchmarkTimerReport-8 300000000 5.69 ns/op
Released under the [MIT License](LICENSE).
Documentation
Index ¶
- Variables
- func KeyForPrefixedStringMap(prefix string, stringMap map[string]string) string
- func KeyForStringMap(stringMap map[string]string) string
- type BaseStatsReporter
- type CachedCount
- type CachedGauge
- type CachedStatsReporter
- type CachedTimer
- type Capabilities
- type Counter
- type CounterSnapshot
- type Gauge
- type GaugeSnapshot
- type ObjectPool
- type Scope
- type Snapshot
- type StatsReporter
- type Stopwatch
- type TestScope
- type Timer
- type TimerSnapshot
Constants ¶
Variables ¶
var (
// NoopScope is a scope that does nothing
NoopScope, _ = NewRootScope("", nil, NullStatsReporter, 0, "")
// DefaultSeparator is the default separator used to join nested scopes
DefaultSeparator = "."
)
Functions ¶
func KeyForPrefixedStringMap ¶
KeyForPrefixedStringMap generates a unique key for a a prefix and a map string set combination.
func KeyForStringMap ¶
KeyForStringMap generates a unique key for a map string set combination.
Types ¶
type BaseStatsReporter ¶
type BaseStatsReporter interface { Capabilities() Capabilities Flush() }
BaseStatsReporter implements the shared reporter methods
type CachedCount ¶
type CachedCount interface {
ReportCount(value int64)
}
CachedCount interface for reporting an individual counter
type CachedGauge ¶
type CachedGauge interface {
ReportGauge(value float64)
}
CachedGauge interface for reporting an individual gauge
type CachedStatsReporter ¶
type CachedStatsReporter interface { BaseStatsReporter // AllocateCounter pre allocates a counter data structure with name & tags. AllocateCounter(name string, tags map[string]string) CachedCount // AllocateGauge pre allocates a gauge data structure with name & tags. AllocateGauge(name string, tags map[string]string) CachedGauge // AllocateTimer pre allocates a timer data structure with name & tags. AllocateTimer(name string, tags map[string]string) CachedTimer }
CachedStatsReporter is a backend for Scopes that pre allocates all counter, gauges & timers. This is harder to implement but more performant
type CachedTimer ¶
CachedTimer interface for reporting an individual timer
type Capabilities ¶
type Capabilities interface { // Reporting returns whether the reporter has the ability to actively report Reporting() bool // Tagging returns whether the reporter has the capability for tagged metrics Tagging() bool }
Capabilities is a description of metrics reporting capabilities
type Counter ¶
type Counter interface { // Inc increments the counter by a delta Inc(delta int64) }
Counter is the interface for emitting counter type metrics
type CounterSnapshot ¶
type CounterSnapshot interface { // Name returns the name Name() string // Tags returns the tags Tags() map[string]string // Value returns the value Value() int64 }
CounterSnapshot is a snapshot of a counter
type Gauge ¶
type Gauge interface { // Update sets the gauges absolute value Update(value float64) }
Gauge is the interface for emitting gauge metrics
type GaugeSnapshot ¶
type GaugeSnapshot interface { // Name returns the name Name() string // Tags returns the tags Tags() map[string]string // Value returns the value Value() float64 }
GaugeSnapshot is a snapshot of a gauge
type ObjectPool ¶
type ObjectPool struct {
// contains filtered or unexported fields
}
ObjectPool is an minimalistic object pool to avoid any circular dependencies on any other object pool.
func (*ObjectPool) Init ¶
func (p *ObjectPool) Init(alloc func() interface{})
Init initializes the object pool.
func (*ObjectPool) Put ¶
func (p *ObjectPool) Put(obj interface{})
Put puts an object back to the pool.
type Scope ¶
type Scope interface { // Counter returns the Counter object corresponding to the name Counter(name string) Counter // Gauge returns the Gauge object corresponding to the name Gauge(name string) Gauge // Timer returns the Timer object corresponding to the name Timer(name string) Timer // Tagged returns a new child scope with the given tags and current tags Tagged(tags map[string]string) Scope // SubScope returns a new child scope appending a further name prefix SubScope(name string) Scope // Capabilities returns a description of metrics reporting capabilities Capabilities() Capabilities }
Scope is a namespace wrapper around a stats reporter, ensuring that all emitted values have a given prefix or set of tags
type Snapshot ¶
type Snapshot interface { // Counters returns a snapshot of all counter summations since last report execution Counters() map[string]CounterSnapshot // Gauges returns a snapshot of gauge last values since last report execution Gauges() map[string]GaugeSnapshot // Timers returns a snapshot of timer values since last report execution Timers() map[string]TimerSnapshot }
Snapshot is a snapshot of values since last report execution
type StatsReporter ¶
type StatsReporter interface { BaseStatsReporter // ReportCounter reports a counter value ReportCounter(name string, tags map[string]string, value int64) // ReportGauge reports a gauge value ReportGauge(name string, tags map[string]string, value float64) // ReportTimer reports a timer value ReportTimer(name string, tags map[string]string, interval time.Duration) }
StatsReporter is a backend for Scopes to report metrics to
var NullStatsReporter StatsReporter = nullStatsReporter{}
NullStatsReporter is an implementatin of StatsReporter than simply does nothing.
type Stopwatch ¶
type Stopwatch struct {
// contains filtered or unexported fields
}
Stopwatch is a helper convenience struct for nicer tracking of elapsed time
type TestScope ¶
type TestScope interface { Scope // Snapshot returns a copy of all values since the last report execution, // this is an expensive operation and should only be use for testing purposes Snapshot() Snapshot }
TestScope is a metrics collector that has no reporting, ensuring that all emitted values have a given prefix or set of tags
Directories
Path | Synopsis |
---|---|