diff --git a/command/agent/metrics_endpoint_test.go b/command/agent/metrics_endpoint_test.go index 3d8d3a1db1f..d1c65d0cd8b 100644 --- a/command/agent/metrics_endpoint_test.go +++ b/command/agent/metrics_endpoint_test.go @@ -3,11 +3,16 @@ package agent import ( "net/http" "net/http/httptest" + "strings" "testing" + "time" - metrics "github.com/armon/go-metrics" + "github.com/armon/go-metrics" + "github.com/hashicorp/nomad/nomad/mock" + "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestHTTP_MetricsWithIllegalMethod(t *testing.T) { @@ -56,3 +61,67 @@ func TestHTTP_Metrics(t *testing.T) { }) }) } + +// When emitting metrics, the client should use the local copy of the allocs with +// updated task states (not the copy submitted by the server). +func TestHTTP_FreshClientAllocMetrics(t *testing.T) { + t.Parallel() + require := require.New(t) + numTasks := 10 + + httpTest(t, func(c *Config) { + c.Telemetry.PublishAllocationMetrics = true + c.Telemetry.PublishNodeMetrics = true + c.Telemetry.BackwardsCompatibleMetrics = false + c.Telemetry.DisableTaggedMetrics = false + }, func(s *TestAgent) { + // Create the job, wait for it to finish + job := mock.BatchJob() + job.TaskGroups[0].Count = numTasks + testutil.RegisterJob(t, s.RPC, job) + testutil.WaitForResult(func() (bool, error) { + time.Sleep(200 * time.Millisecond) + args := &structs.JobSpecificRequest{} + args.JobID = job.ID + args.QueryOptions.Region = "global" + var resp structs.SingleJobResponse + err := s.RPC("Job.GetJob", args, &resp) + return err == nil && resp.Job.Status == "dead", err + }, func(err error) { + require.Fail("timed-out waiting for job to complete") + }) + + // wait for metrics to converge + var pending, running, terminal float32 = -1.0, -1.0, -1.0 + testutil.WaitForResultRetries(100, func() (bool, error) { + time.Sleep(100 * time.Millisecond) + req, err := http.NewRequest("GET", "/v1/metrics", nil) + require.NoError(err) + respW := httptest.NewRecorder() + + obj, err := s.Server.MetricsRequest(respW, req) + if err != nil { + return false, err + } + + metrics := obj.(metrics.MetricsSummary) + for _, g := range metrics.Gauges { + if strings.HasSuffix(g.Name, "client.allocations.pending") { + pending = g.Value + } + if strings.HasSuffix(g.Name, "client.allocations.running") { + running = g.Value + } + if strings.HasSuffix(g.Name, "client.allocations.terminal") { + terminal = g.Value + } + } + // client alloc metrics should reflect that there is numTasks terminal allocs and no other allocs + return pending == float32(0) && running == float32(0) && + terminal == float32(numTasks), nil + }, func(err error) { + require.Fail("timed out waiting for metrics to converge", + "pending: %v, running: %v, terminal: %v", pending, running, terminal) + }) + }) +} diff --git a/vendor/github.com/armon/go-metrics/README.md b/vendor/github.com/armon/go-metrics/README.md index a7399cddffa..aa73348c08d 100644 --- a/vendor/github.com/armon/go-metrics/README.md +++ b/vendor/github.com/armon/go-metrics/README.md @@ -7,7 +7,7 @@ expose application metrics, and profile runtime performance in a flexible manner Current API: [![GoDoc](https://godoc.org/github.com/armon/go-metrics?status.svg)](https://godoc.org/github.com/armon/go-metrics) Sinks -===== +----- The `metrics` package makes use of a `MetricSink` interface to support delivery to any type of backend. Currently the following sinks are provided: @@ -23,8 +23,26 @@ In addition to the sinks, the `InmemSignal` can be used to catch a signal, and dump a formatted output of recent metrics. For example, when a process gets a SIGUSR1, it can dump to stderr recent performance metrics for debugging. +Labels +------ + +Most metrics do have an equivalent ending with `WithLabels`, such methods +allow to push metrics with labels and use some features of underlying Sinks +(ex: translated into Prometheus labels). + +Since some of these labels may increase greatly cardinality of metrics, the +library allow to filter labels using a blacklist/whitelist filtering system +which is global to all metrics. + +* If `Config.AllowedLabels` is not nil, then only labels specified in this value will be sent to underlying Sink, otherwise, all labels are sent by default. +* If `Config.BlockedLabels` is not nil, any label specified in this value will not be sent to underlying Sinks. + +By default, both `Config.AllowedLabels` and `Config.BlockedLabels` are nil, meaning that +no tags are filetered at all, but it allow to a user to globally block some tags with high +cardinality at application level. + Examples -======== +-------- Here is an example of using the package: @@ -70,5 +88,4 @@ When a signal comes in, output like the following will be dumped to stderr: [2014-01-28 14:57:33.04 -0800 PST][G] 'foo': 42.000 [2014-01-28 14:57:33.04 -0800 PST][P] 'bar': 30.000 [2014-01-28 14:57:33.04 -0800 PST][C] 'baz': Count: 3 Min: 1.000 Mean: 41.000 Max: 80.000 Stddev: 39.509 - [2014-01-28 14:57:33.04 -0800 PST][S] 'method.wow': Count: 3 Min: 22.000 Mean: 54.667 Max: 100.000 Stddev: 40.513 - + [2014-01-28 14:57:33.04 -0800 PST][S] 'method.wow': Count: 3 Min: 22.000 Mean: 54.667 Max: 100.000 Stddev: 40.513 \ No newline at end of file diff --git a/vendor/github.com/armon/go-metrics/go.mod b/vendor/github.com/armon/go-metrics/go.mod new file mode 100644 index 00000000000..88e1e98fbf4 --- /dev/null +++ b/vendor/github.com/armon/go-metrics/go.mod @@ -0,0 +1,16 @@ +module github.com/armon/go-metrics + +go 1.12 + +require ( + github.com/DataDog/datadog-go v2.2.0+incompatible + github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible + github.com/circonus-labs/circonusllhist v0.1.3 // indirect + github.com/hashicorp/go-immutable-radix v1.0.0 + github.com/hashicorp/go-retryablehttp v0.5.3 // indirect + github.com/pascaldekloe/goe v0.1.0 + github.com/pkg/errors v0.8.1 // indirect + github.com/prometheus/client_golang v0.9.2 + github.com/stretchr/testify v1.3.0 // indirect + github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect +) diff --git a/vendor/github.com/armon/go-metrics/go.sum b/vendor/github.com/armon/go-metrics/go.sum new file mode 100644 index 00000000000..5ffd8329aff --- /dev/null +++ b/vendor/github.com/armon/go-metrics/go.sum @@ -0,0 +1,46 @@ +github.com/DataDog/datadog-go v2.2.0+incompatible h1:V5BKkxACZLjzHjSgBbr2gvLA2Ae49yhc6CSY7MLy5k4= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/vendor/github.com/armon/go-metrics/inmem.go b/vendor/github.com/armon/go-metrics/inmem.go index 8fe1de8023c..93b0e0ad83c 100644 --- a/vendor/github.com/armon/go-metrics/inmem.go +++ b/vendor/github.com/armon/go-metrics/inmem.go @@ -232,8 +232,37 @@ func (i *InmemSink) Data() []*IntervalMetrics { i.intervalLock.RLock() defer i.intervalLock.RUnlock() - intervals := make([]*IntervalMetrics, len(i.intervals)) - copy(intervals, i.intervals) + n := len(i.intervals) + intervals := make([]*IntervalMetrics, n) + + copy(intervals[:n-1], i.intervals[:n-1]) + current := i.intervals[n-1] + + // make its own copy for current interval + intervals[n-1] = &IntervalMetrics{} + copyCurrent := intervals[n-1] + current.RLock() + *copyCurrent = *current + + copyCurrent.Gauges = make(map[string]GaugeValue, len(current.Gauges)) + for k, v := range current.Gauges { + copyCurrent.Gauges[k] = v + } + // saved values will be not change, just copy its link + copyCurrent.Points = make(map[string][]float32, len(current.Points)) + for k, v := range current.Points { + copyCurrent.Points[k] = v + } + copyCurrent.Counters = make(map[string]SampledValue, len(current.Counters)) + for k, v := range current.Counters { + copyCurrent.Counters[k] = v.deepCopy() + } + copyCurrent.Samples = make(map[string]SampledValue, len(current.Samples)) + for k, v := range current.Samples { + copyCurrent.Samples[k] = v.deepCopy() + } + current.RUnlock() + return intervals } diff --git a/vendor/github.com/armon/go-metrics/inmem_endpoint.go b/vendor/github.com/armon/go-metrics/inmem_endpoint.go index 504f1b37485..5fac958d941 100644 --- a/vendor/github.com/armon/go-metrics/inmem_endpoint.go +++ b/vendor/github.com/armon/go-metrics/inmem_endpoint.go @@ -41,6 +41,16 @@ type SampledValue struct { DisplayLabels map[string]string `json:"Labels"` } +// deepCopy allocates a new instance of AggregateSample +func (source *SampledValue) deepCopy() SampledValue { + dest := *source + if source.AggregateSample != nil { + dest.AggregateSample = &AggregateSample{} + *dest.AggregateSample = *source.AggregateSample + } + return dest +} + // 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() @@ -52,12 +62,15 @@ func (i *InmemSink) DisplayMetrics(resp http.ResponseWriter, req *http.Request) 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] + interval = data[0] default: // Show the most recent finished interval if we have one - interval = i.intervals[n-2] + interval = data[n-2] } + interval.RLock() + defer interval.RUnlock() + summary := MetricsSummary{ Timestamp: interval.Interval.Round(time.Second).UTC().String(), Gauges: make([]GaugeValue, 0, len(interval.Gauges)), diff --git a/vendor/github.com/armon/go-metrics/metrics.go b/vendor/github.com/armon/go-metrics/metrics.go index d260bd4b29e..4920d68324a 100644 --- a/vendor/github.com/armon/go-metrics/metrics.go +++ b/vendor/github.com/armon/go-metrics/metrics.go @@ -35,10 +35,11 @@ func (m *Metrics) SetGaugeWithLabels(key []string, val float32, labels []Label) key = insert(0, m.ServiceName, key) } } - if !m.allowMetric(key) { + allowed, labelsFiltered := m.allowMetric(key, labels) + if !allowed { return } - m.sink.SetGaugeWithLabels(key, val, labels) + m.sink.SetGaugeWithLabels(key, val, labelsFiltered) } func (m *Metrics) EmitKey(key []string, val float32) { @@ -48,7 +49,8 @@ func (m *Metrics) EmitKey(key []string, val float32) { if m.ServiceName != "" { key = insert(0, m.ServiceName, key) } - if !m.allowMetric(key) { + allowed, _ := m.allowMetric(key, nil) + if !allowed { return } m.sink.EmitKey(key, val) @@ -72,10 +74,11 @@ func (m *Metrics) IncrCounterWithLabels(key []string, val float32, labels []Labe key = insert(0, m.ServiceName, key) } } - if !m.allowMetric(key) { + allowed, labelsFiltered := m.allowMetric(key, labels) + if !allowed { return } - m.sink.IncrCounterWithLabels(key, val, labels) + m.sink.IncrCounterWithLabels(key, val, labelsFiltered) } func (m *Metrics) AddSample(key []string, val float32) { @@ -96,10 +99,11 @@ func (m *Metrics) AddSampleWithLabels(key []string, val float32, labels []Label) key = insert(0, m.ServiceName, key) } } - if !m.allowMetric(key) { + allowed, labelsFiltered := m.allowMetric(key, labels) + if !allowed { return } - m.sink.AddSampleWithLabels(key, val, labels) + m.sink.AddSampleWithLabels(key, val, labelsFiltered) } func (m *Metrics) MeasureSince(key []string, start time.Time) { @@ -120,23 +124,45 @@ func (m *Metrics) MeasureSinceWithLabels(key []string, start time.Time, labels [ key = insert(0, m.ServiceName, key) } } - if !m.allowMetric(key) { + allowed, labelsFiltered := m.allowMetric(key, labels) + if !allowed { return } now := time.Now() elapsed := now.Sub(start) msec := float32(elapsed.Nanoseconds()) / float32(m.TimerGranularity) - m.sink.AddSampleWithLabels(key, msec, labels) + m.sink.AddSampleWithLabels(key, msec, labelsFiltered) } // UpdateFilter overwrites the existing filter with the given rules. func (m *Metrics) UpdateFilter(allow, block []string) { + m.UpdateFilterAndLabels(allow, block, m.AllowedLabels, m.BlockedLabels) +} + +// UpdateFilterAndLabels overwrites the existing filter with the given rules. +func (m *Metrics) UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) { m.filterLock.Lock() defer m.filterLock.Unlock() m.AllowedPrefixes = allow m.BlockedPrefixes = block + if allowedLabels == nil { + // Having a white list means we take only elements from it + m.allowedLabels = nil + } else { + m.allowedLabels = make(map[string]bool) + for _, v := range allowedLabels { + m.allowedLabels[v] = true + } + } + m.blockedLabels = make(map[string]bool) + for _, v := range blockedLabels { + m.blockedLabels[v] = true + } + m.AllowedLabels = allowedLabels + m.BlockedLabels = blockedLabels + m.filter = iradix.New() for _, prefix := range m.AllowedPrefixes { m.filter, _, _ = m.filter.Insert([]byte(prefix), true) @@ -146,20 +172,56 @@ func (m *Metrics) UpdateFilter(allow, block []string) { } } +// labelIsAllowed return true if a should be included in metric +// the caller should lock m.filterLock while calling this method +func (m *Metrics) labelIsAllowed(label *Label) bool { + labelName := (*label).Name + if m.blockedLabels != nil { + _, ok := m.blockedLabels[labelName] + if ok { + // If present, let's remove this label + return false + } + } + if m.allowedLabels != nil { + _, ok := m.allowedLabels[labelName] + return ok + } + // Allow by default + return true +} + +// filterLabels return only allowed labels +// the caller should lock m.filterLock while calling this method +func (m *Metrics) filterLabels(labels []Label) []Label { + if labels == nil { + return nil + } + toReturn := []Label{} + for _, label := range labels { + if m.labelIsAllowed(&label) { + toReturn = append(toReturn, label) + } + } + return toReturn +} + // Returns whether the metric should be allowed based on configured prefix filters -func (m *Metrics) allowMetric(key []string) bool { +// Also return the applicable labels +func (m *Metrics) allowMetric(key []string, labels []Label) (bool, []Label) { m.filterLock.RLock() defer m.filterLock.RUnlock() if m.filter == nil || m.filter.Len() == 0 { - return m.Config.FilterDefault + return m.Config.FilterDefault, m.filterLabels(labels) } _, allowed, ok := m.filter.Root().LongestPrefix([]byte(strings.Join(key, "."))) if !ok { - return m.Config.FilterDefault + return m.Config.FilterDefault, m.filterLabels(labels) } - return allowed.(bool) + + return allowed.(bool), m.filterLabels(labels) } // Periodically collects runtime stats to publish diff --git a/vendor/github.com/armon/go-metrics/prometheus/prometheus.go b/vendor/github.com/armon/go-metrics/prometheus/prometheus.go index a5b27d6d3e7..9b339be3aaa 100644 --- a/vendor/github.com/armon/go-metrics/prometheus/prometheus.go +++ b/vendor/github.com/armon/go-metrics/prometheus/prometheus.go @@ -1,4 +1,5 @@ // +build go1.3 + package prometheus import ( @@ -100,7 +101,7 @@ func (p *PrometheusSink) Collect(c chan<- prometheus.Metric) { } } -var forbiddenChars = regexp.MustCompile("[ .=\\-]") +var forbiddenChars = regexp.MustCompile("[ .=\\-/]") func (p *PrometheusSink) flattenKey(parts []string, labels []metrics.Label) (string, string) { key := strings.Join(parts, "_") diff --git a/vendor/github.com/armon/go-metrics/start.go b/vendor/github.com/armon/go-metrics/start.go index 46f0c2eb2db..32a28c48378 100644 --- a/vendor/github.com/armon/go-metrics/start.go +++ b/vendor/github.com/armon/go-metrics/start.go @@ -11,7 +11,7 @@ import ( // Config is used to configure metrics settings type Config struct { - ServiceName string // Prefixed with keys to seperate services + ServiceName string // Prefixed with keys to separate 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 @@ -23,6 +23,8 @@ type Config struct { 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 + AllowedLabels []string // A list of metric labels to allow, with '.' as the separator + BlockedLabels []string // A list of metric labels to block, with '.' as the separator FilterDefault bool // Whether to allow metrics by default } @@ -30,10 +32,12 @@ type Config struct { // be used to emit type Metrics struct { Config - lastNumGC uint32 - sink MetricSink - filter *iradix.Tree - filterLock sync.RWMutex + lastNumGC uint32 + sink MetricSink + filter *iradix.Tree + allowedLabels map[string]bool + blockedLabels map[string]bool + filterLock sync.RWMutex // Lock filters and allowedLabels/blockedLabels access } // Shared global metrics instance @@ -68,7 +72,7 @@ func New(conf *Config, sink MetricSink) (*Metrics, error) { met := &Metrics{} met.Config = *conf met.sink = sink - met.UpdateFilter(conf.AllowedPrefixes, conf.BlockedPrefixes) + met.UpdateFilterAndLabels(conf.AllowedPrefixes, conf.BlockedPrefixes, conf.AllowedLabels, conf.BlockedLabels) // Start the runtime collector if conf.EnableRuntimeMetrics { @@ -127,3 +131,11 @@ func MeasureSinceWithLabels(key []string, start time.Time, labels []Label) { func UpdateFilter(allow, block []string) { globalMetrics.Load().(*Metrics).UpdateFilter(allow, block) } + +// UpdateFilterAndLabels set allow/block prefixes of metrics while allowedLabels +// and blockedLabels - when not nil - allow filtering of labels in order to +// block/allow globally labels (especially useful when having large number of +// values for a given label). See README.md for more information about usage. +func UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) { + globalMetrics.Load().(*Metrics).UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels) +} diff --git a/vendor/github.com/hashicorp/memberlist/state.go b/vendor/github.com/hashicorp/memberlist/state.go index 6caded31358..869ce8c0708 100644 --- a/vendor/github.com/hashicorp/memberlist/state.go +++ b/vendor/github.com/hashicorp/memberlist/state.go @@ -953,7 +953,7 @@ func (m *Memberlist) aliveNode(a *alive, notify chan struct{}, bootstrap bool) { // possible for the following situation to happen: // 1) Start with configuration C, join cluster // 2) Hard fail / Kill / Shutdown - // 3) Restart with configuration C', join cluster + // 3) Retarttart with configuration C', join cluster // // In this case, other nodes and the local node see the same incarnation, // but the values may not be the same. For this reason, we always diff --git a/vendor/vendor.json b/vendor/vendor.json index ebd689d5de6..0345b4334c5 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -22,10 +22,10 @@ {"path":"github.com/appc/spec/schema/types","checksumSHA1":"kYXCle7Ikc8WqiMs7NXz99bUWqo=","revision":"cbe99b7160b1397bf89f9c8bb1418f69c9424049","revisionTime":"2017-09-19T09:55:19Z"}, {"path":"github.com/appc/spec/schema/types/resource","checksumSHA1":"VgPsPj5PH7LKXMa3ZLe5/+Avydo=","revision":"cbe99b7160b1397bf89f9c8bb1418f69c9424049","revisionTime":"2017-09-19T09:55:19Z"}, {"path":"github.com/armon/circbuf","checksumSHA1":"l0iFqayYAaEip6Olaq3/LCOa/Sg=","revision":"bbbad097214e2918d8543d5201d12bfd7bca254d"}, - {"path":"github.com/armon/go-metrics","checksumSHA1":"xp/2s4XclLL17DThGBI7jXZ4Crs=","revision":"6c3acc97c61d04290a8ba2e54640151f54c1546a","revisionTime":"2017-11-16T18:41:20Z"}, - {"path":"github.com/armon/go-metrics/circonus","checksumSHA1":"xCsGGM9TKBogZDfSN536KtQdLko=","revision":"6c3acc97c61d04290a8ba2e54640151f54c1546a","revisionTime":"2017-11-16T18:41:20Z"}, - {"path":"github.com/armon/go-metrics/datadog","checksumSHA1":"Dt0n1sSivvvdZQdzc4Hu/yOG+T0=","revision":"6c3acc97c61d04290a8ba2e54640151f54c1546a","revisionTime":"2017-11-16T18:41:20Z"}, - {"path":"github.com/armon/go-metrics/prometheus","checksumSHA1":"XfPPXw55zKziOWnZbkEGEJ96O9c=","revision":"6c3acc97c61d04290a8ba2e54640151f54c1546a","revisionTime":"2017-11-16T18:41:20Z"}, + {"path":"github.com/armon/go-metrics","checksumSHA1":"gaT7FBF9uH5TY4lCo96ySrYXjek=","revision":"c1e99089638e6f1f57fe71461f99f9d00a43ccf1","revisionTime":"2019-04-30T14:02:02Z"}, + {"path":"github.com/armon/go-metrics/circonus","checksumSHA1":"xCsGGM9TKBogZDfSN536KtQdLko=","revision":"c1e99089638e6f1f57fe71461f99f9d00a43ccf1","revisionTime":"2019-04-30T14:02:02Z"}, + {"path":"github.com/armon/go-metrics/datadog","checksumSHA1":"Dt0n1sSivvvdZQdzc4Hu/yOG+T0=","revision":"c1e99089638e6f1f57fe71461f99f9d00a43ccf1","revisionTime":"2019-04-30T14:02:02Z"}, + {"path":"github.com/armon/go-metrics/prometheus","checksumSHA1":"vxr0X6/jCQ4FkMxdhzUaBEWrFGA=","revision":"c1e99089638e6f1f57fe71461f99f9d00a43ccf1","revisionTime":"2019-04-30T14:02:02Z"}, {"path":"github.com/armon/go-radix","checksumSHA1":"gNO0JNpLzYOdInGeq7HqMZUzx9M=","revision":"4239b77079c7b5d1243b7b4736304ce8ddb6f0f2","revisionTime":"2016-01-15T23:47:25Z"}, {"path":"github.com/aws/aws-sdk-go/aws","checksumSHA1":"gMMx/JVSQVE4KHKoJQC7cqjTIZc=","comment":"v1.0.6-2-g80dd495","revision":"80dd4951fdb3f711d31843b8d87871130ef2df67"}, {"path":"github.com/aws/aws-sdk-go/aws/awserr","checksumSHA1":"OlpdlsDV2Qv50MuHlpH9heaHjQc=","comment":"v1.0.6-2-g80dd495","revision":"80dd4951fdb3f711d31843b8d87871130ef2df67"},