Updating server dependancies. (#7246)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
2c895ee66e
Коммит
96eab12027
27
vendor/github.com/armon/go-metrics/circonus/circonus.go
сгенерированный
поставляемый
27
vendor/github.com/armon/go-metrics/circonus/circonus.go
сгенерированный
поставляемый
@@ -5,6 +5,7 @@ package circonus
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
cgm "github.com/circonus-labs/circonus-gometrics"
|
||||
)
|
||||
|
||||
@@ -61,6 +62,12 @@ func (s *CirconusSink) SetGauge(key []string, val float32) {
|
||||
s.metrics.SetGauge(flatKey, int64(val))
|
||||
}
|
||||
|
||||
// SetGaugeWithLabels sets value for a gauge metric with the given labels
|
||||
func (s *CirconusSink) SetGaugeWithLabels(key []string, val float32, labels []metrics.Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.metrics.SetGauge(flatKey, int64(val))
|
||||
}
|
||||
|
||||
// EmitKey is not implemented in circonus
|
||||
func (s *CirconusSink) EmitKey(key []string, val float32) {
|
||||
// NOP
|
||||
@@ -72,12 +79,24 @@ func (s *CirconusSink) IncrCounter(key []string, val float32) {
|
||||
s.metrics.IncrementByValue(flatKey, uint64(val))
|
||||
}
|
||||
|
||||
// IncrCounterWithLabels increments a counter metric with the given labels
|
||||
func (s *CirconusSink) IncrCounterWithLabels(key []string, val float32, labels []metrics.Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.metrics.IncrementByValue(flatKey, uint64(val))
|
||||
}
|
||||
|
||||
// AddSample adds a sample to a histogram metric
|
||||
func (s *CirconusSink) AddSample(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.metrics.RecordValue(flatKey, float64(val))
|
||||
}
|
||||
|
||||
// AddSampleWithLabels adds a sample to a histogram metric with the given labels
|
||||
func (s *CirconusSink) AddSampleWithLabels(key []string, val float32, labels []metrics.Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.metrics.RecordValue(flatKey, float64(val))
|
||||
}
|
||||
|
||||
// Flattens key to Circonus metric name
|
||||
func (s *CirconusSink) flattenKey(parts []string) string {
|
||||
joined := strings.Join(parts, "`")
|
||||
@@ -90,3 +109,11 @@ func (s *CirconusSink) flattenKey(parts []string) string {
|
||||
}
|
||||
}, joined)
|
||||
}
|
||||
|
||||
// Flattens the key along with labels for formatting, removes spaces
|
||||
func (s *CirconusSink) flattenKeyLabels(parts []string, labels []metrics.Label) string {
|
||||
for _, label := range labels {
|
||||
parts = append(parts, label.Value)
|
||||
}
|
||||
return s.flattenKey(parts)
|
||||
}
|
||||
|
||||
4
vendor/github.com/armon/go-metrics/circonus/circonus_test.go
сгенерированный
поставляемый
4
vendor/github.com/armon/go-metrics/circonus/circonus_test.go
сгенерированный
поставляемый
@@ -12,7 +12,7 @@ import (
|
||||
func TestNewCirconusSink(t *testing.T) {
|
||||
|
||||
// test with invalid config (nil)
|
||||
expectedError := errors.New("Invalid check manager configuration (no API token AND no submission url).")
|
||||
expectedError := errors.New("invalid check manager configuration (no API token AND no submission url)")
|
||||
_, err := NewCirconusSink(nil)
|
||||
if err == nil || err.Error() != expectedError.Error() {
|
||||
t.Errorf("Expected an '%#v' error, got '%#v'", expectedError, err)
|
||||
@@ -87,7 +87,7 @@ func TestSetGauge(t *testing.T) {
|
||||
cs.Flush()
|
||||
}()
|
||||
|
||||
expect := "{\"foo`bar\":{\"_type\":\"n\",\"_value\":1}}"
|
||||
expect := "{\"foo`bar\":{\"_type\":\"n\",\"_value\":\"1\"}}"
|
||||
actual := <-q
|
||||
|
||||
if actual != expect {
|
||||
|
||||
73
vendor/github.com/armon/go-metrics/datadog/dogstatsd.go
сгенерированный
поставляемый
73
vendor/github.com/armon/go-metrics/datadog/dogstatsd.go
сгенерированный
поставляемый
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/DataDog/datadog-go/statsd"
|
||||
"github.com/armon/go-metrics"
|
||||
)
|
||||
|
||||
// DogStatsdSink provides a MetricSink that can be used
|
||||
@@ -45,46 +46,49 @@ func (s *DogStatsdSink) EnableHostNamePropagation() {
|
||||
|
||||
func (s *DogStatsdSink) flattenKey(parts []string) string {
|
||||
joined := strings.Join(parts, ".")
|
||||
return strings.Map(func(r rune) rune {
|
||||
switch r {
|
||||
case ':':
|
||||
fallthrough
|
||||
case ' ':
|
||||
return '_'
|
||||
default:
|
||||
return r
|
||||
}
|
||||
}, joined)
|
||||
return strings.Map(sanitize, joined)
|
||||
}
|
||||
|
||||
func (s *DogStatsdSink) parseKey(key []string) ([]string, []string) {
|
||||
func sanitize(r rune) rune {
|
||||
switch r {
|
||||
case ':':
|
||||
fallthrough
|
||||
case ' ':
|
||||
return '_'
|
||||
default:
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DogStatsdSink) parseKey(key []string) ([]string, []metrics.Label) {
|
||||
// Since DogStatsd supports dimensionality via tags on metric keys, this sink's approach is to splice the hostname out of the key in favor of a `host` tag
|
||||
// The `host` tag is either forced here, or set downstream by the DogStatsd server
|
||||
|
||||
var tags []string
|
||||
var labels []metrics.Label
|
||||
hostName := s.hostName
|
||||
|
||||
//Splice the hostname out of the key
|
||||
// Splice the hostname out of the key
|
||||
for i, el := range key {
|
||||
if el == hostName {
|
||||
key = append(key[:i], key[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if s.propagateHostname {
|
||||
tags = append(tags, fmt.Sprintf("host:%s", hostName))
|
||||
labels = append(labels, metrics.Label{"host", hostName})
|
||||
}
|
||||
return key, tags
|
||||
return key, labels
|
||||
}
|
||||
|
||||
// Implementation of methods in the MetricSink interface
|
||||
|
||||
func (s *DogStatsdSink) SetGauge(key []string, val float32) {
|
||||
s.SetGaugeWithTags(key, val, []string{})
|
||||
s.SetGaugeWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (s *DogStatsdSink) IncrCounter(key []string, val float32) {
|
||||
s.IncrCounterWithTags(key, val, []string{})
|
||||
s.IncrCounterWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
// EmitKey is not implemented since DogStatsd does not provide a metric type that holds an
|
||||
@@ -93,33 +97,44 @@ func (s *DogStatsdSink) EmitKey(key []string, val float32) {
|
||||
}
|
||||
|
||||
func (s *DogStatsdSink) AddSample(key []string, val float32) {
|
||||
s.AddSampleWithTags(key, val, []string{})
|
||||
s.AddSampleWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
// The following ...WithTags methods correspond to Datadog's Tag extension to Statsd.
|
||||
// The following ...WithLabels methods correspond to Datadog's Tag extension to Statsd.
|
||||
// http://docs.datadoghq.com/guides/dogstatsd/#tags
|
||||
|
||||
func (s *DogStatsdSink) SetGaugeWithTags(key []string, val float32, tags []string) {
|
||||
flatKey, tags := s.getFlatkeyAndCombinedTags(key, tags)
|
||||
func (s *DogStatsdSink) SetGaugeWithLabels(key []string, val float32, labels []metrics.Label) {
|
||||
flatKey, tags := s.getFlatkeyAndCombinedLabels(key, labels)
|
||||
rate := 1.0
|
||||
s.client.Gauge(flatKey, float64(val), tags, rate)
|
||||
}
|
||||
|
||||
func (s *DogStatsdSink) IncrCounterWithTags(key []string, val float32, tags []string) {
|
||||
flatKey, tags := s.getFlatkeyAndCombinedTags(key, tags)
|
||||
func (s *DogStatsdSink) IncrCounterWithLabels(key []string, val float32, labels []metrics.Label) {
|
||||
flatKey, tags := s.getFlatkeyAndCombinedLabels(key, labels)
|
||||
rate := 1.0
|
||||
s.client.Count(flatKey, int64(val), tags, rate)
|
||||
}
|
||||
|
||||
func (s *DogStatsdSink) AddSampleWithTags(key []string, val float32, tags []string) {
|
||||
flatKey, tags := s.getFlatkeyAndCombinedTags(key, tags)
|
||||
func (s *DogStatsdSink) AddSampleWithLabels(key []string, val float32, labels []metrics.Label) {
|
||||
flatKey, tags := s.getFlatkeyAndCombinedLabels(key, labels)
|
||||
rate := 1.0
|
||||
s.client.TimeInMilliseconds(flatKey, float64(val), tags, rate)
|
||||
}
|
||||
|
||||
func (s *DogStatsdSink) getFlatkeyAndCombinedTags(key []string, tags []string) (flattenedKey string, combinedTags []string) {
|
||||
key, hostTags := s.parseKey(key)
|
||||
func (s *DogStatsdSink) getFlatkeyAndCombinedLabels(key []string, labels []metrics.Label) (string, []string) {
|
||||
key, parsedLabels := s.parseKey(key)
|
||||
flatKey := s.flattenKey(key)
|
||||
tags = append(tags, hostTags...)
|
||||
labels = append(labels, parsedLabels...)
|
||||
|
||||
var tags []string
|
||||
for _, label := range labels {
|
||||
label.Name = strings.Map(sanitize, label.Name)
|
||||
label.Value = strings.Map(sanitize, label.Value)
|
||||
if label.Value != "" {
|
||||
tags = append(tags, fmt.Sprintf("%s:%s", label.Name, label.Value))
|
||||
} else {
|
||||
tags = append(tags, label.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return flatKey, tags
|
||||
}
|
||||
|
||||
35
vendor/github.com/armon/go-metrics/datadog/dogstatsd_test.go
сгенерированный
поставляемый
35
vendor/github.com/armon/go-metrics/datadog/dogstatsd_test.go
сгенерированный
поставляемый
@@ -1,13 +1,14 @@
|
||||
package datadog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
)
|
||||
|
||||
var EmptyTags []string
|
||||
var EmptyTags []metrics.Label
|
||||
|
||||
const (
|
||||
DogStatsdAddr = "127.0.0.1:7254"
|
||||
@@ -22,14 +23,14 @@ func MockGetHostname() string {
|
||||
|
||||
var ParseKeyTests = []struct {
|
||||
KeyToParse []string
|
||||
Tags []string
|
||||
Tags []metrics.Label
|
||||
PropagateHostname bool
|
||||
ExpectedKey []string
|
||||
ExpectedTags []string
|
||||
ExpectedTags []metrics.Label
|
||||
}{
|
||||
{[]string{"a", MockGetHostname(), "b", "c"}, EmptyTags, HostnameDisabled, []string{"a", "b", "c"}, EmptyTags},
|
||||
{[]string{"a", "b", "c"}, EmptyTags, HostnameDisabled, []string{"a", "b", "c"}, EmptyTags},
|
||||
{[]string{"a", "b", "c"}, EmptyTags, HostnameEnabled, []string{"a", "b", "c"}, []string{fmt.Sprintf("host:%s", MockGetHostname())}},
|
||||
{[]string{"a", "b", "c"}, EmptyTags, HostnameEnabled, []string{"a", "b", "c"}, []metrics.Label{{"host", MockGetHostname()}}},
|
||||
}
|
||||
|
||||
var FlattenKeyTests = []struct {
|
||||
@@ -44,7 +45,7 @@ var MetricSinkTests = []struct {
|
||||
Method string
|
||||
Metric []string
|
||||
Value interface{}
|
||||
Tags []string
|
||||
Tags []metrics.Label
|
||||
PropagateHostname bool
|
||||
Expected string
|
||||
}{
|
||||
@@ -53,13 +54,15 @@ var MetricSinkTests = []struct {
|
||||
{"AddSample", []string{"sample", "thing"}, float32(4), EmptyTags, HostnameDisabled, "sample.thing:4.000000|ms"},
|
||||
{"IncrCounter", []string{"count", "me"}, float32(3), EmptyTags, HostnameDisabled, "count.me:3|c"},
|
||||
|
||||
{"SetGauge", []string{"foo", "baz"}, float32(42), []string{"my_tag:my_value"}, HostnameDisabled, "foo.baz:42.000000|g|#my_tag:my_value"},
|
||||
{"SetGauge", []string{"foo", "bar"}, float32(42), []string{"my_tag:my_value", "other_tag:other_value"}, HostnameDisabled, "foo.bar:42.000000|g|#my_tag:my_value,other_tag:other_value"},
|
||||
{"SetGauge", []string{"foo", "bar"}, float32(42), []string{"my_tag:my_value", "other_tag:other_value"}, HostnameEnabled, "foo.bar:42.000000|g|#my_tag:my_value,other_tag:other_value,host:test_hostname"},
|
||||
{"SetGauge", []string{"foo", "baz"}, float32(42), []metrics.Label{{"my_tag", ""}}, HostnameDisabled, "foo.baz:42.000000|g|#my_tag"},
|
||||
{"SetGauge", []string{"foo", "baz"}, float32(42), []metrics.Label{{"my tag", "my_value"}}, HostnameDisabled, "foo.baz:42.000000|g|#my_tag:my_value"},
|
||||
{"SetGauge", []string{"foo", "bar"}, float32(42), []metrics.Label{{"my_tag", "my_value"}, {"other_tag", "other_value"}}, HostnameDisabled, "foo.bar:42.000000|g|#my_tag:my_value,other_tag:other_value"},
|
||||
{"SetGauge", []string{"foo", "bar"}, float32(42), []metrics.Label{{"my_tag", "my_value"}, {"other_tag", "other_value"}}, HostnameEnabled, "foo.bar:42.000000|g|#my_tag:my_value,other_tag:other_value,host:test_hostname"},
|
||||
}
|
||||
|
||||
func mockNewDogStatsdSink(addr string, tags []string, tagWithHostname bool) *DogStatsdSink {
|
||||
func mockNewDogStatsdSink(addr string, labels []metrics.Label, tagWithHostname bool) *DogStatsdSink {
|
||||
dog, _ := NewDogStatsdSink(addr, MockGetHostname())
|
||||
_, tags := dog.getFlatkeyAndCombinedLabels(nil, labels)
|
||||
dog.SetTags(tags)
|
||||
if tagWithHostname {
|
||||
dog.EnableHostNamePropagation()
|
||||
@@ -90,7 +93,7 @@ func TestParseKey(t *testing.T) {
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(tags, tt.ExpectedTags) {
|
||||
t.Fatalf("Tag Parsing Failed for %v", tt.KeyToParse)
|
||||
t.Fatalf("Tag Parsing Failed for %v, %v != %v", tt.KeyToParse, tags, tt.ExpectedTags)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,17 +127,17 @@ func TestTaggableMetrics(t *testing.T) {
|
||||
|
||||
dog := mockNewDogStatsdSink(DogStatsdAddr, EmptyTags, HostnameDisabled)
|
||||
|
||||
dog.AddSampleWithTags([]string{"sample", "thing"}, float32(4), []string{"tagkey:tagvalue"})
|
||||
dog.AddSampleWithLabels([]string{"sample", "thing"}, float32(4), []metrics.Label{{"tagkey", "tagvalue"}})
|
||||
assertServerMatchesExpected(t, server, buf, "sample.thing:4.000000|ms|#tagkey:tagvalue")
|
||||
|
||||
dog.SetGaugeWithTags([]string{"sample", "thing"}, float32(4), []string{"tagkey:tagvalue"})
|
||||
dog.SetGaugeWithLabels([]string{"sample", "thing"}, float32(4), []metrics.Label{{"tagkey", "tagvalue"}})
|
||||
assertServerMatchesExpected(t, server, buf, "sample.thing:4.000000|g|#tagkey:tagvalue")
|
||||
|
||||
dog.IncrCounterWithTags([]string{"sample", "thing"}, float32(4), []string{"tagkey:tagvalue"})
|
||||
dog.IncrCounterWithLabels([]string{"sample", "thing"}, float32(4), []metrics.Label{{"tagkey", "tagvalue"}})
|
||||
assertServerMatchesExpected(t, server, buf, "sample.thing:4|c|#tagkey:tagvalue")
|
||||
|
||||
dog = mockNewDogStatsdSink(DogStatsdAddr, []string{"global"}, HostnameEnabled) // with hostname, global tags
|
||||
dog.IncrCounterWithTags([]string{"sample", "thing"}, float32(4), []string{"tagkey:tagvalue"})
|
||||
dog = mockNewDogStatsdSink(DogStatsdAddr, []metrics.Label{{Name: "global"}}, HostnameEnabled) // with hostname, global tags
|
||||
dog.IncrCounterWithLabels([]string{"sample", "thing"}, float32(4), []metrics.Label{{"tagkey", "tagvalue"}})
|
||||
assertServerMatchesExpected(t, server, buf, "sample.thing:4|c|#global,tagkey:tagvalue,host:test_hostname")
|
||||
}
|
||||
|
||||
|
||||
95
vendor/github.com/armon/go-metrics/inmem.go
сгенерированный
поставляемый
95
vendor/github.com/armon/go-metrics/inmem.go
сгенерированный
поставляемый
@@ -1,6 +1,7 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
@@ -39,7 +40,7 @@ type IntervalMetrics struct {
|
||||
Interval time.Time
|
||||
|
||||
// Gauges maps the key to the last set value
|
||||
Gauges map[string]float32
|
||||
Gauges map[string]GaugeValue
|
||||
|
||||
// Points maps the string to the list of emitted values
|
||||
// from EmitKey
|
||||
@@ -47,21 +48,21 @@ type IntervalMetrics struct {
|
||||
|
||||
// Counters maps the string key to a sum of the counter
|
||||
// values
|
||||
Counters map[string]*AggregateSample
|
||||
Counters map[string]SampledValue
|
||||
|
||||
// Samples maps the key to an AggregateSample,
|
||||
// which has the rolled up view of a sample
|
||||
Samples map[string]*AggregateSample
|
||||
Samples map[string]SampledValue
|
||||
}
|
||||
|
||||
// NewIntervalMetrics creates a new IntervalMetrics for a given interval
|
||||
func NewIntervalMetrics(intv time.Time) *IntervalMetrics {
|
||||
return &IntervalMetrics{
|
||||
Interval: intv,
|
||||
Gauges: make(map[string]float32),
|
||||
Gauges: make(map[string]GaugeValue),
|
||||
Points: make(map[string][]float32),
|
||||
Counters: make(map[string]*AggregateSample),
|
||||
Samples: make(map[string]*AggregateSample),
|
||||
Counters: make(map[string]SampledValue),
|
||||
Samples: make(map[string]SampledValue),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,12 +70,12 @@ func NewIntervalMetrics(intv time.Time) *IntervalMetrics {
|
||||
// about a sample
|
||||
type AggregateSample struct {
|
||||
Count int // The count of emitted pairs
|
||||
Rate float64 // The count of emitted pairs per time unit (usually 1 second)
|
||||
Rate float64 `json:"-"` // The count of emitted pairs per time unit (usually 1 second)
|
||||
Sum float64 // The sum of values
|
||||
SumSq float64 // The sum of squared values
|
||||
SumSq float64 `json:"-"` // The sum of squared values
|
||||
Min float64 // Minimum value
|
||||
Max float64 // Maximum value
|
||||
LastUpdated time.Time // When value was last updated
|
||||
LastUpdated time.Time `json:"-"` // When value was last updated
|
||||
}
|
||||
|
||||
// Computes a Stddev of the values
|
||||
@@ -154,12 +155,16 @@ func NewInmemSink(interval, retain time.Duration) *InmemSink {
|
||||
}
|
||||
|
||||
func (i *InmemSink) SetGauge(key []string, val float32) {
|
||||
k := i.flattenKey(key)
|
||||
i.SetGaugeWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (i *InmemSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
k, name := i.flattenKeyLabels(key, labels)
|
||||
intv := i.getInterval()
|
||||
|
||||
intv.Lock()
|
||||
defer intv.Unlock()
|
||||
intv.Gauges[k] = val
|
||||
intv.Gauges[k] = GaugeValue{Name: name, Value: val, Labels: labels}
|
||||
}
|
||||
|
||||
func (i *InmemSink) EmitKey(key []string, val float32) {
|
||||
@@ -173,30 +178,46 @@ func (i *InmemSink) EmitKey(key []string, val float32) {
|
||||
}
|
||||
|
||||
func (i *InmemSink) IncrCounter(key []string, val float32) {
|
||||
k := i.flattenKey(key)
|
||||
i.IncrCounterWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (i *InmemSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
k, name := i.flattenKeyLabels(key, labels)
|
||||
intv := i.getInterval()
|
||||
|
||||
intv.Lock()
|
||||
defer intv.Unlock()
|
||||
|
||||
agg := intv.Counters[k]
|
||||
if agg == nil {
|
||||
agg = &AggregateSample{}
|
||||
agg, ok := intv.Counters[k]
|
||||
if !ok {
|
||||
agg = SampledValue{
|
||||
Name: name,
|
||||
AggregateSample: &AggregateSample{},
|
||||
Labels: labels,
|
||||
}
|
||||
intv.Counters[k] = agg
|
||||
}
|
||||
agg.Ingest(float64(val), i.rateDenom)
|
||||
}
|
||||
|
||||
func (i *InmemSink) AddSample(key []string, val float32) {
|
||||
k := i.flattenKey(key)
|
||||
i.AddSampleWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (i *InmemSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
k, name := i.flattenKeyLabels(key, labels)
|
||||
intv := i.getInterval()
|
||||
|
||||
intv.Lock()
|
||||
defer intv.Unlock()
|
||||
|
||||
agg := intv.Samples[k]
|
||||
if agg == nil {
|
||||
agg = &AggregateSample{}
|
||||
agg, ok := intv.Samples[k]
|
||||
if !ok {
|
||||
agg = SampledValue{
|
||||
Name: name,
|
||||
AggregateSample: &AggregateSample{},
|
||||
Labels: labels,
|
||||
}
|
||||
intv.Samples[k] = agg
|
||||
}
|
||||
agg.Ingest(float64(val), i.rateDenom)
|
||||
@@ -261,6 +282,38 @@ func (i *InmemSink) getInterval() *IntervalMetrics {
|
||||
|
||||
// Flattens the key for formatting, removes spaces
|
||||
func (i *InmemSink) flattenKey(parts []string) string {
|
||||
joined := strings.Join(parts, ".")
|
||||
return strings.Replace(joined, " ", "_", -1)
|
||||
buf := &bytes.Buffer{}
|
||||
replacer := strings.NewReplacer(" ", "_")
|
||||
|
||||
if len(parts) > 0 {
|
||||
replacer.WriteString(buf, parts[0])
|
||||
}
|
||||
for _, part := range parts[1:] {
|
||||
replacer.WriteString(buf, ".")
|
||||
replacer.WriteString(buf, part)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Flattens the key for formatting along with its labels, removes spaces
|
||||
func (i *InmemSink) flattenKeyLabels(parts []string, labels []Label) (string, string) {
|
||||
buf := &bytes.Buffer{}
|
||||
replacer := strings.NewReplacer(" ", "_")
|
||||
|
||||
if len(parts) > 0 {
|
||||
replacer.WriteString(buf, parts[0])
|
||||
}
|
||||
for _, part := range parts[1:] {
|
||||
replacer.WriteString(buf, ".")
|
||||
replacer.WriteString(buf, part)
|
||||
}
|
||||
|
||||
key := buf.String()
|
||||
|
||||
for _, label := range labels {
|
||||
replacer.WriteString(buf, fmt.Sprintf(";%s=%s", label.Name, label.Value))
|
||||
}
|
||||
|
||||
return buf.String(), key
|
||||
}
|
||||
|
||||
118
vendor/github.com/armon/go-metrics/inmem_endpoint.go
сгенерированный
поставляемый
Обычный файл
118
vendor/github.com/armon/go-metrics/inmem_endpoint.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,118 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MetricsSummary holds a roll-up of metrics info for a given interval
|
||||
type MetricsSummary struct {
|
||||
Timestamp string
|
||||
Gauges []GaugeValue
|
||||
Points []PointValue
|
||||
Counters []SampledValue
|
||||
Samples []SampledValue
|
||||
}
|
||||
|
||||
type GaugeValue struct {
|
||||
Name string
|
||||
Hash string `json:"-"`
|
||||
Value float32
|
||||
|
||||
Labels []Label `json:"-"`
|
||||
DisplayLabels map[string]string `json:"Labels"`
|
||||
}
|
||||
|
||||
type PointValue struct {
|
||||
Name string
|
||||
Points []float32
|
||||
}
|
||||
|
||||
type SampledValue struct {
|
||||
Name string
|
||||
Hash string `json:"-"`
|
||||
*AggregateSample
|
||||
Mean float64
|
||||
Stddev float64
|
||||
|
||||
Labels []Label `json:"-"`
|
||||
DisplayLabels map[string]string `json:"Labels"`
|
||||
}
|
||||
|
||||
// DisplayMetrics returns a summary of the metrics from the most recent finished interval.
|
||||
func (i *InmemSink) DisplayMetrics(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
data := i.Data()
|
||||
|
||||
var interval *IntervalMetrics
|
||||
n := len(data)
|
||||
switch {
|
||||
case n == 0:
|
||||
return nil, fmt.Errorf("no metric intervals have been initialized yet")
|
||||
case n == 1:
|
||||
// Show the current interval if it's all we have
|
||||
interval = i.intervals[0]
|
||||
default:
|
||||
// Show the most recent finished interval if we have one
|
||||
interval = i.intervals[n-2]
|
||||
}
|
||||
|
||||
summary := MetricsSummary{
|
||||
Timestamp: interval.Interval.Round(time.Second).UTC().String(),
|
||||
Gauges: make([]GaugeValue, 0, len(interval.Gauges)),
|
||||
Points: make([]PointValue, 0, len(interval.Points)),
|
||||
}
|
||||
|
||||
// Format and sort the output of each metric type, so it gets displayed in a
|
||||
// deterministic order.
|
||||
for name, points := range interval.Points {
|
||||
summary.Points = append(summary.Points, PointValue{name, points})
|
||||
}
|
||||
sort.Slice(summary.Points, func(i, j int) bool {
|
||||
return summary.Points[i].Name < summary.Points[j].Name
|
||||
})
|
||||
|
||||
for hash, value := range interval.Gauges {
|
||||
value.Hash = hash
|
||||
value.DisplayLabels = make(map[string]string)
|
||||
for _, label := range value.Labels {
|
||||
value.DisplayLabels[label.Name] = label.Value
|
||||
}
|
||||
value.Labels = nil
|
||||
|
||||
summary.Gauges = append(summary.Gauges, value)
|
||||
}
|
||||
sort.Slice(summary.Gauges, func(i, j int) bool {
|
||||
return summary.Gauges[i].Hash < summary.Gauges[j].Hash
|
||||
})
|
||||
|
||||
summary.Counters = formatSamples(interval.Counters)
|
||||
summary.Samples = formatSamples(interval.Samples)
|
||||
|
||||
return summary, nil
|
||||
}
|
||||
|
||||
func formatSamples(source map[string]SampledValue) []SampledValue {
|
||||
output := make([]SampledValue, 0, len(source))
|
||||
for hash, sample := range source {
|
||||
displayLabels := make(map[string]string)
|
||||
for _, label := range sample.Labels {
|
||||
displayLabels[label.Name] = label.Value
|
||||
}
|
||||
|
||||
output = append(output, SampledValue{
|
||||
Name: sample.Name,
|
||||
Hash: hash,
|
||||
AggregateSample: sample.AggregateSample,
|
||||
Mean: sample.AggregateSample.Mean(),
|
||||
Stddev: sample.AggregateSample.Stddev(),
|
||||
DisplayLabels: displayLabels,
|
||||
})
|
||||
}
|
||||
sort.Slice(output, func(i, j int) bool {
|
||||
return output[i].Hash < output[j].Hash
|
||||
})
|
||||
|
||||
return output
|
||||
}
|
||||
133
vendor/github.com/armon/go-metrics/inmem_endpoint_test.go
сгенерированный
поставляемый
Обычный файл
133
vendor/github.com/armon/go-metrics/inmem_endpoint_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,133 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pascaldekloe/goe/verify"
|
||||
)
|
||||
|
||||
func TestDisplayMetrics(t *testing.T) {
|
||||
interval := 10 * time.Millisecond
|
||||
inm := NewInmemSink(interval, 50*time.Millisecond)
|
||||
|
||||
// Add data points
|
||||
inm.SetGauge([]string{"foo", "bar"}, 42)
|
||||
inm.SetGaugeWithLabels([]string{"foo", "bar"}, 23, []Label{{"a", "b"}})
|
||||
inm.EmitKey([]string{"foo", "bar"}, 42)
|
||||
inm.IncrCounter([]string{"foo", "bar"}, 20)
|
||||
inm.IncrCounter([]string{"foo", "bar"}, 22)
|
||||
inm.IncrCounterWithLabels([]string{"foo", "bar"}, 20, []Label{{"a", "b"}})
|
||||
inm.IncrCounterWithLabels([]string{"foo", "bar"}, 40, []Label{{"a", "b"}})
|
||||
inm.AddSample([]string{"foo", "bar"}, 20)
|
||||
inm.AddSample([]string{"foo", "bar"}, 24)
|
||||
inm.AddSampleWithLabels([]string{"foo", "bar"}, 23, []Label{{"a", "b"}})
|
||||
inm.AddSampleWithLabels([]string{"foo", "bar"}, 33, []Label{{"a", "b"}})
|
||||
|
||||
data := inm.Data()
|
||||
if len(data) != 1 {
|
||||
t.Fatalf("bad: %v", data)
|
||||
}
|
||||
|
||||
expected := MetricsSummary{
|
||||
Timestamp: data[0].Interval.Round(time.Second).UTC().String(),
|
||||
Gauges: []GaugeValue{
|
||||
{
|
||||
Name: "foo.bar",
|
||||
Hash: "foo.bar",
|
||||
Value: float32(42),
|
||||
DisplayLabels: map[string]string{},
|
||||
},
|
||||
{
|
||||
Name: "foo.bar",
|
||||
Hash: "foo.bar;a=b",
|
||||
Value: float32(23),
|
||||
DisplayLabels: map[string]string{"a": "b"},
|
||||
},
|
||||
},
|
||||
Points: []PointValue{
|
||||
{
|
||||
Name: "foo.bar",
|
||||
Points: []float32{42},
|
||||
},
|
||||
},
|
||||
Counters: []SampledValue{
|
||||
{
|
||||
Name: "foo.bar",
|
||||
Hash: "foo.bar",
|
||||
AggregateSample: &AggregateSample{
|
||||
Count: 2,
|
||||
Min: 20,
|
||||
Max: 22,
|
||||
Sum: 42,
|
||||
SumSq: 884,
|
||||
Rate: 200,
|
||||
},
|
||||
Mean: 21,
|
||||
Stddev: 1.4142135623730951,
|
||||
},
|
||||
{
|
||||
Name: "foo.bar",
|
||||
Hash: "foo.bar;a=b",
|
||||
AggregateSample: &AggregateSample{
|
||||
Count: 2,
|
||||
Min: 20,
|
||||
Max: 40,
|
||||
Sum: 60,
|
||||
SumSq: 2000,
|
||||
Rate: 200,
|
||||
},
|
||||
Mean: 30,
|
||||
Stddev: 14.142135623730951,
|
||||
DisplayLabels: map[string]string{"a": "b"},
|
||||
},
|
||||
},
|
||||
Samples: []SampledValue{
|
||||
{
|
||||
Name: "foo.bar",
|
||||
Hash: "foo.bar",
|
||||
AggregateSample: &AggregateSample{
|
||||
Count: 2,
|
||||
Min: 20,
|
||||
Max: 24,
|
||||
Sum: 44,
|
||||
SumSq: 976,
|
||||
Rate: 200,
|
||||
},
|
||||
Mean: 22,
|
||||
Stddev: 2.8284271247461903,
|
||||
},
|
||||
{
|
||||
Name: "foo.bar",
|
||||
Hash: "foo.bar;a=b",
|
||||
AggregateSample: &AggregateSample{
|
||||
Count: 2,
|
||||
Min: 23,
|
||||
Max: 33,
|
||||
Sum: 56,
|
||||
SumSq: 1618,
|
||||
Rate: 200,
|
||||
},
|
||||
Mean: 28,
|
||||
Stddev: 7.0710678118654755,
|
||||
DisplayLabels: map[string]string{"a": "b"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
raw, err := inm.DisplayMetrics(nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
result := raw.(MetricsSummary)
|
||||
|
||||
// Ignore the LastUpdated field, we don't export that anyway
|
||||
for i, got := range result.Counters {
|
||||
expected.Counters[i].LastUpdated = got.LastUpdated
|
||||
}
|
||||
for i, got := range result.Samples {
|
||||
expected.Samples[i].LastUpdated = got.LastUpdated
|
||||
}
|
||||
|
||||
verify.Values(t, "all", result, expected)
|
||||
}
|
||||
33
vendor/github.com/armon/go-metrics/inmem_signal.go
сгенерированный
поставляемый
33
vendor/github.com/armon/go-metrics/inmem_signal.go
сгенерированный
поставляемый
@@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
@@ -75,22 +76,25 @@ func (i *InmemSignal) dumpStats() {
|
||||
|
||||
data := i.inm.Data()
|
||||
// Skip the last period which is still being aggregated
|
||||
for i := 0; i < len(data)-1; i++ {
|
||||
intv := data[i]
|
||||
for j := 0; j < len(data)-1; j++ {
|
||||
intv := data[j]
|
||||
intv.RLock()
|
||||
for name, val := range intv.Gauges {
|
||||
fmt.Fprintf(buf, "[%v][G] '%s': %0.3f\n", intv.Interval, name, val)
|
||||
for _, val := range intv.Gauges {
|
||||
name := i.flattenLabels(val.Name, val.Labels)
|
||||
fmt.Fprintf(buf, "[%v][G] '%s': %0.3f\n", intv.Interval, name, val.Value)
|
||||
}
|
||||
for name, vals := range intv.Points {
|
||||
for _, val := range vals {
|
||||
fmt.Fprintf(buf, "[%v][P] '%s': %0.3f\n", intv.Interval, name, val)
|
||||
}
|
||||
}
|
||||
for name, agg := range intv.Counters {
|
||||
fmt.Fprintf(buf, "[%v][C] '%s': %s\n", intv.Interval, name, agg)
|
||||
for _, agg := range intv.Counters {
|
||||
name := i.flattenLabels(agg.Name, agg.Labels)
|
||||
fmt.Fprintf(buf, "[%v][C] '%s': %s\n", intv.Interval, name, agg.AggregateSample)
|
||||
}
|
||||
for name, agg := range intv.Samples {
|
||||
fmt.Fprintf(buf, "[%v][S] '%s': %s\n", intv.Interval, name, agg)
|
||||
for _, agg := range intv.Samples {
|
||||
name := i.flattenLabels(agg.Name, agg.Labels)
|
||||
fmt.Fprintf(buf, "[%v][S] '%s': %s\n", intv.Interval, name, agg.AggregateSample)
|
||||
}
|
||||
intv.RUnlock()
|
||||
}
|
||||
@@ -98,3 +102,16 @@ func (i *InmemSignal) dumpStats() {
|
||||
// Write out the bytes
|
||||
i.w.Write(buf.Bytes())
|
||||
}
|
||||
|
||||
// Flattens the key for formatting along with its labels, removes spaces
|
||||
func (i *InmemSignal) flattenLabels(name string, labels []Label) string {
|
||||
buf := bytes.NewBufferString(name)
|
||||
replacer := strings.NewReplacer(" ", "_", ":", "_")
|
||||
|
||||
for _, label := range labels {
|
||||
replacer.WriteString(buf, ".")
|
||||
replacer.WriteString(buf, label.Value)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
12
vendor/github.com/armon/go-metrics/inmem_signal_test.go
сгенерированный
поставляемый
12
vendor/github.com/armon/go-metrics/inmem_signal_test.go
сгенерированный
поставляемый
@@ -19,6 +19,9 @@ func TestInmemSignal(t *testing.T) {
|
||||
inm.EmitKey([]string{"bar"}, 42)
|
||||
inm.IncrCounter([]string{"baz"}, 42)
|
||||
inm.AddSample([]string{"wow"}, 42)
|
||||
inm.SetGaugeWithLabels([]string{"asdf"}, 42, []Label{{"a", "b"}})
|
||||
inm.IncrCounterWithLabels([]string{"qwer"}, 42, []Label{{"a", "b"}})
|
||||
inm.AddSampleWithLabels([]string{"zxcv"}, 42, []Label{{"a", "b"}})
|
||||
|
||||
// Wait for period to end
|
||||
time.Sleep(15 * time.Millisecond)
|
||||
@@ -43,4 +46,13 @@ func TestInmemSignal(t *testing.T) {
|
||||
if !strings.Contains(out, "[S] 'wow': Count: 1 Sum: 42") {
|
||||
t.Fatalf("bad: %v", out)
|
||||
}
|
||||
if !strings.Contains(out, "[G] 'asdf.b': 42") {
|
||||
t.Fatalf("bad: %v", out)
|
||||
}
|
||||
if !strings.Contains(out, "[C] 'qwer.b': Count: 1 Sum: 42") {
|
||||
t.Fatalf("bad: %v", out)
|
||||
}
|
||||
if !strings.Contains(out, "[S] 'zxcv.b': Count: 1 Sum: 42") {
|
||||
t.Fatalf("bad: %v", out)
|
||||
}
|
||||
}
|
||||
|
||||
78
vendor/github.com/armon/go-metrics/inmem_test.go
сгенерированный
поставляемый
78
vendor/github.com/armon/go-metrics/inmem_test.go
сгенерированный
поставляемый
@@ -18,11 +18,15 @@ func TestInmemSink(t *testing.T) {
|
||||
|
||||
// Add data points
|
||||
inm.SetGauge([]string{"foo", "bar"}, 42)
|
||||
inm.SetGaugeWithLabels([]string{"foo", "bar"}, 23, []Label{{"a", "b"}})
|
||||
inm.EmitKey([]string{"foo", "bar"}, 42)
|
||||
inm.IncrCounter([]string{"foo", "bar"}, 20)
|
||||
inm.IncrCounter([]string{"foo", "bar"}, 22)
|
||||
inm.IncrCounterWithLabels([]string{"foo", "bar"}, 20, []Label{{"a", "b"}})
|
||||
inm.IncrCounterWithLabels([]string{"foo", "bar"}, 22, []Label{{"a", "b"}})
|
||||
inm.AddSample([]string{"foo", "bar"}, 20)
|
||||
inm.AddSample([]string{"foo", "bar"}, 22)
|
||||
inm.AddSampleWithLabels([]string{"foo", "bar"}, 23, []Label{{"a", "b"}})
|
||||
|
||||
data = inm.Data()
|
||||
if len(data) != 1 {
|
||||
@@ -35,49 +39,57 @@ func TestInmemSink(t *testing.T) {
|
||||
if time.Now().Sub(intvM.Interval) > 10*time.Millisecond {
|
||||
t.Fatalf("interval too old")
|
||||
}
|
||||
if intvM.Gauges["foo.bar"] != 42 {
|
||||
if intvM.Gauges["foo.bar"].Value != 42 {
|
||||
t.Fatalf("bad val: %v", intvM.Gauges)
|
||||
}
|
||||
if intvM.Gauges["foo.bar;a=b"].Value != 23 {
|
||||
t.Fatalf("bad val: %v", intvM.Gauges)
|
||||
}
|
||||
if intvM.Points["foo.bar"][0] != 42 {
|
||||
t.Fatalf("bad val: %v", intvM.Points)
|
||||
}
|
||||
|
||||
agg := intvM.Counters["foo.bar"]
|
||||
if agg.Count != 2 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.Rate != 200 {
|
||||
t.Fatalf("bad val: %v", agg.Rate)
|
||||
}
|
||||
if agg.Sum != 42 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.SumSq != 884 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.Min != 20 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.Max != 22 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.Mean() != 21 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.Stddev() != math.Sqrt(2) {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
for _, agg := range []SampledValue{intvM.Counters["foo.bar"], intvM.Counters["foo.bar;a=b"]} {
|
||||
if agg.Count != 2 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.Rate != 200 {
|
||||
t.Fatalf("bad val: %v", agg.Rate)
|
||||
}
|
||||
if agg.Sum != 42 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.SumSq != 884 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.Min != 20 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.Max != 22 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.AggregateSample.Mean() != 21 {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
if agg.AggregateSample.Stddev() != math.Sqrt(2) {
|
||||
t.Fatalf("bad val: %v", agg)
|
||||
}
|
||||
|
||||
if agg.LastUpdated.IsZero() {
|
||||
t.Fatalf("agg.LastUpdated is not set: %v", agg)
|
||||
}
|
||||
|
||||
diff := time.Now().Sub(agg.LastUpdated).Seconds()
|
||||
if diff > 1 {
|
||||
t.Fatalf("time diff too great: %f", diff)
|
||||
}
|
||||
}
|
||||
|
||||
if agg.LastUpdated.IsZero() {
|
||||
t.Fatalf("agg.LastUpdated is not set: %v", agg)
|
||||
if _, ok := intvM.Samples["foo.bar"]; !ok {
|
||||
t.Fatalf("missing sample")
|
||||
}
|
||||
|
||||
diff := time.Now().Sub(agg.LastUpdated).Seconds()
|
||||
if diff > 1 {
|
||||
t.Fatalf("time diff too great: %f", diff)
|
||||
}
|
||||
|
||||
if agg = intvM.Samples["foo.bar"]; agg == nil {
|
||||
if _, ok := intvM.Samples["foo.bar;a=b"]; !ok {
|
||||
t.Fatalf("missing sample")
|
||||
}
|
||||
|
||||
|
||||
121
vendor/github.com/armon/go-metrics/metrics.go
сгенерированный
поставляемый
121
vendor/github.com/armon/go-metrics/metrics.go
сгенерированный
поставляемый
@@ -2,20 +2,43 @@ package metrics
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-immutable-radix"
|
||||
)
|
||||
|
||||
type Label struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
func (m *Metrics) SetGauge(key []string, val float32) {
|
||||
if m.HostName != "" && m.EnableHostname {
|
||||
key = insert(0, m.HostName, key)
|
||||
m.SetGaugeWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (m *Metrics) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
if m.HostName != "" {
|
||||
if m.EnableHostnameLabel {
|
||||
labels = append(labels, Label{"host", m.HostName})
|
||||
} else if m.EnableHostname {
|
||||
key = insert(0, m.HostName, key)
|
||||
}
|
||||
}
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "gauge", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
if m.EnableServiceLabel {
|
||||
labels = append(labels, Label{"service", m.ServiceName})
|
||||
} else {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
}
|
||||
m.sink.SetGauge(key, val)
|
||||
if !m.allowMetric(key) {
|
||||
return
|
||||
}
|
||||
m.sink.SetGaugeWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func (m *Metrics) EmitKey(key []string, val float32) {
|
||||
@@ -25,40 +48,118 @@ func (m *Metrics) EmitKey(key []string, val float32) {
|
||||
if m.ServiceName != "" {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
if !m.allowMetric(key) {
|
||||
return
|
||||
}
|
||||
m.sink.EmitKey(key, val)
|
||||
}
|
||||
|
||||
func (m *Metrics) IncrCounter(key []string, val float32) {
|
||||
m.IncrCounterWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (m *Metrics) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
if m.HostName != "" && m.EnableHostnameLabel {
|
||||
labels = append(labels, Label{"host", m.HostName})
|
||||
}
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "counter", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
if m.EnableServiceLabel {
|
||||
labels = append(labels, Label{"service", m.ServiceName})
|
||||
} else {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
}
|
||||
m.sink.IncrCounter(key, val)
|
||||
if !m.allowMetric(key) {
|
||||
return
|
||||
}
|
||||
m.sink.IncrCounterWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func (m *Metrics) AddSample(key []string, val float32) {
|
||||
m.AddSampleWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (m *Metrics) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
if m.HostName != "" && m.EnableHostnameLabel {
|
||||
labels = append(labels, Label{"host", m.HostName})
|
||||
}
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "sample", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
if m.EnableServiceLabel {
|
||||
labels = append(labels, Label{"service", m.ServiceName})
|
||||
} else {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
}
|
||||
m.sink.AddSample(key, val)
|
||||
if !m.allowMetric(key) {
|
||||
return
|
||||
}
|
||||
m.sink.AddSampleWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func (m *Metrics) MeasureSince(key []string, start time.Time) {
|
||||
m.MeasureSinceWithLabels(key, start, nil)
|
||||
}
|
||||
|
||||
func (m *Metrics) MeasureSinceWithLabels(key []string, start time.Time, labels []Label) {
|
||||
if m.HostName != "" && m.EnableHostnameLabel {
|
||||
labels = append(labels, Label{"host", m.HostName})
|
||||
}
|
||||
if m.EnableTypePrefix {
|
||||
key = insert(0, "timer", key)
|
||||
}
|
||||
if m.ServiceName != "" {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
if m.EnableServiceLabel {
|
||||
labels = append(labels, Label{"service", m.ServiceName})
|
||||
} else {
|
||||
key = insert(0, m.ServiceName, key)
|
||||
}
|
||||
}
|
||||
if !m.allowMetric(key) {
|
||||
return
|
||||
}
|
||||
now := time.Now()
|
||||
elapsed := now.Sub(start)
|
||||
msec := float32(elapsed.Nanoseconds()) / float32(m.TimerGranularity)
|
||||
m.sink.AddSample(key, msec)
|
||||
m.sink.AddSampleWithLabels(key, msec, labels)
|
||||
}
|
||||
|
||||
// UpdateFilter overwrites the existing filter with the given rules.
|
||||
func (m *Metrics) UpdateFilter(allow, block []string) {
|
||||
m.filterLock.Lock()
|
||||
defer m.filterLock.Unlock()
|
||||
|
||||
m.AllowedPrefixes = allow
|
||||
m.BlockedPrefixes = block
|
||||
|
||||
m.filter = iradix.New()
|
||||
for _, prefix := range m.AllowedPrefixes {
|
||||
m.filter, _, _ = m.filter.Insert([]byte(prefix), true)
|
||||
}
|
||||
for _, prefix := range m.BlockedPrefixes {
|
||||
m.filter, _, _ = m.filter.Insert([]byte(prefix), false)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns whether the metric should be allowed based on configured prefix filters
|
||||
func (m *Metrics) allowMetric(key []string) bool {
|
||||
m.filterLock.RLock()
|
||||
defer m.filterLock.RUnlock()
|
||||
|
||||
if m.filter == nil || m.filter.Len() == 0 {
|
||||
return m.Config.FilterDefault
|
||||
}
|
||||
|
||||
_, allowed, ok := m.filter.Root().LongestPrefix([]byte(strings.Join(key, ".")))
|
||||
if !ok {
|
||||
return m.Config.FilterDefault
|
||||
}
|
||||
return allowed.(bool)
|
||||
}
|
||||
|
||||
// Periodically collects runtime stats to publish
|
||||
|
||||
151
vendor/github.com/armon/go-metrics/metrics_test.go
сгенерированный
поставляемый
151
vendor/github.com/armon/go-metrics/metrics_test.go
сгенерированный
поставляемый
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
func mockMetric() (*MockSink, *Metrics) {
|
||||
m := &MockSink{}
|
||||
met := &Metrics{sink: m}
|
||||
met := &Metrics{Config: Config{FilterDefault: true}, sink: m}
|
||||
return m, met
|
||||
}
|
||||
|
||||
@@ -23,6 +23,19 @@ func TestMetrics_SetGauge(t *testing.T) {
|
||||
t.Fatalf("")
|
||||
}
|
||||
|
||||
m, met = mockMetric()
|
||||
labels := []Label{{"a", "b"}}
|
||||
met.SetGaugeWithLabels([]string{"key"}, float32(1), labels)
|
||||
if m.keys[0][0] != "key" {
|
||||
t.Fatalf("")
|
||||
}
|
||||
if m.vals[0] != 1 {
|
||||
t.Fatalf("")
|
||||
}
|
||||
if !reflect.DeepEqual(m.labels[0], labels) {
|
||||
t.Fatalf("")
|
||||
}
|
||||
|
||||
m, met = mockMetric()
|
||||
met.HostName = "test"
|
||||
met.EnableHostname = true
|
||||
@@ -96,6 +109,19 @@ func TestMetrics_IncrCounter(t *testing.T) {
|
||||
t.Fatalf("")
|
||||
}
|
||||
|
||||
m, met = mockMetric()
|
||||
labels := []Label{{"a", "b"}}
|
||||
met.IncrCounterWithLabels([]string{"key"}, float32(1), labels)
|
||||
if m.keys[0][0] != "key" {
|
||||
t.Fatalf("")
|
||||
}
|
||||
if m.vals[0] != 1 {
|
||||
t.Fatalf("")
|
||||
}
|
||||
if !reflect.DeepEqual(m.labels[0], labels) {
|
||||
t.Fatalf("")
|
||||
}
|
||||
|
||||
m, met = mockMetric()
|
||||
met.EnableTypePrefix = true
|
||||
met.IncrCounter([]string{"key"}, float32(1))
|
||||
@@ -127,6 +153,19 @@ func TestMetrics_AddSample(t *testing.T) {
|
||||
t.Fatalf("")
|
||||
}
|
||||
|
||||
m, met = mockMetric()
|
||||
labels := []Label{{"a", "b"}}
|
||||
met.AddSampleWithLabels([]string{"key"}, float32(1), labels)
|
||||
if m.keys[0][0] != "key" {
|
||||
t.Fatalf("")
|
||||
}
|
||||
if m.vals[0] != 1 {
|
||||
t.Fatalf("")
|
||||
}
|
||||
if !reflect.DeepEqual(m.labels[0], labels) {
|
||||
t.Fatalf("")
|
||||
}
|
||||
|
||||
m, met = mockMetric()
|
||||
met.EnableTypePrefix = true
|
||||
met.AddSample([]string{"key"}, float32(1))
|
||||
@@ -160,6 +199,20 @@ func TestMetrics_MeasureSince(t *testing.T) {
|
||||
t.Fatalf("")
|
||||
}
|
||||
|
||||
m, met = mockMetric()
|
||||
met.TimerGranularity = time.Millisecond
|
||||
labels := []Label{{"a", "b"}}
|
||||
met.MeasureSinceWithLabels([]string{"key"}, n, labels)
|
||||
if m.keys[0][0] != "key" {
|
||||
t.Fatalf("")
|
||||
}
|
||||
if m.vals[0] > 0.1 {
|
||||
t.Fatalf("")
|
||||
}
|
||||
if !reflect.DeepEqual(m.labels[0], labels) {
|
||||
t.Fatalf("")
|
||||
}
|
||||
|
||||
m, met = mockMetric()
|
||||
met.TimerGranularity = time.Millisecond
|
||||
met.EnableTypePrefix = true
|
||||
@@ -260,3 +313,99 @@ func TestInsert(t *testing.T) {
|
||||
t.Fatalf("bad insert %v %v", exp, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetrics_Filter_Blacklist(t *testing.T) {
|
||||
m := &MockSink{}
|
||||
conf := DefaultConfig("")
|
||||
conf.AllowedPrefixes = []string{"service", "debug.thing"}
|
||||
conf.BlockedPrefixes = []string{"debug"}
|
||||
conf.EnableHostname = false
|
||||
met, err := New(conf, m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Allowed by default
|
||||
key := []string{"thing"}
|
||||
met.SetGauge(key, 1)
|
||||
if !reflect.DeepEqual(m.keys[0], key) {
|
||||
t.Fatalf("key doesn't exist %v, %v", m.keys[0], key)
|
||||
}
|
||||
if m.vals[0] != 1 {
|
||||
t.Fatalf("bad val: %v", m.vals[0])
|
||||
}
|
||||
|
||||
// Allowed by filter
|
||||
key = []string{"service", "thing"}
|
||||
met.SetGauge(key, 2)
|
||||
if !reflect.DeepEqual(m.keys[1], key) {
|
||||
t.Fatalf("key doesn't exist")
|
||||
}
|
||||
if m.vals[1] != 2 {
|
||||
t.Fatalf("bad val: %v", m.vals[1])
|
||||
}
|
||||
|
||||
// Allowed by filter, subtree of a blocked entry
|
||||
key = []string{"debug", "thing"}
|
||||
met.SetGauge(key, 3)
|
||||
if !reflect.DeepEqual(m.keys[2], key) {
|
||||
t.Fatalf("key doesn't exist")
|
||||
}
|
||||
if m.vals[2] != 3 {
|
||||
t.Fatalf("bad val: %v", m.vals[2])
|
||||
}
|
||||
|
||||
// Blocked by filter
|
||||
key = []string{"debug", "other-thing"}
|
||||
met.SetGauge(key, 4)
|
||||
if len(m.keys) != 3 {
|
||||
t.Fatalf("key shouldn't exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetrics_Filter_Whitelist(t *testing.T) {
|
||||
m := &MockSink{}
|
||||
conf := DefaultConfig("")
|
||||
conf.AllowedPrefixes = []string{"service", "debug.thing"}
|
||||
conf.BlockedPrefixes = []string{"debug"}
|
||||
conf.FilterDefault = false
|
||||
conf.EnableHostname = false
|
||||
met, err := New(conf, m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Blocked by default
|
||||
key := []string{"thing"}
|
||||
met.SetGauge(key, 1)
|
||||
if len(m.keys) != 0 {
|
||||
t.Fatalf("key should not exist")
|
||||
}
|
||||
|
||||
// Allowed by filter
|
||||
key = []string{"service", "thing"}
|
||||
met.SetGauge(key, 2)
|
||||
if !reflect.DeepEqual(m.keys[0], key) {
|
||||
t.Fatalf("key doesn't exist")
|
||||
}
|
||||
if m.vals[0] != 2 {
|
||||
t.Fatalf("bad val: %v", m.vals[0])
|
||||
}
|
||||
|
||||
// Allowed by filter, subtree of a blocked entry
|
||||
key = []string{"debug", "thing"}
|
||||
met.SetGauge(key, 3)
|
||||
if !reflect.DeepEqual(m.keys[1], key) {
|
||||
t.Fatalf("key doesn't exist")
|
||||
}
|
||||
if m.vals[1] != 3 {
|
||||
t.Fatalf("bad val: %v", m.vals[1])
|
||||
}
|
||||
|
||||
// Blocked by filter
|
||||
key = []string{"debug", "other-thing"}
|
||||
met.SetGauge(key, 4)
|
||||
if len(m.keys) != 2 {
|
||||
t.Fatalf("key shouldn't exist")
|
||||
}
|
||||
}
|
||||
|
||||
72
vendor/github.com/armon/go-metrics/prometheus/prometheus.go
сгенерированный
поставляемый
72
vendor/github.com/armon/go-metrics/prometheus/prometheus.go
сгенерированный
поставляемый
@@ -2,10 +2,14 @@
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"regexp"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -24,24 +28,42 @@ func NewPrometheusSink() (*PrometheusSink, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *PrometheusSink) flattenKey(parts []string) string {
|
||||
joined := strings.Join(parts, "_")
|
||||
joined = strings.Replace(joined, " ", "_", -1)
|
||||
joined = strings.Replace(joined, ".", "_", -1)
|
||||
joined = strings.Replace(joined, "-", "_", -1)
|
||||
joined = strings.Replace(joined, "=", "_", -1)
|
||||
return joined
|
||||
var forbiddenChars = regexp.MustCompile("[ .=\\-]")
|
||||
|
||||
func (p *PrometheusSink) flattenKey(parts []string, labels []metrics.Label) (string, string) {
|
||||
key := strings.Join(parts, "_")
|
||||
key = forbiddenChars.ReplaceAllString(key, "_")
|
||||
|
||||
hash := key
|
||||
for _, label := range labels {
|
||||
hash += fmt.Sprintf(";%s=%s", label.Name, label.Value)
|
||||
}
|
||||
|
||||
return key, hash
|
||||
}
|
||||
|
||||
func prometheusLabels(labels []metrics.Label) prometheus.Labels {
|
||||
l := make(prometheus.Labels)
|
||||
for _, label := range labels {
|
||||
l[label.Name] = label.Value
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (p *PrometheusSink) SetGauge(parts []string, val float32) {
|
||||
p.SetGaugeWithLabels(parts, val, nil)
|
||||
}
|
||||
|
||||
func (p *PrometheusSink) SetGaugeWithLabels(parts []string, val float32, labels []metrics.Label) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
key := p.flattenKey(parts)
|
||||
g, ok := p.gauges[key]
|
||||
key, hash := p.flattenKey(parts, labels)
|
||||
g, ok := p.gauges[hash]
|
||||
if !ok {
|
||||
g = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: key,
|
||||
Help: key,
|
||||
Name: key,
|
||||
Help: key,
|
||||
ConstLabels: prometheusLabels(labels),
|
||||
})
|
||||
prometheus.MustRegister(g)
|
||||
p.gauges[key] = g
|
||||
@@ -50,15 +72,20 @@ func (p *PrometheusSink) SetGauge(parts []string, val float32) {
|
||||
}
|
||||
|
||||
func (p *PrometheusSink) AddSample(parts []string, val float32) {
|
||||
p.AddSampleWithLabels(parts, val, nil)
|
||||
}
|
||||
|
||||
func (p *PrometheusSink) AddSampleWithLabels(parts []string, val float32, labels []metrics.Label) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
key := p.flattenKey(parts)
|
||||
g, ok := p.summaries[key]
|
||||
key, hash := p.flattenKey(parts, labels)
|
||||
g, ok := p.summaries[hash]
|
||||
if !ok {
|
||||
g = prometheus.NewSummary(prometheus.SummaryOpts{
|
||||
Name: key,
|
||||
Help: key,
|
||||
MaxAge: 10 * time.Second,
|
||||
Name: key,
|
||||
Help: key,
|
||||
MaxAge: 10 * time.Second,
|
||||
ConstLabels: prometheusLabels(labels),
|
||||
})
|
||||
prometheus.MustRegister(g)
|
||||
p.summaries[key] = g
|
||||
@@ -73,14 +100,19 @@ func (p *PrometheusSink) EmitKey(key []string, val float32) {
|
||||
}
|
||||
|
||||
func (p *PrometheusSink) IncrCounter(parts []string, val float32) {
|
||||
p.IncrCounterWithLabels(parts, val, nil)
|
||||
}
|
||||
|
||||
func (p *PrometheusSink) IncrCounterWithLabels(parts []string, val float32, labels []metrics.Label) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
key := p.flattenKey(parts)
|
||||
g, ok := p.counters[key]
|
||||
key, hash := p.flattenKey(parts, labels)
|
||||
g, ok := p.counters[hash]
|
||||
if !ok {
|
||||
g = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Name: key,
|
||||
Help: key,
|
||||
Name: key,
|
||||
Help: key,
|
||||
ConstLabels: prometheusLabels(labels),
|
||||
})
|
||||
prometheus.MustRegister(g)
|
||||
p.counters[key] = g
|
||||
|
||||
32
vendor/github.com/armon/go-metrics/sink.go
сгенерированный
поставляемый
32
vendor/github.com/armon/go-metrics/sink.go
сгенерированный
поставляемый
@@ -10,31 +10,41 @@ import (
|
||||
type MetricSink interface {
|
||||
// A Gauge should retain the last value it is set to
|
||||
SetGauge(key []string, val float32)
|
||||
SetGaugeWithLabels(key []string, val float32, labels []Label)
|
||||
|
||||
// Should emit a Key/Value pair for each call
|
||||
EmitKey(key []string, val float32)
|
||||
|
||||
// Counters should accumulate values
|
||||
IncrCounter(key []string, val float32)
|
||||
IncrCounterWithLabels(key []string, val float32, labels []Label)
|
||||
|
||||
// Samples are for timing information, where quantiles are used
|
||||
AddSample(key []string, val float32)
|
||||
AddSampleWithLabels(key []string, val float32, labels []Label)
|
||||
}
|
||||
|
||||
// BlackholeSink is used to just blackhole messages
|
||||
type BlackholeSink struct{}
|
||||
|
||||
func (*BlackholeSink) SetGauge(key []string, val float32) {}
|
||||
func (*BlackholeSink) EmitKey(key []string, val float32) {}
|
||||
func (*BlackholeSink) IncrCounter(key []string, val float32) {}
|
||||
func (*BlackholeSink) AddSample(key []string, val float32) {}
|
||||
func (*BlackholeSink) SetGauge(key []string, val float32) {}
|
||||
func (*BlackholeSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {}
|
||||
func (*BlackholeSink) EmitKey(key []string, val float32) {}
|
||||
func (*BlackholeSink) IncrCounter(key []string, val float32) {}
|
||||
func (*BlackholeSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {}
|
||||
func (*BlackholeSink) AddSample(key []string, val float32) {}
|
||||
func (*BlackholeSink) AddSampleWithLabels(key []string, val float32, labels []Label) {}
|
||||
|
||||
// FanoutSink is used to sink to fanout values to multiple sinks
|
||||
type FanoutSink []MetricSink
|
||||
|
||||
func (fh FanoutSink) SetGauge(key []string, val float32) {
|
||||
fh.SetGaugeWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (fh FanoutSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
for _, s := range fh {
|
||||
s.SetGauge(key, val)
|
||||
s.SetGaugeWithLabels(key, val, labels)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,14 +55,22 @@ func (fh FanoutSink) EmitKey(key []string, val float32) {
|
||||
}
|
||||
|
||||
func (fh FanoutSink) IncrCounter(key []string, val float32) {
|
||||
fh.IncrCounterWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (fh FanoutSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
for _, s := range fh {
|
||||
s.IncrCounter(key, val)
|
||||
s.IncrCounterWithLabels(key, val, labels)
|
||||
}
|
||||
}
|
||||
|
||||
func (fh FanoutSink) AddSample(key []string, val float32) {
|
||||
fh.AddSampleWithLabels(key, val, nil)
|
||||
}
|
||||
|
||||
func (fh FanoutSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
for _, s := range fh {
|
||||
s.AddSample(key, val)
|
||||
s.AddSampleWithLabels(key, val, labels)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
108
vendor/github.com/armon/go-metrics/sink_test.go
сгенерированный
поставляемый
108
vendor/github.com/armon/go-metrics/sink_test.go
сгенерированный
поставляемый
@@ -7,25 +7,39 @@ import (
|
||||
)
|
||||
|
||||
type MockSink struct {
|
||||
keys [][]string
|
||||
vals []float32
|
||||
keys [][]string
|
||||
vals []float32
|
||||
labels [][]Label
|
||||
}
|
||||
|
||||
func (m *MockSink) SetGauge(key []string, val float32) {
|
||||
m.SetGaugeWithLabels(key, val, nil)
|
||||
}
|
||||
func (m *MockSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
m.keys = append(m.keys, key)
|
||||
m.vals = append(m.vals, val)
|
||||
m.labels = append(m.labels, labels)
|
||||
}
|
||||
func (m *MockSink) EmitKey(key []string, val float32) {
|
||||
m.keys = append(m.keys, key)
|
||||
m.vals = append(m.vals, val)
|
||||
m.labels = append(m.labels, nil)
|
||||
}
|
||||
func (m *MockSink) IncrCounter(key []string, val float32) {
|
||||
m.IncrCounterWithLabels(key, val, nil)
|
||||
}
|
||||
func (m *MockSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
m.keys = append(m.keys, key)
|
||||
m.vals = append(m.vals, val)
|
||||
m.labels = append(m.labels, labels)
|
||||
}
|
||||
func (m *MockSink) AddSample(key []string, val float32) {
|
||||
m.AddSampleWithLabels(key, val, nil)
|
||||
}
|
||||
func (m *MockSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
m.keys = append(m.keys, key)
|
||||
m.vals = append(m.vals, val)
|
||||
m.labels = append(m.labels, labels)
|
||||
}
|
||||
|
||||
func TestFanoutSink_Gauge(t *testing.T) {
|
||||
@@ -51,6 +65,36 @@ func TestFanoutSink_Gauge(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFanoutSink_Gauge_Labels(t *testing.T) {
|
||||
m1 := &MockSink{}
|
||||
m2 := &MockSink{}
|
||||
fh := &FanoutSink{m1, m2}
|
||||
|
||||
k := []string{"test"}
|
||||
v := float32(42.0)
|
||||
l := []Label{{"a", "b"}}
|
||||
fh.SetGaugeWithLabels(k, v, l)
|
||||
|
||||
if !reflect.DeepEqual(m1.keys[0], k) {
|
||||
t.Fatalf("key not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.keys[0], k) {
|
||||
t.Fatalf("key not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m1.vals[0], v) {
|
||||
t.Fatalf("val not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.vals[0], v) {
|
||||
t.Fatalf("val not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m1.labels[0], l) {
|
||||
t.Fatalf("labels not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.labels[0], l) {
|
||||
t.Fatalf("labels not equal")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFanoutSink_Key(t *testing.T) {
|
||||
m1 := &MockSink{}
|
||||
m2 := &MockSink{}
|
||||
@@ -97,6 +141,36 @@ func TestFanoutSink_Counter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFanoutSink_Counter_Labels(t *testing.T) {
|
||||
m1 := &MockSink{}
|
||||
m2 := &MockSink{}
|
||||
fh := &FanoutSink{m1, m2}
|
||||
|
||||
k := []string{"test"}
|
||||
v := float32(42.0)
|
||||
l := []Label{{"a", "b"}}
|
||||
fh.IncrCounterWithLabels(k, v, l)
|
||||
|
||||
if !reflect.DeepEqual(m1.keys[0], k) {
|
||||
t.Fatalf("key not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.keys[0], k) {
|
||||
t.Fatalf("key not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m1.vals[0], v) {
|
||||
t.Fatalf("val not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.vals[0], v) {
|
||||
t.Fatalf("val not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m1.labels[0], l) {
|
||||
t.Fatalf("labels not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.labels[0], l) {
|
||||
t.Fatalf("labels not equal")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFanoutSink_Sample(t *testing.T) {
|
||||
m1 := &MockSink{}
|
||||
m2 := &MockSink{}
|
||||
@@ -120,6 +194,36 @@ func TestFanoutSink_Sample(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFanoutSink_Sample_Labels(t *testing.T) {
|
||||
m1 := &MockSink{}
|
||||
m2 := &MockSink{}
|
||||
fh := &FanoutSink{m1, m2}
|
||||
|
||||
k := []string{"test"}
|
||||
v := float32(42.0)
|
||||
l := []Label{{"a", "b"}}
|
||||
fh.AddSampleWithLabels(k, v, l)
|
||||
|
||||
if !reflect.DeepEqual(m1.keys[0], k) {
|
||||
t.Fatalf("key not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.keys[0], k) {
|
||||
t.Fatalf("key not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m1.vals[0], v) {
|
||||
t.Fatalf("val not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.vals[0], v) {
|
||||
t.Fatalf("val not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m1.labels[0], l) {
|
||||
t.Fatalf("labels not equal")
|
||||
}
|
||||
if !reflect.DeepEqual(m2.labels[0], l) {
|
||||
t.Fatalf("labels not equal")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewMetricSinkFromURL(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
|
||||
37
vendor/github.com/armon/go-metrics/start.go
сгенерированный
поставляемый
37
vendor/github.com/armon/go-metrics/start.go
сгенерированный
поставляемый
@@ -2,8 +2,11 @@ package metrics
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-immutable-radix"
|
||||
)
|
||||
|
||||
// Config is used to configure metrics settings
|
||||
@@ -11,18 +14,26 @@ type Config struct {
|
||||
ServiceName string // Prefixed with keys to seperate services
|
||||
HostName string // Hostname to use. If not provided and EnableHostname, it will be os.Hostname
|
||||
EnableHostname bool // Enable prefixing gauge values with hostname
|
||||
EnableHostnameLabel bool // Enable adding hostname to labels
|
||||
EnableServiceLabel bool // Enable adding service to labels
|
||||
EnableRuntimeMetrics bool // Enables profiling of runtime metrics (GC, Goroutines, Memory)
|
||||
EnableTypePrefix bool // Prefixes key with a type ("counter", "gauge", "timer")
|
||||
TimerGranularity time.Duration // Granularity of timers.
|
||||
ProfileInterval time.Duration // Interval to profile runtime metrics
|
||||
|
||||
AllowedPrefixes []string // A list of metric prefixes to allow, with '.' as the separator
|
||||
BlockedPrefixes []string // A list of metric prefixes to block, with '.' as the separator
|
||||
FilterDefault bool // Whether to allow metrics by default
|
||||
}
|
||||
|
||||
// Metrics represents an instance of a metrics sink that can
|
||||
// be used to emit
|
||||
type Metrics struct {
|
||||
Config
|
||||
lastNumGC uint32
|
||||
sink MetricSink
|
||||
lastNumGC uint32
|
||||
sink MetricSink
|
||||
filter *iradix.Tree
|
||||
filterLock sync.RWMutex
|
||||
}
|
||||
|
||||
// Shared global metrics instance
|
||||
@@ -43,6 +54,7 @@ func DefaultConfig(serviceName string) *Config {
|
||||
EnableTypePrefix: false, // Disable type prefix
|
||||
TimerGranularity: time.Millisecond, // Timers are in milliseconds
|
||||
ProfileInterval: time.Second, // Poll runtime every second
|
||||
FilterDefault: true, // Don't filter metrics by default
|
||||
}
|
||||
|
||||
// Try to get the hostname
|
||||
@@ -56,6 +68,7 @@ func New(conf *Config, sink MetricSink) (*Metrics, error) {
|
||||
met := &Metrics{}
|
||||
met.Config = *conf
|
||||
met.sink = sink
|
||||
met.UpdateFilter(conf.AllowedPrefixes, conf.BlockedPrefixes)
|
||||
|
||||
// Start the runtime collector
|
||||
if conf.EnableRuntimeMetrics {
|
||||
@@ -79,6 +92,10 @@ func SetGauge(key []string, val float32) {
|
||||
globalMetrics.Load().(*Metrics).SetGauge(key, val)
|
||||
}
|
||||
|
||||
func SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
globalMetrics.Load().(*Metrics).SetGaugeWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func EmitKey(key []string, val float32) {
|
||||
globalMetrics.Load().(*Metrics).EmitKey(key, val)
|
||||
}
|
||||
@@ -87,10 +104,26 @@ func IncrCounter(key []string, val float32) {
|
||||
globalMetrics.Load().(*Metrics).IncrCounter(key, val)
|
||||
}
|
||||
|
||||
func IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
globalMetrics.Load().(*Metrics).IncrCounterWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func AddSample(key []string, val float32) {
|
||||
globalMetrics.Load().(*Metrics).AddSample(key, val)
|
||||
}
|
||||
|
||||
func AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
globalMetrics.Load().(*Metrics).AddSampleWithLabels(key, val, labels)
|
||||
}
|
||||
|
||||
func MeasureSince(key []string, start time.Time) {
|
||||
globalMetrics.Load().(*Metrics).MeasureSince(key, start)
|
||||
}
|
||||
|
||||
func MeasureSinceWithLabels(key []string, start time.Time, labels []Label) {
|
||||
globalMetrics.Load().(*Metrics).MeasureSinceWithLabels(key, start, labels)
|
||||
}
|
||||
|
||||
func UpdateFilter(allow, block []string) {
|
||||
globalMetrics.Load().(*Metrics).UpdateFilter(allow, block)
|
||||
}
|
||||
|
||||
107
vendor/github.com/armon/go-metrics/start_test.go
сгенерированный
поставляемый
107
vendor/github.com/armon/go-metrics/start_test.go
сгенерированный
поставляемый
@@ -30,6 +30,7 @@ func TestDefaultConfig(t *testing.T) {
|
||||
t.Fatalf("bad interval")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GlobalMetrics(t *testing.T) {
|
||||
var tests = []struct {
|
||||
desc string
|
||||
@@ -46,7 +47,7 @@ func Test_GlobalMetrics(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
s := &MockSink{}
|
||||
globalMetrics.Store(&Metrics{sink: s})
|
||||
globalMetrics.Store(&Metrics{Config: Config{FilterDefault: true}, sink: s})
|
||||
tt.fn(tt.key, tt.val)
|
||||
if got, want := s.keys[0], tt.key; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got key %s want %s", got, want)
|
||||
@@ -58,9 +59,83 @@ func Test_GlobalMetrics(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GlobalMetrics_Labels(t *testing.T) {
|
||||
labels := []Label{{"a", "b"}}
|
||||
var tests = []struct {
|
||||
desc string
|
||||
key []string
|
||||
val float32
|
||||
fn func([]string, float32, []Label)
|
||||
labels []Label
|
||||
}{
|
||||
{"SetGaugeWithLabels", []string{"test"}, 42, SetGaugeWithLabels, labels},
|
||||
{"IncrCounterWithLabels", []string{"test"}, 42, IncrCounterWithLabels, labels},
|
||||
{"AddSampleWithLabels", []string{"test"}, 42, AddSampleWithLabels, labels},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
s := &MockSink{}
|
||||
globalMetrics.Store(&Metrics{Config: Config{FilterDefault: true}, sink: s})
|
||||
tt.fn(tt.key, tt.val, tt.labels)
|
||||
if got, want := s.keys[0], tt.key; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got key %s want %s", got, want)
|
||||
}
|
||||
if got, want := s.vals[0], tt.val; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got val %s want %s", got, want)
|
||||
}
|
||||
if got, want := s.labels[0], tt.labels; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got val %s want %s", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GlobalMetrics_DefaultLabels(t *testing.T) {
|
||||
config := Config{
|
||||
HostName: "host1",
|
||||
ServiceName: "redis",
|
||||
EnableHostnameLabel: true,
|
||||
EnableServiceLabel: true,
|
||||
FilterDefault: true,
|
||||
}
|
||||
labels := []Label{
|
||||
{"host", config.HostName},
|
||||
{"service", config.ServiceName},
|
||||
}
|
||||
var tests = []struct {
|
||||
desc string
|
||||
key []string
|
||||
val float32
|
||||
fn func([]string, float32, []Label)
|
||||
labels []Label
|
||||
}{
|
||||
{"SetGaugeWithLabels", []string{"test"}, 42, SetGaugeWithLabels, labels},
|
||||
{"IncrCounterWithLabels", []string{"test"}, 42, IncrCounterWithLabels, labels},
|
||||
{"AddSampleWithLabels", []string{"test"}, 42, AddSampleWithLabels, labels},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
s := &MockSink{}
|
||||
globalMetrics.Store(&Metrics{Config: config, sink: s})
|
||||
tt.fn(tt.key, tt.val, nil)
|
||||
if got, want := s.keys[0], tt.key; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got key %s want %s", got, want)
|
||||
}
|
||||
if got, want := s.vals[0], tt.val; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got val %s want %s", got, want)
|
||||
}
|
||||
if got, want := s.labels[0], tt.labels; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got val %s want %s", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GlobalMetrics_MeasureSince(t *testing.T) {
|
||||
s := &MockSink{}
|
||||
m := &Metrics{sink: s, Config: Config{TimerGranularity: time.Millisecond}}
|
||||
m := &Metrics{sink: s, Config: Config{TimerGranularity: time.Millisecond, FilterDefault: true}}
|
||||
globalMetrics.Store(m)
|
||||
|
||||
k := []string{"test"}
|
||||
@@ -73,6 +148,34 @@ func Test_GlobalMetrics_MeasureSince(t *testing.T) {
|
||||
if s.vals[0] > 0.1 {
|
||||
t.Fatalf("val too large %v", s.vals[0])
|
||||
}
|
||||
|
||||
labels := []Label{{"a", "b"}}
|
||||
MeasureSinceWithLabels(k, now, labels)
|
||||
if got, want := s.keys[1], k; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got key %s want %s", got, want)
|
||||
}
|
||||
if s.vals[1] > 0.1 {
|
||||
t.Fatalf("val too large %v", s.vals[0])
|
||||
}
|
||||
if got, want := s.labels[1], labels; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got val %s want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GlobalMetrics_UpdateFilter(t *testing.T) {
|
||||
globalMetrics.Store(&Metrics{Config: Config{
|
||||
AllowedPrefixes: []string{"a"},
|
||||
BlockedPrefixes: []string{"b"},
|
||||
}})
|
||||
UpdateFilter([]string{"c"}, []string{"d"})
|
||||
|
||||
m := globalMetrics.Load().(*Metrics)
|
||||
if m.AllowedPrefixes[0] != "c" {
|
||||
t.Fatalf("bad: %v", m.AllowedPrefixes)
|
||||
}
|
||||
if m.BlockedPrefixes[0] != "d" {
|
||||
t.Fatalf("bad: %v", m.BlockedPrefixes)
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark_GlobalMetrics_Direct/direct-8 5000000 278 ns/op
|
||||
|
||||
23
vendor/github.com/armon/go-metrics/statsd.go
сгенерированный
поставляемый
23
vendor/github.com/armon/go-metrics/statsd.go
сгенерированный
поставляемый
@@ -50,6 +50,11 @@ func (s *StatsdSink) SetGauge(key []string, val float32) {
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) EmitKey(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val))
|
||||
@@ -60,11 +65,21 @@ func (s *StatsdSink) IncrCounter(key []string, val float32) {
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) AddSample(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsdSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
|
||||
}
|
||||
|
||||
// Flattens the key for formatting, removes spaces
|
||||
func (s *StatsdSink) flattenKey(parts []string) string {
|
||||
joined := strings.Join(parts, ".")
|
||||
@@ -80,6 +95,14 @@ func (s *StatsdSink) flattenKey(parts []string) string {
|
||||
}, joined)
|
||||
}
|
||||
|
||||
// Flattens the key along with labels for formatting, removes spaces
|
||||
func (s *StatsdSink) flattenKeyLabels(parts []string, labels []Label) string {
|
||||
for _, label := range labels {
|
||||
parts = append(parts, label.Value)
|
||||
}
|
||||
return s.flattenKey(parts)
|
||||
}
|
||||
|
||||
// Does a non-blocking push to the metrics queue
|
||||
func (s *StatsdSink) pushMetric(m string) {
|
||||
select {
|
||||
|
||||
39
vendor/github.com/armon/go-metrics/statsd_test.go
сгенерированный
поставляемый
39
vendor/github.com/armon/go-metrics/statsd_test.go
сгенерированный
поставляемый
@@ -66,7 +66,7 @@ func TestStatsd_Conn(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "key.other:2.000000|kv\n" {
|
||||
if line != "gauge_labels.val.label:2.000000|g\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestStatsd_Conn(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "counter.me:3.000000|c\n" {
|
||||
if line != "key.other:3.000000|kv\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
@@ -82,7 +82,31 @@ func TestStatsd_Conn(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "sample.slow_thingy:4.000000|ms\n" {
|
||||
if line != "counter.me:4.000000|c\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
line, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "counter_labels.me.label:5.000000|c\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
line, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "sample.slow_thingy:6.000000|ms\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
line, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "sample_labels.slow_thingy.label:7.000000|ms\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
@@ -94,9 +118,12 @@ func TestStatsd_Conn(t *testing.T) {
|
||||
}
|
||||
|
||||
s.SetGauge([]string{"gauge", "val"}, float32(1))
|
||||
s.EmitKey([]string{"key", "other"}, float32(2))
|
||||
s.IncrCounter([]string{"counter", "me"}, float32(3))
|
||||
s.AddSample([]string{"sample", "slow thingy"}, float32(4))
|
||||
s.SetGaugeWithLabels([]string{"gauge_labels", "val"}, float32(2), []Label{{"a", "label"}})
|
||||
s.EmitKey([]string{"key", "other"}, float32(3))
|
||||
s.IncrCounter([]string{"counter", "me"}, float32(4))
|
||||
s.IncrCounterWithLabels([]string{"counter_labels", "me"}, float32(5), []Label{{"a", "label"}})
|
||||
s.AddSample([]string{"sample", "slow thingy"}, float32(6))
|
||||
s.AddSampleWithLabels([]string{"sample_labels", "slow thingy"}, float32(7), []Label{{"a", "label"}})
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
|
||||
23
vendor/github.com/armon/go-metrics/statsite.go
сгенерированный
поставляемый
23
vendor/github.com/armon/go-metrics/statsite.go
сгенерированный
поставляемый
@@ -50,6 +50,11 @@ func (s *StatsiteSink) SetGauge(key []string, val float32) {
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) EmitKey(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val))
|
||||
@@ -60,11 +65,21 @@ func (s *StatsiteSink) IncrCounter(key []string, val float32) {
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) AddSample(key []string, val float32) {
|
||||
flatKey := s.flattenKey(key)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
|
||||
}
|
||||
|
||||
func (s *StatsiteSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
|
||||
flatKey := s.flattenKeyLabels(key, labels)
|
||||
s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
|
||||
}
|
||||
|
||||
// Flattens the key for formatting, removes spaces
|
||||
func (s *StatsiteSink) flattenKey(parts []string) string {
|
||||
joined := strings.Join(parts, ".")
|
||||
@@ -80,6 +95,14 @@ func (s *StatsiteSink) flattenKey(parts []string) string {
|
||||
}, joined)
|
||||
}
|
||||
|
||||
// Flattens the key along with labels for formatting, removes spaces
|
||||
func (s *StatsiteSink) flattenKeyLabels(parts []string, labels []Label) string {
|
||||
for _, label := range labels {
|
||||
parts = append(parts, label.Value)
|
||||
}
|
||||
return s.flattenKey(parts)
|
||||
}
|
||||
|
||||
// Does a non-blocking push to the metrics queue
|
||||
func (s *StatsiteSink) pushMetric(m string) {
|
||||
select {
|
||||
|
||||
39
vendor/github.com/armon/go-metrics/statsite_test.go
сгенерированный
поставляемый
39
vendor/github.com/armon/go-metrics/statsite_test.go
сгенерированный
поставляемый
@@ -61,7 +61,7 @@ func TestStatsite_Conn(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "key.other:2.000000|kv\n" {
|
||||
if line != "gauge_labels.val.label:2.000000|g\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestStatsite_Conn(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "counter.me:3.000000|c\n" {
|
||||
if line != "key.other:3.000000|kv\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
@@ -77,7 +77,31 @@ func TestStatsite_Conn(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "sample.slow_thingy:4.000000|ms\n" {
|
||||
if line != "counter.me:4.000000|c\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
line, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "counter_labels.me.label:5.000000|c\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
line, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "sample.slow_thingy:6.000000|ms\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
line, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err %s", err)
|
||||
}
|
||||
if line != "sample_labels.slow_thingy.label:7.000000|ms\n" {
|
||||
t.Fatalf("bad line %s", line)
|
||||
}
|
||||
|
||||
@@ -90,9 +114,12 @@ func TestStatsite_Conn(t *testing.T) {
|
||||
}
|
||||
|
||||
s.SetGauge([]string{"gauge", "val"}, float32(1))
|
||||
s.EmitKey([]string{"key", "other"}, float32(2))
|
||||
s.IncrCounter([]string{"counter", "me"}, float32(3))
|
||||
s.AddSample([]string{"sample", "slow thingy"}, float32(4))
|
||||
s.SetGaugeWithLabels([]string{"gauge_labels", "val"}, float32(2), []Label{{"a", "label"}})
|
||||
s.EmitKey([]string{"key", "other"}, float32(3))
|
||||
s.IncrCounter([]string{"counter", "me"}, float32(4))
|
||||
s.IncrCounterWithLabels([]string{"counter_labels", "me"}, float32(5), []Label{{"a", "label"}})
|
||||
s.AddSample([]string{"sample", "slow thingy"}, float32(6))
|
||||
s.AddSampleWithLabels([]string{"sample_labels", "slow thingy"}, float32(7), []Label{{"a", "label"}})
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
|
||||
Ссылка в новой задаче
Block a user