diff --git a/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go b/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go index c41c0cf5f1..192ba49c0d 100644 --- a/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go +++ b/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go @@ -455,6 +455,11 @@ type apiResponse struct { Error string `json:"error"` } +func apiError(code int) bool { + // These are the codes that Prometheus sends when it returns an error. + return code == statusAPIError || code == http.StatusBadRequest +} + func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) { resp, body, err := c.Client.Do(ctx, req) if err != nil { @@ -463,7 +468,7 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [ code := resp.StatusCode - if code/100 != 2 && code != statusAPIError { + if code/100 != 2 && !apiError(code) { return resp, body, &Error{ Type: ErrBadResponse, Msg: fmt.Sprintf("bad response code %d", resp.StatusCode), @@ -479,14 +484,14 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [ } } - if (code == statusAPIError) != (result.Status == "error") { + if apiError(code) != (result.Status == "error") { err = &Error{ Type: ErrBadResponse, Msg: "inconsistent body for response code", } } - if code == statusAPIError && result.Status == "error" { + if apiError(code) && result.Status == "error" { err = &Error{ Type: result.ErrorType, Msg: result.Error, diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go index 096454af91..0440bd1206 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go @@ -17,8 +17,12 @@ type goCollector struct { metrics memStatsMetrics } -// NewGoCollector returns a collector which exports metrics about the current -// go process. +// NewGoCollector returns a collector which exports metrics about the current Go +// process. This includes memory stats. To collect those, runtime.ReadMemStats +// is called. This causes a stop-the-world, which is very short with Go1.9+ +// (~25µs). However, with older Go versions, the stop-the-world duration depends +// on the heap size and can be quite significant (~1.7 ms/GiB as per +// https://go-review.googlesource.com/c/go/+/34937). func NewGoCollector() Collector { return &goCollector{ goroutinesDesc: NewDesc( @@ -265,7 +269,7 @@ func (c *goCollector) Collect(ch chan<- Metric) { quantiles[float64(idx+1)/float64(len(stats.PauseQuantiles)-1)] = pq.Seconds() } quantiles[0.0] = stats.PauseQuantiles[0].Seconds() - ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), float64(stats.PauseTotal.Seconds()), quantiles) + ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles) ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/http.go b/vendor/github.com/prometheus/client_golang/prometheus/http.go index dd0f8197f9..4d08154b23 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/http.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/http.go @@ -115,7 +115,7 @@ func decorateWriter(request *http.Request, writer io.Writer) (io.Writer, string) header := request.Header.Get(acceptEncodingHeader) parts := strings.Split(header, ",") for _, part := range parts { - part := strings.TrimSpace(part) + part = strings.TrimSpace(part) if part == "gzip" || strings.HasPrefix(part, "gzip;") { return gzip.NewWriter(writer), "gzip" } @@ -139,16 +139,6 @@ var now nower = nowFunc(func() time.Time { return time.Now() }) -func nowSeries(t ...time.Time) nower { - return nowFunc(func() time.Time { - defer func() { - t = t[1:] - }() - - return t[0] - }) -} - // InstrumentHandler wraps the given HTTP handler for instrumentation. It // registers four metric collectors (if not already done) and reports HTTP // metrics to the (newly or already) registered collectors: http_requests_total @@ -352,10 +342,9 @@ func computeApproximateRequestSize(r *http.Request) <-chan int { type responseWriterDelegator struct { http.ResponseWriter - handler, method string - status int - written int64 - wroteHeader bool + status int + written int64 + wroteHeader bool } func (r *responseWriterDelegator) WriteHeader(code int) { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go index 6213ee8127..76035bca54 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/metric.go @@ -127,20 +127,6 @@ func (s LabelPairSorter) Less(i, j int) bool { return s[i].GetName() < s[j].GetName() } -type hashSorter []uint64 - -func (s hashSorter) Len() int { - return len(s) -} - -func (s hashSorter) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s hashSorter) Less(i, j int) bool { - return s[i] < s[j] -} - type invalidMetric struct { desc *Desc err error diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go index 32ac74a7f7..b80adc6e3d 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go @@ -16,7 +16,6 @@ package prometheus import "github.com/prometheus/procfs" type processCollector struct { - pid int collectFn func(chan<- Metric) pidFn func() (int, error) cpuTotal *Desc diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go index 8dc2603558..01357374fe 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go @@ -302,7 +302,7 @@ func decorateWriter(request *http.Request, writer io.Writer, compressionDisabled header := request.Header.Get(acceptEncodingHeader) parts := strings.Split(header, ",") for _, part := range parts { - part := strings.TrimSpace(part) + part = strings.TrimSpace(part) if part == "gzip" || strings.HasPrefix(part, "gzip;") { return gzip.NewWriter(writer), "gzip" } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go index bee3703640..fdb7badf73 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/registry.go @@ -38,12 +38,13 @@ const ( // Registerer and Gatherer interface a number of convenience functions in this // package act on. Initially, both variables point to the same Registry, which // has a process collector (currently on Linux only, see NewProcessCollector) -// and a Go collector (see NewGoCollector) already registered. This approach to -// keep default instances as global state mirrors the approach of other packages -// in the Go standard library. Note that there are caveats. Change the variables -// with caution and only if you understand the consequences. Users who want to -// avoid global state altogether should not use the convenience functions and -// act on custom instances instead. +// and a Go collector (see NewGoCollector, in particular the note about +// stop-the-world implication with Go versions older than 1.9) already +// registered. This approach to keep default instances as global state mirrors +// the approach of other packages in the Go standard library. Note that there +// are caveats. Change the variables with caution and only if you understand the +// consequences. Users who want to avoid global state altogether should not use +// the convenience functions and act on custom instances instead. var ( defaultRegistry = NewRegistry() DefaultRegisterer Registerer = defaultRegistry @@ -125,15 +126,23 @@ type Registerer interface { type Gatherer interface { // Gather calls the Collect method of the registered Collectors and then // gathers the collected metrics into a lexicographically sorted slice - // of MetricFamily protobufs. Even if an error occurs, Gather attempts - // to gather as many metrics as possible. Hence, if a non-nil error is - // returned, the returned MetricFamily slice could be nil (in case of a - // fatal error that prevented any meaningful metric collection) or - // contain a number of MetricFamily protobufs, some of which might be - // incomplete, and some might be missing altogether. The returned error - // (which might be a MultiError) explains the details. In scenarios - // where complete collection is critical, the returned MetricFamily - // protobufs should be disregarded if the returned error is non-nil. + // of uniquely named MetricFamily protobufs. Gather ensures that the + // returned slice is valid and self-consistent so that it can be used + // for valid exposition. As an exception to the strict consistency + // requirements described for metric.Desc, Gather will tolerate + // different sets of label names for metrics of the same metric family. + // + // Even if an error occurs, Gather attempts to gather as many metrics as + // possible. Hence, if a non-nil error is returned, the returned + // MetricFamily slice could be nil (in case of a fatal error that + // prevented any meaningful metric collection) or contain a number of + // MetricFamily protobufs, some of which might be incomplete, and some + // might be missing altogether. The returned error (which might be a + // MultiError) explains the details. Note that this is mostly useful for + // debugging purposes. If the gathered protobufs are to be used for + // exposition in actual monitoring, it is almost always better to not + // expose an incomplete result and instead disregard the returned + // MetricFamily protobufs in case the returned error is non-nil. Gather() ([]*dto.MetricFamily, error) } @@ -369,7 +378,6 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { var ( metricChan = make(chan Metric, capMetricChan) metricHashes = map[uint64]struct{}{} - dimHashes = map[string]uint64{} wg sync.WaitGroup errs MultiError // The collected errors to return in the end. registeredDescIDs map[uint64]struct{} // Only used for pedantic checks @@ -432,19 +440,19 @@ collectLoop: } errs.Append(processMetric( metric, metricFamiliesByName, - metricHashes, dimHashes, + metricHashes, registeredDescIDs, )) default: if goroutineBudget <= 0 || len(collectors) == 0 { - // All collectors are aleady being worked on or + // All collectors are already being worked on or // we have already as many goroutines started as // there are collectors. Just process metrics // from now on. for metric := range metricChan { errs.Append(processMetric( metric, metricFamiliesByName, - metricHashes, dimHashes, + metricHashes, registeredDescIDs, )) } @@ -464,7 +472,6 @@ func processMetric( metric Metric, metricFamiliesByName map[string]*dto.MetricFamily, metricHashes map[uint64]struct{}, - dimHashes map[string]uint64, registeredDescIDs map[uint64]struct{}, ) error { desc := metric.Desc() @@ -541,7 +548,7 @@ func processMetric( } metricFamiliesByName[desc.fqName] = metricFamily } - if err := checkMetricConsistency(metricFamily, dtoMetric, metricHashes, dimHashes); err != nil { + if err := checkMetricConsistency(metricFamily, dtoMetric, metricHashes); err != nil { return err } if registeredDescIDs != nil { @@ -583,7 +590,6 @@ func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) { var ( metricFamiliesByName = map[string]*dto.MetricFamily{} metricHashes = map[uint64]struct{}{} - dimHashes = map[string]uint64{} errs MultiError // The collected errors to return in the end. ) @@ -623,7 +629,7 @@ func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) { metricFamiliesByName[mf.GetName()] = existingMF } for _, m := range mf.Metric { - if err := checkMetricConsistency(existingMF, m, metricHashes, dimHashes); err != nil { + if err := checkMetricConsistency(existingMF, m, metricHashes); err != nil { errs = append(errs, err) continue } @@ -700,18 +706,13 @@ func normalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) } // checkMetricConsistency checks if the provided Metric is consistent with the -// provided MetricFamily. It also hashed the Metric labels and the MetricFamily +// provided MetricFamily. It also hashes the Metric labels and the MetricFamily // name. If the resulting hash is already in the provided metricHashes, an error -// is returned. If not, it is added to metricHashes. The provided dimHashes maps -// MetricFamily names to their dimHash (hashed sorted label names). If dimHashes -// doesn't yet contain a hash for the provided MetricFamily, it is -// added. Otherwise, an error is returned if the existing dimHashes in not equal -// the calculated dimHash. +// is returned. If not, it is added to metricHashes. func checkMetricConsistency( metricFamily *dto.MetricFamily, dtoMetric *dto.Metric, metricHashes map[uint64]struct{}, - dimHashes map[string]uint64, ) error { // Type consistency with metric family. if metricFamily.GetType() == dto.MetricType_GAUGE && dtoMetric.Gauge == nil || @@ -726,24 +727,23 @@ func checkMetricConsistency( } for _, labelPair := range dtoMetric.GetLabel() { - if !utf8.ValidString(*labelPair.Value) { - return fmt.Errorf("collected metric's label %s is not utf8: %#v", *labelPair.Name, *labelPair.Value) + if !utf8.ValidString(labelPair.GetValue()) { + return fmt.Errorf("collected metric's label %s is not utf8: %#v", labelPair.GetName(), labelPair.GetValue()) } } - // Is the metric unique (i.e. no other metric with the same name and the same label values)? + // Is the metric unique (i.e. no other metric with the same name and the same labels)? h := hashNew() h = hashAdd(h, metricFamily.GetName()) h = hashAddByte(h, separatorByte) - dh := hashNew() // Make sure label pairs are sorted. We depend on it for the consistency // check. sort.Sort(LabelPairSorter(dtoMetric.Label)) for _, lp := range dtoMetric.Label { + h = hashAdd(h, lp.GetName()) + h = hashAddByte(h, separatorByte) h = hashAdd(h, lp.GetValue()) h = hashAddByte(h, separatorByte) - dh = hashAdd(dh, lp.GetName()) - dh = hashAddByte(dh, separatorByte) } if _, exists := metricHashes[h]; exists { return fmt.Errorf( @@ -751,16 +751,6 @@ func checkMetricConsistency( metricFamily.GetName(), dtoMetric, ) } - if dimHash, ok := dimHashes[metricFamily.GetName()]; ok { - if dimHash != dh { - return fmt.Errorf( - "collected metric %s %s has label dimensions inconsistent with previously collected metrics in the same metric family", - metricFamily.GetName(), dtoMetric, - ) - } - } else { - dimHashes[metricFamily.GetName()] = dh - } metricHashes[h] = struct{}{} return nil } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go index 543b57c27e..9fb7eab061 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/value.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/value.go @@ -152,9 +152,7 @@ func makeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { Value: proto.String(labelValues[i]), }) } - for _, lp := range desc.constLabelPairs { - labelPairs = append(labelPairs, lp) - } + labelPairs = append(labelPairs, desc.constLabelPairs...) sort.Sort(LabelPairSorter(labelPairs)) return labelPairs } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go index cea1582499..14ed9e856d 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/vec.go @@ -277,6 +277,9 @@ func (m *metricMap) deleteByHashWithLabelValues( func (m *metricMap) deleteByHashWithLabels( h uint64, labels Labels, curry []curriedLabelValue, ) bool { + m.mtx.Lock() + defer m.mtx.Unlock() + metrics, ok := m.metrics[h] if !ok { return false diff --git a/vendor/vendor.json b/vendor/vendor.json index b73117ef23..503e0b4496 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -738,26 +738,26 @@ { "checksumSHA1": "4VppKBbzCSmoFfQxGNUm0TYiFCA=", "path": "github.com/prometheus/client_golang/api", - "revision": "82f5ff156b29e276022b1a958f7d385870fb9814", - "revisionTime": "2018-04-16T23:38:56Z" + "revision": "faf4ec335fe01ae5a6a0eaa34a5a9333bfbd1a30", + "revisionTime": "2018-06-07T12:36:07Z" }, { - "checksumSHA1": "b+vg1vscoxR9FbKlKBR+2/HmWfA=", + "checksumSHA1": "83pGB3cRG5uqx9O5d+7MCB+TFT4=", "path": "github.com/prometheus/client_golang/api/prometheus/v1", - "revision": "82f5ff156b29e276022b1a958f7d385870fb9814", - "revisionTime": "2018-04-16T23:38:56Z" + "revision": "faf4ec335fe01ae5a6a0eaa34a5a9333bfbd1a30", + "revisionTime": "2018-06-07T12:36:07Z" }, { - "checksumSHA1": "I87tkF1e/hrl4d/XIKFfkPRq1ww=", + "checksumSHA1": "WVgL9pNO2RZCCcaXfSYSNEPgtCo=", "path": "github.com/prometheus/client_golang/prometheus", - "revision": "f504d69affe11ec1ccb2e5948127f86878c9fd57", - "revisionTime": "2018-03-28T13:04:30Z" + "revision": "faf4ec335fe01ae5a6a0eaa34a5a9333bfbd1a30", + "revisionTime": "2018-06-07T12:36:07Z" }, { - "checksumSHA1": "BM771aKU6hC+5rap48aqvMXczII=", + "checksumSHA1": "MYqKV5uVTfCxP9zBug7naBQ1vr8=", "path": "github.com/prometheus/client_golang/prometheus/promhttp", - "revision": "f504d69affe11ec1ccb2e5948127f86878c9fd57", - "revisionTime": "2018-03-28T13:04:30Z" + "revision": "faf4ec335fe01ae5a6a0eaa34a5a9333bfbd1a30", + "revisionTime": "2018-06-07T12:36:07Z" }, { "checksumSHA1": "DvwvOlPNAgRntBzt3b3OSRMS2N4=",