github.com/uber-go/tally/v4@v4.1.17/README.md (about) 1 # :heavy_check_mark: tally [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] 2 3 Fast, buffered, hierarchical stats collection in Go. 4 5 ## Installation 6 `go get -u github.com/uber-go/tally` 7 8 ## Abstract 9 10 Tally provides a common interface for emitting metrics, while letting you not worry about the velocity of metrics emission. 11 12 By default it buffers counters, gauges and histograms 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 summaries or histograms independently by a reporter. 13 14 ## Structure 15 16 - Scope: Keeps track of metrics, and their common metadata. 17 - Metrics: Counters, Gauges, Timers and Histograms. 18 - Reporter: Implemented by you. Accepts aggregated values from the scope. Forwards the aggregated values to your metrics ingestion pipeline. 19 - The reporters already available listed alphabetically are: 20 - `github.com/uber-go/tally/m3`: Report m3 metrics, timers are not sampled and forwarded directly. 21 - `github.com/uber-go/tally/multi`: Report to multiple reporters, you can multi-write metrics to other reporters simply. 22 - `github.com/uber-go/tally/prometheus`: Report prometheus metrics, timers by default are made summaries with an option to make them histograms instead. 23 - `github.com/uber-go/tally/statsd`: Report statsd metrics, no support for tags. 24 25 ### Basics 26 27 - Scopes created with tally provide race-safe registration and use of all metric types `Counter`, `Gauge`, `Timer`, `Histogram`. 28 - `NewRootScope(...)` returns a `Scope` and `io.Closer`, the second return value is used to stop the scope's goroutine reporting values from the scope to it's reporter. This is to reduce the footprint of `Scope` from the public API for those implementing it themselves to use in Go packages that take a tally `Scope`. 29 30 ### Acquire a Scope ### 31 ```go 32 reporter = NewMyStatsReporter() // Implement as you will 33 tags := map[string]string{ 34 "dc": "east-1", 35 "type": "master", 36 } 37 reportEvery := time.Second 38 39 scope := tally.NewRootScope(tally.ScopeOptions{ 40 Tags: tags, 41 Reporter: reporter, 42 }, reportEvery) 43 ``` 44 45 ### Get/Create a metric, use it ### 46 ```go 47 // Get a counter, increment a counter 48 reqCounter := scope.Counter("requests") // cache me 49 reqCounter.Inc(1) 50 51 queueGauge := scope.Gauge("queue_length") // cache me 52 queueGauge.Update(42) 53 ``` 54 55 ### Report your metrics ### 56 Use the inbuilt statsd reporter: 57 58 ```go 59 import ( 60 "io" 61 "github.com/cactus/go-statsd-client/v5/statsd" 62 "github.com/uber-go/tally" 63 tallystatsd "github.com/uber-go/tally/statsd" 64 // ... 65 ) 66 67 func newScope() (tally.Scope, io.Closer) { 68 statter, _ := statsd.NewBufferedClient("127.0.0.1:8125", 69 "stats", 100*time.Millisecond, 1440) 70 71 reporter := tallystatsd.NewReporter(statter, tallystatsd.Options{ 72 SampleRate: 1.0, 73 }) 74 75 scope, closer := tally.NewRootScope(tally.ScopeOptions{ 76 Prefix: "my-service", 77 Tags: map[string]string{}, 78 Reporter: reporter, 79 }, time.Second) 80 81 return scope, closer 82 } 83 ``` 84 85 Implement your own reporter using the `StatsReporter` interface: 86 87 ```go 88 89 // BaseStatsReporter implements the shared reporter methods. 90 type BaseStatsReporter interface { 91 Capabilities() Capabilities 92 Flush() 93 } 94 95 // StatsReporter is a backend for Scopes to report metrics to. 96 type StatsReporter interface { 97 BaseStatsReporter 98 99 // ReportCounter reports a counter value 100 ReportCounter( 101 name string, 102 tags map[string]string, 103 value int64, 104 ) 105 106 // ReportGauge reports a gauge value 107 ReportGauge( 108 name string, 109 tags map[string]string, 110 value float64, 111 ) 112 113 // ReportTimer reports a timer value 114 ReportTimer( 115 name string, 116 tags map[string]string, 117 interval time.Duration, 118 ) 119 120 // ReportHistogramValueSamples reports histogram samples for a bucket 121 ReportHistogramValueSamples( 122 name string, 123 tags map[string]string, 124 buckets Buckets, 125 bucketLowerBound, 126 bucketUpperBound float64, 127 samples int64, 128 ) 129 130 // ReportHistogramDurationSamples reports histogram samples for a bucket 131 ReportHistogramDurationSamples( 132 name string, 133 tags map[string]string, 134 buckets Buckets, 135 bucketLowerBound, 136 bucketUpperBound time.Duration, 137 samples int64, 138 ) 139 } 140 ``` 141 142 Or implement your own metrics implementation that matches the tally `Scope` interface to use different buffering semantics: 143 144 ```go 145 type Scope interface { 146 // Counter returns the Counter object corresponding to the name. 147 Counter(name string) Counter 148 149 // Gauge returns the Gauge object corresponding to the name. 150 Gauge(name string) Gauge 151 152 // Timer returns the Timer object corresponding to the name. 153 Timer(name string) Timer 154 155 // Histogram returns the Histogram object corresponding to the name. 156 // To use default value and duration buckets configured for the scope 157 // simply pass tally.DefaultBuckets or nil. 158 // You can use tally.ValueBuckets{x, y, ...} for value buckets. 159 // You can use tally.DurationBuckets{x, y, ...} for duration buckets. 160 // You can use tally.MustMakeLinearValueBuckets(start, width, count) for linear values. 161 // You can use tally.MustMakeLinearDurationBuckets(start, width, count) for linear durations. 162 // You can use tally.MustMakeExponentialValueBuckets(start, factor, count) for exponential values. 163 // You can use tally.MustMakeExponentialDurationBuckets(start, factor, count) for exponential durations. 164 Histogram(name string, buckets Buckets) Histogram 165 166 // Tagged returns a new child scope with the given tags and current tags. 167 Tagged(tags map[string]string) Scope 168 169 // SubScope returns a new child scope appending a further name prefix. 170 SubScope(name string) Scope 171 172 // Capabilities returns a description of metrics reporting capabilities. 173 Capabilities() Capabilities 174 } 175 176 // Capabilities is a description of metrics reporting capabilities. 177 type Capabilities interface { 178 // Reporting returns whether the reporter has the ability to actively report. 179 Reporting() bool 180 181 // Tagging returns whether the reporter has the capability for tagged metrics. 182 Tagging() bool 183 } 184 ``` 185 186 ## Performance 187 188 This stuff needs to be fast. With that in mind, we avoid locks and unnecessary memory allocations. 189 190 ``` 191 BenchmarkCounterInc-8 200000000 7.68 ns/op 192 BenchmarkReportCounterNoData-8 300000000 4.88 ns/op 193 BenchmarkReportCounterWithData-8 100000000 21.6 ns/op 194 BenchmarkGaugeSet-8 100000000 16.0 ns/op 195 BenchmarkReportGaugeNoData-8 100000000 10.4 ns/op 196 BenchmarkReportGaugeWithData-8 50000000 27.6 ns/op 197 BenchmarkTimerInterval-8 50000000 37.7 ns/op 198 BenchmarkTimerReport-8 300000000 5.69 ns/op 199 ``` 200 201 <hr> 202 203 Released under the [MIT License](LICENSE). 204 205 [doc-img]: https://godoc.org/github.com/uber-go/tally?status.svg 206 [doc]: https://godoc.org/github.com/uber-go/tally 207 [ci-img]: https://travis-ci.org/uber-go/tally.svg?branch=master 208 [ci]: https://travis-ci.org/uber-go/tally 209 [cov-img]: https://coveralls.io/repos/github/uber-go/tally/badge.svg?branch=master 210 [cov]: https://coveralls.io/github/uber-go/tally?branch=master 211 [glide.lock]: https://github.com/uber-go/tally/blob/master/glide.lock 212 [v1]: https://github.com/uber-go/tally/milestones