mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
metrics: updates per feedback
This commit is contained in:
parent
f6bc65fc68
commit
6eefd0b58c
21 changed files with 77 additions and 67 deletions
|
|
@ -2,7 +2,7 @@ package metrics
|
||||||
|
|
||||||
import "sync/atomic"
|
import "sync/atomic"
|
||||||
|
|
||||||
// Counters hold an int64 value that can be incremented and decremented.
|
// Counter holds an int64 value that can be incremented and decremented.
|
||||||
type Counter interface {
|
type Counter interface {
|
||||||
Clear()
|
Clear()
|
||||||
Count() int64
|
Count() int64
|
||||||
|
|
|
||||||
|
|
@ -19,17 +19,18 @@ var (
|
||||||
gcStats debug.GCStats
|
gcStats debug.GCStats
|
||||||
)
|
)
|
||||||
|
|
||||||
// Capture new values for the Go garbage collector statistics exported in
|
// CaptureDebugGCStats captures new values for the Go garbage collector statistics
|
||||||
// debug.GCStats. This is designed to be called as a goroutine.
|
// exported in debug.GCStats. This is designed to be called as a goroutine.
|
||||||
func CaptureDebugGCStats(r Registry, d time.Duration) {
|
func CaptureDebugGCStats(r Registry, d time.Duration) {
|
||||||
for range time.Tick(d) {
|
for range time.Tick(d) {
|
||||||
CaptureDebugGCStatsOnce(r)
|
CaptureDebugGCStatsOnce(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capture new values for the Go garbage collector statistics exported in
|
// CaptureDebugGCStatsOnce captures new values for the Go garbage collector
|
||||||
// debug.GCStats. This is designed to be called in a background goroutine.
|
// statistics exported in debug.GCStats. This is designed to be called in a
|
||||||
// Giving a registry which has not been given to RegisterDebugGCStats will
|
// background goroutine.Giving a registry which has not been given to
|
||||||
|
// RegisterDebugGCStats will
|
||||||
// panic.
|
// panic.
|
||||||
//
|
//
|
||||||
// Be careful (but much less so) with this because debug.ReadGCStats calls
|
// Be careful (but much less so) with this because debug.ReadGCStats calls
|
||||||
|
|
@ -50,8 +51,8 @@ func CaptureDebugGCStatsOnce(r Registry) {
|
||||||
debugMetrics.GCStats.PauseTotal.Update(int64(gcStats.PauseTotal))
|
debugMetrics.GCStats.PauseTotal.Update(int64(gcStats.PauseTotal))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register metrics for the Go garbage collector statistics exported in
|
// RegisterDebugGCStats registers metrics for the Go garbage collector statistics
|
||||||
// debug.GCStats. The metrics are named by their fully-qualified Go symbols,
|
// exported in debug.GCStats. The metrics are named by their fully-qualified Go symbols,
|
||||||
// i.e. debug.GCStats.PauseTotal.
|
// i.e. debug.GCStats.PauseTotal.
|
||||||
func RegisterDebugGCStats(r Registry) {
|
func RegisterDebugGCStats(r Registry) {
|
||||||
debugMetrics.GCStats.LastGC = NewGauge()
|
debugMetrics.GCStats.LastGC = NewGauge()
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EWMAs continuously calculate an exponentially-weighted moving average
|
// EWMA continuously calculates an exponentially-weighted moving average
|
||||||
// based on an outside source of clock ticks.
|
// based on an outside source of clock ticks.
|
||||||
type EWMA interface {
|
type EWMA interface {
|
||||||
Rate() float64
|
Rate() float64
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
// Hook go-metrics into expvar
|
// Package exp hooks go-metrics into expvar.
|
||||||
// on any /debug/metrics request, load all vars from the registry into expvar, and execute regular expvar handler
|
//
|
||||||
|
// On any /debug/metrics request, loads all vars from the registry into expvar,
|
||||||
|
// and executes regular expvar handler.
|
||||||
package exp
|
package exp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package metrics
|
||||||
|
|
||||||
import "sync/atomic"
|
import "sync/atomic"
|
||||||
|
|
||||||
// Gauges hold an int64 value that can be set arbitrarily.
|
// Gauge holds an int64 value that can be set arbitrarily.
|
||||||
type Gauge interface {
|
type Gauge interface {
|
||||||
Snapshot() Gauge
|
Snapshot() Gauge
|
||||||
Update(int64)
|
Update(int64)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package metrics
|
||||||
|
|
||||||
import "sync"
|
import "sync"
|
||||||
|
|
||||||
// GaugeFloat64s hold a float64 value that can be set arbitrarily.
|
// GaugeFloat64 holds a float64 value that can be set arbitrarily.
|
||||||
type GaugeFloat64 interface {
|
type GaugeFloat64 interface {
|
||||||
Snapshot() GaugeFloat64
|
Snapshot() GaugeFloat64
|
||||||
Update(float64)
|
Update(float64)
|
||||||
|
|
@ -38,7 +38,7 @@ func NewRegisteredGaugeFloat64(name string, r Registry) GaugeFloat64 {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFunctionalGauge constructs a new FunctionalGauge.
|
// NewFunctionalGaugeFloat64 constructs a new FunctionalGauge.
|
||||||
func NewFunctionalGaugeFloat64(f func() float64) GaugeFloat64 {
|
func NewFunctionalGaugeFloat64(f func() float64) GaugeFloat64 {
|
||||||
if !Enabled {
|
if !Enabled {
|
||||||
return NilGaugeFloat64{}
|
return NilGaugeFloat64{}
|
||||||
|
|
@ -46,7 +46,7 @@ func NewFunctionalGaugeFloat64(f func() float64) GaugeFloat64 {
|
||||||
return &FunctionalGaugeFloat64{value: f}
|
return &FunctionalGaugeFloat64{value: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRegisteredFunctionalGauge constructs and registers a new StandardGauge.
|
// NewRegisteredFunctionalGaugeFloat64 constructs and registers a new StandardGauge.
|
||||||
func NewRegisteredFunctionalGaugeFloat64(name string, r Registry, f func() float64) GaugeFloat64 {
|
func NewRegisteredFunctionalGaugeFloat64(name string, r Registry, f func() float64) GaugeFloat64 {
|
||||||
c := NewFunctionalGaugeFloat64(f)
|
c := NewFunctionalGaugeFloat64(f)
|
||||||
if nil == r {
|
if nil == r {
|
||||||
|
|
@ -70,7 +70,7 @@ func (GaugeFloat64Snapshot) Update(float64) {
|
||||||
// Value returns the value at the time the snapshot was taken.
|
// Value returns the value at the time the snapshot was taken.
|
||||||
func (g GaugeFloat64Snapshot) Value() float64 { return float64(g) }
|
func (g GaugeFloat64Snapshot) Value() float64 { return float64(g) }
|
||||||
|
|
||||||
// NilGauge is a no-op Gauge.
|
// NilGaugeFloat64 is a no-op Gauge.
|
||||||
type NilGaugeFloat64 struct{}
|
type NilGaugeFloat64 struct{}
|
||||||
|
|
||||||
// Snapshot is a no-op.
|
// Snapshot is a no-op.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
// Healthchecks hold an error value describing an arbitrary up/down status.
|
// Healthcheck holds an error value describing an arbitrary up/down status.
|
||||||
type Healthcheck interface {
|
type Healthcheck interface {
|
||||||
Check()
|
Check()
|
||||||
Error() error
|
Error() error
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
// Histograms calculate distribution statistics from a series of int64 values.
|
// Histogram calculates distribution statistics from a series of int64 values.
|
||||||
type Histogram interface {
|
type Histogram interface {
|
||||||
Clear()
|
Clear()
|
||||||
Count() int64
|
Count() int64
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ func WriteJSONOnce(r Registry, w io.Writer) {
|
||||||
json.NewEncoder(w).Encode(r)
|
json.NewEncoder(w).Encode(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON returns a byte slice containing a JSON representation of all
|
||||||
|
// the metrics in the Registry.
|
||||||
func (p *PrefixedRegistry) MarshalJSON() ([]byte, error) {
|
func (p *PrefixedRegistry) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(p.GetAll())
|
return json.Marshal(p.GetAll())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
const Operations = "operations"
|
const Operations = "operations"
|
||||||
const OperationsShort = "ops"
|
const OperationsShort = "ops"
|
||||||
|
|
||||||
|
// LibratoClient holds an email and a token.
|
||||||
type LibratoClient struct {
|
type LibratoClient struct {
|
||||||
Email, Token string
|
Email, Token string
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +53,7 @@ const (
|
||||||
Counters = "counters"
|
Counters = "counters"
|
||||||
Gauges = "gauges"
|
Gauges = "gauges"
|
||||||
|
|
||||||
MetricsPostUrl = "https://metrics-api.librato.com/v1/metrics"
|
MetricsPostURL = "https://metrics-api.librato.com/v1/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Measurement map[string]interface{}
|
type Measurement map[string]interface{}
|
||||||
|
|
@ -80,7 +81,7 @@ func (c *LibratoClient) PostMetrics(batch Batch) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if req, err = http.NewRequest("POST", MetricsPostUrl, bytes.NewBuffer(js)); err != nil {
|
if req, err = http.NewRequest("POST", MetricsPostURL, bytes.NewBuffer(js)); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ func Librato(r metrics.Registry, d time.Duration, e string, t string, s string,
|
||||||
func (rep *Reporter) Run() {
|
func (rep *Reporter) Run() {
|
||||||
log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-librato and will be removed from rcrowley/go-metrics on August 5th 2015")
|
log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-librato and will be removed from rcrowley/go-metrics on August 5th 2015")
|
||||||
ticker := time.Tick(rep.Interval)
|
ticker := time.Tick(rep.Interval)
|
||||||
metricsApi := &LibratoClient{rep.Email, rep.Token}
|
metricsAPI := &LibratoClient{rep.Email, rep.Token}
|
||||||
for now := range ticker {
|
for now := range ticker {
|
||||||
var metrics Batch
|
var metrics Batch
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -51,7 +51,7 @@ func (rep *Reporter) Run() {
|
||||||
log.Printf("ERROR constructing librato request body %s", err)
|
log.Printf("ERROR constructing librato request body %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := metricsApi.PostMetrics(metrics); err != nil {
|
if err := metricsAPI.PostMetrics(metrics); err != nil {
|
||||||
log.Printf("ERROR sending metrics to librato %s", err)
|
log.Printf("ERROR sending metrics to librato %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,18 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Logger will print any number of passed arguments of type interface.
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
Printf(format string, v ...interface{})
|
Printf(format string, v ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log outputs each metric in the given registry periodically using the given
|
||||||
|
// logger and current time in nanos.
|
||||||
func Log(r Registry, freq time.Duration, l Logger) {
|
func Log(r Registry, freq time.Duration, l Logger) {
|
||||||
LogScaled(r, freq, time.Nanosecond, l)
|
LogScaled(r, freq, time.Nanosecond, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output each metric in the given registry periodically using the given
|
// LogScaled outputs each metric in the given registry periodically using the given
|
||||||
// logger. Print timings in `scale` units (eg time.Millisecond) rather than nanos.
|
// logger. Print timings in `scale` units (eg time.Millisecond) rather than nanos.
|
||||||
func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) {
|
func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) {
|
||||||
du := float64(scale)
|
du := float64(scale)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Meters count events to produce exponentially-weighted moving average rates
|
// Meter counts events to produce exponentially-weighted moving average rates
|
||||||
// at one-, five-, and fifteen-minutes and a mean rate.
|
// at one-, five-, and fifteen-minutes and a mean rate.
|
||||||
type Meter interface {
|
type Meter interface {
|
||||||
Count() int64
|
Count() int64
|
||||||
|
|
@ -46,7 +46,7 @@ func NewMeter() Meter {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMeter constructs and registers a new StandardMeter and launches a
|
// NewRegisteredMeter constructs and registers a new StandardMeter and launches a
|
||||||
// goroutine.
|
// goroutine.
|
||||||
// Be sure to unregister the meter from the registry once it is of no use to
|
// Be sure to unregister the meter from the registry once it is of no use to
|
||||||
// allow for garbage collection.
|
// allow for garbage collection.
|
||||||
|
|
@ -110,7 +110,7 @@ func (NilMeter) Rate1() float64 { return 0.0 }
|
||||||
// Rate5 is a no-op.
|
// Rate5 is a no-op.
|
||||||
func (NilMeter) Rate5() float64 { return 0.0 }
|
func (NilMeter) Rate5() float64 { return 0.0 }
|
||||||
|
|
||||||
// Rate15is a no-op.
|
// Rate15 is a no-op.
|
||||||
func (NilMeter) Rate15() float64 { return 0.0 }
|
func (NilMeter) Rate15() float64 { return 0.0 }
|
||||||
|
|
||||||
// RateMean is a no-op.
|
// RateMean is a no-op.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// <https://github.com/rcrowley/go-metrics>
|
// <https://github.com/rcrowley/go-metrics>
|
||||||
//
|
//
|
||||||
// Coda Hale's original work: <https://github.com/codahale/metrics>
|
// Package metrics is a go port of Coda Hale's original work: <https://github.com/codahale/metrics>
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -19,7 +19,7 @@ import (
|
||||||
//
|
//
|
||||||
// This global kill-switch helps quantify the observer effect and makes
|
// This global kill-switch helps quantify the observer effect and makes
|
||||||
// for less cluttered pprof profiles.
|
// for less cluttered pprof profiles.
|
||||||
var Enabled bool = false
|
var Enabled = false
|
||||||
|
|
||||||
// MetricsEnabledFlag is the CLI flag name to use to enable metrics collections.
|
// MetricsEnabledFlag is the CLI flag name to use to enable metrics collections.
|
||||||
const MetricsEnabledFlag = "metrics"
|
const MetricsEnabledFlag = "metrics"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var shortHostName string = ""
|
var shortHostName string
|
||||||
|
|
||||||
// OpenTSDBConfig provides a container with configuration parameters for
|
// OpenTSDBConfig provides a container with configuration parameters for
|
||||||
// the OpenTSDB exporter
|
// the OpenTSDB exporter
|
||||||
|
|
|
||||||
|
|
@ -50,33 +50,32 @@ type Registry interface {
|
||||||
UnregisterAll()
|
UnregisterAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// The standard implementation of a Registry is a mutex-protected map
|
// StandardRegistry is a mutex protected implementation of a Registry.
|
||||||
// of names to metrics.
|
|
||||||
type StandardRegistry struct {
|
type StandardRegistry struct {
|
||||||
metrics map[string]interface{}
|
metrics map[string]interface{}
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new registry.
|
// NewRegistry creates a new registry.
|
||||||
func NewRegistry() Registry {
|
func NewRegistry() Registry {
|
||||||
return &StandardRegistry{metrics: make(map[string]interface{})}
|
return &StandardRegistry{metrics: make(map[string]interface{})}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the given function for each registered metric.
|
// Each calls the given function for each registered metric.
|
||||||
func (r *StandardRegistry) Each(f func(string, interface{})) {
|
func (r *StandardRegistry) Each(f func(string, interface{})) {
|
||||||
for name, i := range r.registered() {
|
for name, i := range r.registered() {
|
||||||
f(name, i)
|
f(name, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the metric by the given name or nil if none is registered.
|
// Get gets the metric by the given name or nil if none is registered.
|
||||||
func (r *StandardRegistry) Get(name string) interface{} {
|
func (r *StandardRegistry) Get(name string) interface{} {
|
||||||
r.mutex.Lock()
|
r.mutex.Lock()
|
||||||
defer r.mutex.Unlock()
|
defer r.mutex.Unlock()
|
||||||
return r.metrics[name]
|
return r.metrics[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets an existing metric or creates and registers a new one. Threadsafe
|
// GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe
|
||||||
// alternative to calling Get and Register on failure.
|
// alternative to calling Get and Register on failure.
|
||||||
// The interface can be the metric to register if not found in registry,
|
// The interface can be the metric to register if not found in registry,
|
||||||
// or a function returning the metric for lazy instantiation.
|
// or a function returning the metric for lazy instantiation.
|
||||||
|
|
@ -101,7 +100,7 @@ func (r *StandardRegistry) Register(name string, i interface{}) error {
|
||||||
return r.register(name, i)
|
return r.register(name, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run all registered healthchecks.
|
// RunHealthchecks runs all registered healthchecks.
|
||||||
func (r *StandardRegistry) RunHealthchecks() {
|
func (r *StandardRegistry) RunHealthchecks() {
|
||||||
r.mutex.Lock()
|
r.mutex.Lock()
|
||||||
defer r.mutex.Unlock()
|
defer r.mutex.Unlock()
|
||||||
|
|
@ -181,7 +180,7 @@ func (r *StandardRegistry) Unregister(name string) {
|
||||||
delete(r.metrics, name)
|
delete(r.metrics, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unregister all metrics. (Mostly for testing.)
|
// UnregisterAll unregisters all metrics. Mostly for testing.
|
||||||
func (r *StandardRegistry) UnregisterAll() {
|
func (r *StandardRegistry) UnregisterAll() {
|
||||||
r.mutex.Lock()
|
r.mutex.Lock()
|
||||||
defer r.mutex.Unlock()
|
defer r.mutex.Unlock()
|
||||||
|
|
@ -244,7 +243,7 @@ func NewPrefixedChildRegistry(parent Registry, prefix string) Registry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the given function for each registered metric.
|
// Each calls the given function for each registered metric.
|
||||||
func (r *PrefixedRegistry) Each(fn func(string, interface{})) {
|
func (r *PrefixedRegistry) Each(fn func(string, interface{})) {
|
||||||
wrappedFn := func(prefix string) func(string, interface{}) {
|
wrappedFn := func(prefix string) func(string, interface{}) {
|
||||||
return func(name string, iface interface{}) {
|
return func(name string, iface interface{}) {
|
||||||
|
|
@ -276,7 +275,7 @@ func (r *PrefixedRegistry) Get(name string) interface{} {
|
||||||
return r.underlying.Get(realName)
|
return r.underlying.Get(realName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets an existing metric or registers the given one.
|
// GetOrRegister gets an existing metric or registers the given one.
|
||||||
// The interface can be the metric to register if not found in registry,
|
// The interface can be the metric to register if not found in registry,
|
||||||
// or a function returning the metric for lazy instantiation.
|
// or a function returning the metric for lazy instantiation.
|
||||||
func (r *PrefixedRegistry) GetOrRegister(name string, metric interface{}) interface{} {
|
func (r *PrefixedRegistry) GetOrRegister(name string, metric interface{}) interface{} {
|
||||||
|
|
@ -290,7 +289,7 @@ func (r *PrefixedRegistry) Register(name string, metric interface{}) error {
|
||||||
return r.underlying.Register(realName, metric)
|
return r.underlying.Register(realName, metric)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run all registered healthchecks.
|
// RunHealthchecks runs all registered healthchecks.
|
||||||
func (r *PrefixedRegistry) RunHealthchecks() {
|
func (r *PrefixedRegistry) RunHealthchecks() {
|
||||||
r.underlying.RunHealthchecks()
|
r.underlying.RunHealthchecks()
|
||||||
}
|
}
|
||||||
|
|
@ -306,14 +305,14 @@ func (r *PrefixedRegistry) Unregister(name string) {
|
||||||
r.underlying.Unregister(realName)
|
r.underlying.Unregister(realName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unregister all metrics. (Mostly for testing.)
|
// UnregisterAll unregisters all metrics. Mostly for testing.
|
||||||
func (r *PrefixedRegistry) UnregisterAll() {
|
func (r *PrefixedRegistry) UnregisterAll() {
|
||||||
r.underlying.UnregisterAll()
|
r.underlying.UnregisterAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultRegistry Registry = NewRegistry()
|
var DefaultRegistry = NewRegistry()
|
||||||
|
|
||||||
// Call the given function for each registered metric.
|
// Each calls the given function for each registered metric.
|
||||||
func Each(f func(string, interface{})) {
|
func Each(f func(string, interface{})) {
|
||||||
DefaultRegistry.Each(f)
|
DefaultRegistry.Each(f)
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +322,7 @@ func Get(name string) interface{} {
|
||||||
return DefaultRegistry.Get(name)
|
return DefaultRegistry.Get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets an existing metric or creates and registers a new one. Threadsafe
|
// GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe
|
||||||
// alternative to calling Get and Register on failure.
|
// alternative to calling Get and Register on failure.
|
||||||
func GetOrRegister(name string, i interface{}) interface{} {
|
func GetOrRegister(name string, i interface{}) interface{} {
|
||||||
return DefaultRegistry.GetOrRegister(name, i)
|
return DefaultRegistry.GetOrRegister(name, i)
|
||||||
|
|
@ -335,7 +334,7 @@ func Register(name string, i interface{}) error {
|
||||||
return DefaultRegistry.Register(name, i)
|
return DefaultRegistry.Register(name, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the given metric under the given name. Panics if a metric by the
|
// MustRegister registers the given metric under the given name. Panics if a metric by the
|
||||||
// given name is already registered.
|
// given name is already registered.
|
||||||
func MustRegister(name string, i interface{}) {
|
func MustRegister(name string, i interface{}) {
|
||||||
if err := Register(name, i); err != nil {
|
if err := Register(name, i); err != nil {
|
||||||
|
|
@ -343,7 +342,7 @@ func MustRegister(name string, i interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run all registered healthchecks.
|
// RunHealthchecks runs all registered healthchecks.
|
||||||
func RunHealthchecks() {
|
func RunHealthchecks() {
|
||||||
DefaultRegistry.RunHealthchecks()
|
DefaultRegistry.RunHealthchecks()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Initial slice capacity for the values stored in a ResettingTimer
|
// InitialResettingTimerSliceCap is the initial slice capacity for the values
|
||||||
|
// stored in a ResettingTimer.
|
||||||
const InitialResettingTimerSliceCap = 10
|
const InitialResettingTimerSliceCap = 10
|
||||||
|
|
||||||
// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval.
|
// ResettingTimer is used for storing aggregated values for timers, which are reset on every flush interval.
|
||||||
|
|
@ -113,21 +114,21 @@ func (t *StandardResettingTimer) Mean() float64 {
|
||||||
panic("Mean called on a StandardResettingTimer")
|
panic("Mean called on a StandardResettingTimer")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of the execution of the given function.
|
// Time records the duration of the execution of the given function.
|
||||||
func (t *StandardResettingTimer) Time(f func()) {
|
func (t *StandardResettingTimer) Time(f func()) {
|
||||||
ts := time.Now()
|
ts := time.Now()
|
||||||
f()
|
f()
|
||||||
t.Update(time.Since(ts))
|
t.Update(time.Since(ts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of an event.
|
// Update records the duration of an event.
|
||||||
func (t *StandardResettingTimer) Update(d time.Duration) {
|
func (t *StandardResettingTimer) Update(d time.Duration) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
t.values = append(t.values, int64(d))
|
t.values = append(t.values, int64(d))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of an event that started at a time and ends now.
|
// UpdateSince records the duration of an event that started at a time and ends now.
|
||||||
func (t *StandardResettingTimer) UpdateSince(ts time.Time) {
|
func (t *StandardResettingTimer) UpdateSince(ts time.Time) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
|
|
@ -211,7 +212,7 @@ func (t *ResettingTimerSnapshot) calc(percentiles []float64) {
|
||||||
// math.Floor(x + 0.5)
|
// math.Floor(x + 0.5)
|
||||||
indexOfPerc := int(math.Floor(((abs / 100.0) * float64(count)) + 0.5))
|
indexOfPerc := int(math.Floor(((abs / 100.0) * float64(count)) + 0.5))
|
||||||
if pct >= 0 {
|
if pct >= 0 {
|
||||||
indexOfPerc -= 1 // index offset=0
|
indexOfPerc-- // index offset=0
|
||||||
}
|
}
|
||||||
thresholdBoundary = t.values[indexOfPerc]
|
thresholdBoundary = t.values[indexOfPerc]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,18 +52,18 @@ var (
|
||||||
threadCreateProfile = pprof.Lookup("threadcreate")
|
threadCreateProfile = pprof.Lookup("threadcreate")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Capture new values for the Go runtime statistics exported in
|
// CaptureRuntimeMemStats captures new values for the Go runtime statistics exported
|
||||||
// runtime.MemStats. This is designed to be called as a goroutine.
|
// in runtime.MemStats. This is designed to be called as a goroutine.
|
||||||
func CaptureRuntimeMemStats(r Registry, d time.Duration) {
|
func CaptureRuntimeMemStats(r Registry, d time.Duration) {
|
||||||
for range time.Tick(d) {
|
for range time.Tick(d) {
|
||||||
CaptureRuntimeMemStatsOnce(r)
|
CaptureRuntimeMemStatsOnce(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capture new values for the Go runtime statistics exported in
|
// CaptureRuntimeMemStatsOnce captures new values for the Go runtime statistics
|
||||||
// runtime.MemStats. This is designed to be called in a background
|
// exported in runtime.MemStats. This is designed to be called in a background
|
||||||
// goroutine. Giving a registry which has not been given to
|
// goroutine. Giving a registry which has not been given to RegisterRuntimeMemStats
|
||||||
// RegisterRuntimeMemStats will panic.
|
// will panic.
|
||||||
//
|
//
|
||||||
// Be very careful with this because runtime.ReadMemStats calls the C
|
// Be very careful with this because runtime.ReadMemStats calls the C
|
||||||
// functions runtime·semacquire(&runtime·worldsema) and runtime·stoptheworld()
|
// functions runtime·semacquire(&runtime·worldsema) and runtime·stoptheworld()
|
||||||
|
|
@ -142,7 +142,7 @@ func CaptureRuntimeMemStatsOnce(r Registry) {
|
||||||
runtimeMetrics.NumThread.Update(int64(threadCreateProfile.Count()))
|
runtimeMetrics.NumThread.Update(int64(threadCreateProfile.Count()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register runtimeMetrics for the Go runtime statistics exported in runtime and
|
// RegisterRuntimeMemStats registers runtimeMetrics for the Go runtime statistics exported in runtime and
|
||||||
// specifically runtime.MemStats. The runtimeMetrics are named by their
|
// specifically runtime.MemStats. The runtimeMetrics are named by their
|
||||||
// fully-qualified Go symbols, i.e. runtime.MemStats.Alloc.
|
// fully-qualified Go symbols, i.e. runtime.MemStats.Alloc.
|
||||||
func RegisterRuntimeMemStats(r Registry) {
|
func RegisterRuntimeMemStats(r Registry) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
const rescaleThreshold = time.Hour
|
const rescaleThreshold = time.Hour
|
||||||
|
|
||||||
// Samples maintain a statistically-significant selection of values from
|
// Sample maintains a statistically-significant selection of values from
|
||||||
// a stream.
|
// a stream.
|
||||||
type Sample interface {
|
type Sample interface {
|
||||||
Clear()
|
Clear()
|
||||||
|
|
@ -214,7 +214,7 @@ func (NilSample) Percentiles(ps []float64) []float64 {
|
||||||
// Size is a no-op.
|
// Size is a no-op.
|
||||||
func (NilSample) Size() int { return 0 }
|
func (NilSample) Size() int { return 0 }
|
||||||
|
|
||||||
// Sample is a no-op.
|
// Snapshot is a no-op.
|
||||||
func (NilSample) Snapshot() Sample { return NilSample{} }
|
func (NilSample) Snapshot() Sample { return NilSample{} }
|
||||||
|
|
||||||
// StdDev is a no-op.
|
// StdDev is a no-op.
|
||||||
|
|
@ -268,7 +268,7 @@ func SampleMin(values []int64) int64 {
|
||||||
return min
|
return min
|
||||||
}
|
}
|
||||||
|
|
||||||
// SamplePercentiles returns an arbitrary percentile of the slice of int64.
|
// SamplePercentile returns an arbitrary percentile of the slice of int64.
|
||||||
func SamplePercentile(values int64Slice, p float64) float64 {
|
func SamplePercentile(values int64Slice, p float64) float64 {
|
||||||
return SamplePercentiles(values, []float64{p})[0]
|
return SamplePercentiles(values, []float64{p})[0]
|
||||||
}
|
}
|
||||||
|
|
@ -302,6 +302,7 @@ type SampleSnapshot struct {
|
||||||
values []int64
|
values []int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewSampleSnapshot creates a new sample snapshot.
|
||||||
func NewSampleSnapshot(count int64, values []int64) *SampleSnapshot {
|
func NewSampleSnapshot(count int64, values []int64) *SampleSnapshot {
|
||||||
return &SampleSnapshot{
|
return &SampleSnapshot{
|
||||||
count: count,
|
count: count,
|
||||||
|
|
@ -394,7 +395,7 @@ func SampleVariance(values []int64) float64 {
|
||||||
return sum / float64(len(values))
|
return sum / float64(len(values))
|
||||||
}
|
}
|
||||||
|
|
||||||
// A uniform sample using Vitter's Algorithm R.
|
// UniformSample represents a uniform sample using Vitter's Algorithm R.
|
||||||
//
|
//
|
||||||
// <http://www.cs.umd.edu/~samir/498/vitter.pdf>
|
// <http://www.cs.umd.edu/~samir/498/vitter.pdf>
|
||||||
type UniformSample struct {
|
type UniformSample struct {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Output each metric in the given registry to syslog periodically using
|
// Syslog outputs each metric in the given registry to syslog periodically using
|
||||||
// the given syslogger.
|
// the given syslogger.
|
||||||
func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
|
func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
|
||||||
for range time.Tick(d) {
|
for range time.Tick(d) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Timers capture the duration and rate of events.
|
// Timer captures the duration and rate of events.
|
||||||
type Timer interface {
|
type Timer interface {
|
||||||
Count() int64
|
Count() int64
|
||||||
Max() int64
|
Max() int64
|
||||||
|
|
@ -221,14 +221,14 @@ func (t *StandardTimer) Sum() int64 {
|
||||||
return t.histogram.Sum()
|
return t.histogram.Sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of the execution of the given function.
|
// Time records the duration of the execution of the given function.
|
||||||
func (t *StandardTimer) Time(f func()) {
|
func (t *StandardTimer) Time(f func()) {
|
||||||
ts := time.Now()
|
ts := time.Now()
|
||||||
f()
|
f()
|
||||||
t.Update(time.Since(ts))
|
t.Update(time.Since(ts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of an event.
|
// Update records the duration of an event.
|
||||||
func (t *StandardTimer) Update(d time.Duration) {
|
func (t *StandardTimer) Update(d time.Duration) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
|
|
@ -236,7 +236,7 @@ func (t *StandardTimer) Update(d time.Duration) {
|
||||||
t.meter.Mark(1)
|
t.meter.Mark(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the duration of an event that started at a time and ends now.
|
// UpdateSince records the duration of an event that started at a time and ends now.
|
||||||
func (t *StandardTimer) UpdateSince(ts time.Time) {
|
func (t *StandardTimer) UpdateSince(ts time.Time) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue