mirror of https://github.com/status-im/consul.git
vendor: upgrade github.com/armon/go-metrics
Pull in changes to fix race condition for concurrent tests.
This commit is contained in:
parent
375825f34c
commit
c5ba51db19
|
@ -28,39 +28,42 @@ Examples
|
||||||
|
|
||||||
Here is an example of using the package:
|
Here is an example of using the package:
|
||||||
|
|
||||||
func SlowMethod() {
|
```go
|
||||||
// Profiling the runtime of a method
|
func SlowMethod() {
|
||||||
defer metrics.MeasureSince([]string{"SlowMethod"}, time.Now())
|
// Profiling the runtime of a method
|
||||||
}
|
defer metrics.MeasureSince([]string{"SlowMethod"}, time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
// Configure a statsite sink as the global metrics sink
|
// Configure a statsite sink as the global metrics sink
|
||||||
sink, _ := metrics.NewStatsiteSink("statsite:8125")
|
sink, _ := metrics.NewStatsiteSink("statsite:8125")
|
||||||
metrics.NewGlobal(metrics.DefaultConfig("service-name"), sink)
|
metrics.NewGlobal(metrics.DefaultConfig("service-name"), sink)
|
||||||
|
|
||||||
// Emit a Key/Value pair
|
// Emit a Key/Value pair
|
||||||
metrics.EmitKey([]string{"questions", "meaning of life"}, 42)
|
metrics.EmitKey([]string{"questions", "meaning of life"}, 42)
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is an example of setting up a signal handler:
|
||||||
|
|
||||||
Here is an example of setting up an signal handler:
|
```go
|
||||||
|
// Setup the inmem sink and signal handler
|
||||||
|
inm := metrics.NewInmemSink(10*time.Second, time.Minute)
|
||||||
|
sig := metrics.DefaultInmemSignal(inm)
|
||||||
|
metrics.NewGlobal(metrics.DefaultConfig("service-name"), inm)
|
||||||
|
|
||||||
// Setup the inmem sink and signal handler
|
// Run some code
|
||||||
inm := metrics.NewInmemSink(10*time.Second, time.Minute)
|
inm.SetGauge([]string{"foo"}, 42)
|
||||||
sig := metrics.DefaultInmemSignal(inm)
|
inm.EmitKey([]string{"bar"}, 30)
|
||||||
metrics.NewGlobal(metrics.DefaultConfig("service-name"), inm)
|
|
||||||
|
|
||||||
// Run some code
|
inm.IncrCounter([]string{"baz"}, 42)
|
||||||
inm.SetGauge([]string{"foo"}, 42)
|
inm.IncrCounter([]string{"baz"}, 1)
|
||||||
inm.EmitKey([]string{"bar"}, 30)
|
inm.IncrCounter([]string{"baz"}, 80)
|
||||||
|
|
||||||
inm.IncrCounter([]string{"baz"}, 42)
|
inm.AddSample([]string{"method", "wow"}, 42)
|
||||||
inm.IncrCounter([]string{"baz"}, 1)
|
inm.AddSample([]string{"method", "wow"}, 100)
|
||||||
inm.IncrCounter([]string{"baz"}, 80)
|
inm.AddSample([]string{"method", "wow"}, 22)
|
||||||
|
|
||||||
inm.AddSample([]string{"method", "wow"}, 42)
|
....
|
||||||
inm.AddSample([]string{"method", "wow"}, 100)
|
```
|
||||||
inm.AddSample([]string{"method", "wow"}, 22)
|
|
||||||
|
|
||||||
....
|
|
||||||
|
|
||||||
When a signal comes in, output like the following will be dumped to stderr:
|
When a signal comes in, output like the following will be dumped to stderr:
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package metrics
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -25,7 +26,7 @@ type InmemSink struct {
|
||||||
// intervals is a slice of the retained intervals
|
// intervals is a slice of the retained intervals
|
||||||
intervals []*IntervalMetrics
|
intervals []*IntervalMetrics
|
||||||
intervalLock sync.RWMutex
|
intervalLock sync.RWMutex
|
||||||
|
|
||||||
rateDenom float64
|
rateDenom float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ func NewIntervalMetrics(intv time.Time) *IntervalMetrics {
|
||||||
// about a sample
|
// about a sample
|
||||||
type AggregateSample struct {
|
type AggregateSample struct {
|
||||||
Count int // The count of emitted pairs
|
Count int // The count of emitted pairs
|
||||||
Rate float64 // The count of emitted pairs per time unit (usually 1 second)
|
Rate float64 // The count of emitted pairs per time unit (usually 1 second)
|
||||||
Sum float64 // The sum of values
|
Sum float64 // The sum of values
|
||||||
SumSq float64 // The sum of squared values
|
SumSq float64 // The sum of squared values
|
||||||
Min float64 // Minimum value
|
Min float64 // Minimum value
|
||||||
|
@ -105,7 +106,7 @@ func (a *AggregateSample) Ingest(v float64, rateDenom float64) {
|
||||||
if v > a.Max || a.Count == 1 {
|
if v > a.Max || a.Count == 1 {
|
||||||
a.Max = v
|
a.Max = v
|
||||||
}
|
}
|
||||||
a.Rate = float64(a.Count)/rateDenom
|
a.Rate = float64(a.Count) / rateDenom
|
||||||
a.LastUpdated = time.Now()
|
a.LastUpdated = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +121,24 @@ func (a *AggregateSample) String() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewInmemSinkFromURL creates an InmemSink from a URL. It is used
|
||||||
|
// (and tested) from NewMetricSinkFromURL.
|
||||||
|
func NewInmemSinkFromURL(u *url.URL) (MetricSink, error) {
|
||||||
|
params := u.Query()
|
||||||
|
|
||||||
|
interval, err := time.ParseDuration(params.Get("interval"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Bad 'interval' param: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
retain, err := time.ParseDuration(params.Get("retain"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Bad 'retain' param: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewInmemSink(interval, retain), nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewInmemSink is used to construct a new in-memory sink.
|
// NewInmemSink is used to construct a new in-memory sink.
|
||||||
// Uses an aggregation interval and maximum retention period.
|
// Uses an aggregation interval and maximum retention period.
|
||||||
func NewInmemSink(interval, retain time.Duration) *InmemSink {
|
func NewInmemSink(interval, retain time.Duration) *InmemSink {
|
||||||
|
@ -128,7 +147,7 @@ func NewInmemSink(interval, retain time.Duration) *InmemSink {
|
||||||
interval: interval,
|
interval: interval,
|
||||||
retain: retain,
|
retain: retain,
|
||||||
maxIntervals: int(retain / interval),
|
maxIntervals: int(retain / interval),
|
||||||
rateDenom: float64(interval.Nanoseconds()) / float64(rateTimeUnit.Nanoseconds()),
|
rateDenom: float64(interval.Nanoseconds()) / float64(rateTimeUnit.Nanoseconds()),
|
||||||
}
|
}
|
||||||
i.intervals = make([]*IntervalMetrics, 0, i.maxIntervals)
|
i.intervals = make([]*IntervalMetrics, 0, i.maxIntervals)
|
||||||
return i
|
return i
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
// The MetricSink interface is used to transmit metrics information
|
// The MetricSink interface is used to transmit metrics information
|
||||||
// to an external system
|
// to an external system
|
||||||
type MetricSink interface {
|
type MetricSink interface {
|
||||||
|
@ -50,3 +55,43 @@ func (fh FanoutSink) AddSample(key []string, val float32) {
|
||||||
s.AddSample(key, val)
|
s.AddSample(key, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sinkURLFactoryFunc is an generic interface around the *SinkFromURL() function provided
|
||||||
|
// by each sink type
|
||||||
|
type sinkURLFactoryFunc func(*url.URL) (MetricSink, error)
|
||||||
|
|
||||||
|
// sinkRegistry supports the generic NewMetricSink function by mapping URL
|
||||||
|
// schemes to metric sink factory functions
|
||||||
|
var sinkRegistry = map[string]sinkURLFactoryFunc{
|
||||||
|
"statsd": NewStatsdSinkFromURL,
|
||||||
|
"statsite": NewStatsiteSinkFromURL,
|
||||||
|
"inmem": NewInmemSinkFromURL,
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMetricSinkFromURL allows a generic URL input to configure any of the
|
||||||
|
// supported sinks. The scheme of the URL identifies the type of the sink, the
|
||||||
|
// and query parameters are used to set options.
|
||||||
|
//
|
||||||
|
// "statsd://" - Initializes a StatsdSink. The host and port are passed through
|
||||||
|
// as the "addr" of the sink
|
||||||
|
//
|
||||||
|
// "statsite://" - Initializes a StatsiteSink. The host and port become the
|
||||||
|
// "addr" of the sink
|
||||||
|
//
|
||||||
|
// "inmem://" - Initializes an InmemSink. The host and port are ignored. The
|
||||||
|
// "interval" and "duration" query parameters must be specified with valid
|
||||||
|
// durations, see NewInmemSink for details.
|
||||||
|
func NewMetricSinkFromURL(urlStr string) (MetricSink, error) {
|
||||||
|
u, err := url.Parse(urlStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sinkURLFactoryFunc := sinkRegistry[u.Scheme]
|
||||||
|
if sinkURLFactoryFunc == nil {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"cannot create metric sink, unrecognized sink name: %q", u.Scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sinkURLFactoryFunc(u)
|
||||||
|
}
|
||||||
|
|
|
@ -26,10 +26,11 @@ type Metrics struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shared global metrics instance
|
// Shared global metrics instance
|
||||||
var global atomic.Value
|
var globalMetrics atomic.Value // *Metrics
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
global.Store(&Metrics{sink: &BlackholeSink{}})
|
// Initialize to a blackhole sink to avoid errors
|
||||||
|
globalMetrics.Store(&Metrics{sink: &BlackholeSink{}})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultConfig provides a sane default configuration
|
// DefaultConfig provides a sane default configuration
|
||||||
|
@ -68,28 +69,28 @@ func New(conf *Config, sink MetricSink) (*Metrics, error) {
|
||||||
func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) {
|
func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) {
|
||||||
metrics, err := New(conf, sink)
|
metrics, err := New(conf, sink)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
global.Store(metrics)
|
globalMetrics.Store(metrics)
|
||||||
}
|
}
|
||||||
return metrics, err
|
return metrics, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proxy all the methods to the globalMetrics instance
|
// Proxy all the methods to the globalMetrics instance
|
||||||
func SetGauge(key []string, val float32) {
|
func SetGauge(key []string, val float32) {
|
||||||
global.Load().(*Metrics).SetGauge(key, val)
|
globalMetrics.Load().(*Metrics).SetGauge(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EmitKey(key []string, val float32) {
|
func EmitKey(key []string, val float32) {
|
||||||
global.Load().(*Metrics).EmitKey(key, val)
|
globalMetrics.Load().(*Metrics).EmitKey(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IncrCounter(key []string, val float32) {
|
func IncrCounter(key []string, val float32) {
|
||||||
global.Load().(*Metrics).IncrCounter(key, val)
|
globalMetrics.Load().(*Metrics).IncrCounter(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddSample(key []string, val float32) {
|
func AddSample(key []string, val float32) {
|
||||||
global.Load().(*Metrics).AddSample(key, val)
|
globalMetrics.Load().(*Metrics).AddSample(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MeasureSince(key []string, start time.Time) {
|
func MeasureSince(key []string, start time.Time) {
|
||||||
global.Load().(*Metrics).MeasureSince(key, start)
|
globalMetrics.Load().(*Metrics).MeasureSince(key, start)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -23,6 +24,12 @@ type StatsdSink struct {
|
||||||
metricQueue chan string
|
metricQueue chan string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewStatsdSinkFromURL creates an StatsdSink from a URL. It is used
|
||||||
|
// (and tested) from NewMetricSinkFromURL.
|
||||||
|
func NewStatsdSinkFromURL(u *url.URL) (MetricSink, error) {
|
||||||
|
return NewStatsdSink(u.Host)
|
||||||
|
}
|
||||||
|
|
||||||
// NewStatsdSink is used to create a new StatsdSink
|
// NewStatsdSink is used to create a new StatsdSink
|
||||||
func NewStatsdSink(addr string) (*StatsdSink, error) {
|
func NewStatsdSink(addr string) (*StatsdSink, error) {
|
||||||
s := &StatsdSink{
|
s := &StatsdSink{
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -16,6 +17,12 @@ const (
|
||||||
flushInterval = 100 * time.Millisecond
|
flushInterval = 100 * time.Millisecond
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewStatsiteSinkFromURL creates an StatsiteSink from a URL. It is used
|
||||||
|
// (and tested) from NewMetricSinkFromURL.
|
||||||
|
func NewStatsiteSinkFromURL(u *url.URL) (MetricSink, error) {
|
||||||
|
return NewStatsiteSink(u.Host)
|
||||||
|
}
|
||||||
|
|
||||||
// StatsiteSink provides a MetricSink that can be used with a
|
// StatsiteSink provides a MetricSink that can be used with a
|
||||||
// statsite metrics server
|
// statsite metrics server
|
||||||
type StatsiteSink struct {
|
type StatsiteSink struct {
|
||||||
|
|
|
@ -87,10 +87,10 @@
|
||||||
"revisionTime": "2015-08-27T00:49:46Z"
|
"revisionTime": "2015-08-27T00:49:46Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "d6798KSc0jDg2MHNxKdgyNfMK7A=",
|
"checksumSHA1": "M+ZeYktTT2wak9ZvQ0OZBbIHAGo=",
|
||||||
"path": "github.com/armon/go-metrics",
|
"path": "github.com/armon/go-metrics",
|
||||||
"revision": "3df31a1ada83e310c2e24b267c8e8b68836547b4",
|
"revision": "f036747b9d0e8590f175a5d654a2194a7d9df4b5",
|
||||||
"revisionTime": "2016-07-17T04:34:58Z"
|
"revisionTime": "2017-06-01T21:44:32Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "OmqT9Y1mAHvlAKeJh0jBHC9SH78=",
|
"checksumSHA1": "OmqT9Y1mAHvlAKeJh0jBHC9SH78=",
|
||||||
|
|
Loading…
Reference in New Issue