From 586178b4ab42bbe57811049a16f1aae5d164feb8 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Fri, 13 Mar 2020 00:10:32 +0100 Subject: [PATCH 01/74] Fix promhttp error handling Essentially, just don't try to set a status code and send any error message in the body once metrics gathering has succeeded. At that point, the most likely reason for errors is anyway that the client has disconnected, in which sending an error is moot. The other possible reason for an error is a problem during metrics encoding. This is unlikely to happen (it's a coding error here in client_golang in any case), and if it is happening, the odds are we have already sent something to the ResponseWriter, which means we cannot set a status code anymore. The doc comment for HTTPErrorOnError now describes these circumstances explicitly and recommends to set a logger to report that kind of error. This should fix the reason for the infamous `superfluous response.WriteHeader call` message. Signed-off-by: beorn7 --- prometheus/promhttp/delegator.go | 10 +++++++--- prometheus/promhttp/http.go | 27 +++++++++++++-------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/prometheus/promhttp/delegator.go b/prometheus/promhttp/delegator.go index d1354b1..5070e72 100644 --- a/prometheus/promhttp/delegator.go +++ b/prometheus/promhttp/delegator.go @@ -53,12 +53,16 @@ func (r *responseWriterDelegator) Written() int64 { } func (r *responseWriterDelegator) WriteHeader(code int) { + if r.observeWriteHeader != nil && !r.wroteHeader { + // Only call observeWriteHeader for the 1st time. It's a bug if + // WriteHeader is called more than once, but we want to protect + // against it here. Note that we still delegate the WriteHeader + // to the original ResponseWriter to not mask the bug from it. + r.observeWriteHeader(code) + } r.status = code r.wroteHeader = true r.ResponseWriter.WriteHeader(code) - if r.observeWriteHeader != nil { - r.observeWriteHeader(code) - } } func (r *responseWriterDelegator) Write(b []byte) (int, error) { diff --git a/prometheus/promhttp/http.go b/prometheus/promhttp/http.go index b0ee467..5e1c454 100644 --- a/prometheus/promhttp/http.go +++ b/prometheus/promhttp/http.go @@ -167,15 +167,12 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { enc := expfmt.NewEncoder(w, contentType) - var lastErr error - // handleError handles the error according to opts.ErrorHandling // and returns true if we have to abort after the handling. handleError := func(err error) bool { if err == nil { return false } - lastErr = err if opts.ErrorLog != nil { opts.ErrorLog.Println("error encoding and sending metric family:", err) } @@ -184,7 +181,10 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { case PanicOnError: panic(err) case HTTPErrorOnError: - httpError(rsp, err) + // We cannot really send an HTTP error at this + // point because we most likely have written + // something to rsp already. But at least we can + // stop sending. return true } // Do nothing in all other cases, including ContinueOnError. @@ -202,10 +202,6 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { return } } - - if lastErr != nil { - httpError(rsp, lastErr) - } }) if opts.Timeout <= 0 { @@ -276,7 +272,12 @@ type HandlerErrorHandling int // errors are encountered. const ( // Serve an HTTP status code 500 upon the first error - // encountered. Report the error message in the body. + // encountered. Report the error message in the body. Note that HTTP + // errors cannot be served anymore once the beginning of a regular + // payload has been sent. Thus, in the (unlikely) case that encoding the + // payload into the negotiated wire format fails, serving the response + // will simply be aborted. Set an ErrorLog in HandlerOpts to detect + // those errors. HTTPErrorOnError HandlerErrorHandling = iota // Ignore errors and try to serve as many metrics as possible. However, // if no metrics can be served, serve an HTTP status code 500 and the @@ -365,11 +366,9 @@ func gzipAccepted(header http.Header) bool { } // httpError removes any content-encoding header and then calls http.Error with -// the provided error and http.StatusInternalServerErrer. Error contents is -// supposed to be uncompressed plain text. However, same as with a plain -// http.Error, any header settings will be void if the header has already been -// sent. The error message will still be written to the writer, but it will -// probably be of limited use. +// the provided error and http.StatusInternalServerError. Error contents is +// supposed to be uncompressed plain text. Same as with a plain http.Error, this +// must not be called if the header or any payload has already been sent. func httpError(rsp http.ResponseWriter, err error) { rsp.Header().Del(contentEncodingHeader) http.Error( From bb96a66cf61df1f7836542c136b6f54fdb2ed4ff Mon Sep 17 00:00:00 2001 From: beorn7 Date: Fri, 13 Mar 2020 23:10:05 +0100 Subject: [PATCH 02/74] Cut v1.5.1 Signed-off-by: beorn7 --- CHANGELOG.md | 4 ++++ VERSION | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e657b96..bd44c4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.1 / 2020-03-14 + +* [BUGFIX] promhttp: Remove another superfluous `WriteHeader` call. + ## 1.5.0 / 2020-03-03 * [FEATURE] promauto: Add a factory to allow automatic registration with a local registry. #713 diff --git a/VERSION b/VERSION index bc80560..26ca594 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.0 +1.5.1 From 8f87c69651483517c37e908b94afa0fd28730c91 Mon Sep 17 00:00:00 2001 From: huanggze Date: Thu, 2 Apr 2020 14:36:37 +0800 Subject: [PATCH 03/74] Improve API error handling Signed-off-by: huanggze --- api/prometheus/v1/api.go | 4 ++-- api/prometheus/v1/api_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 61f7fb4..fa35ddd 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -905,14 +905,14 @@ func (h *apiClientImpl) Do(ctx context.Context, req *http.Request) (*http.Respon } } - if apiError(code) != (result.Status == "error") { + if apiError(code) && result.Status == "success" { err = &Error{ Type: ErrBadResponse, Msg: "inconsistent body for response code", } } - if apiError(code) && result.Status == "error" { + if result.Status == "error" { err = &Error{ Type: result.ErrorType, Msg: result.Error, diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 79b00a9..b36c380 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -1095,8 +1095,8 @@ func TestAPIClientDo(t *testing.T) { Error: "timed out", }, expectedErr: &Error{ - Type: ErrBadResponse, - Msg: "inconsistent body for response code", + Type: ErrTimeout, + Msg: "timed out", }, }, { @@ -1109,8 +1109,8 @@ func TestAPIClientDo(t *testing.T) { Warnings: []string{"a"}, }, expectedErr: &Error{ - Type: ErrBadResponse, - Msg: "inconsistent body for response code", + Type: ErrTimeout, + Msg: "timed out", }, expectedWarnings: []string{"a"}, }, From 0bb7f92c093bee1eee8936e8e1f4633e79b64fb1 Mon Sep 17 00:00:00 2001 From: cobolbaby Date: Fri, 10 Apr 2020 16:28:01 +0800 Subject: [PATCH 04/74] fix: process_resident_memory_bytes detected is incorrect in Win7 32bit Ref: https://github.com/prometheus/client_golang/issues/728 Signed-off-by: Cobolbaby --- prometheus/process_collector_windows.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/prometheus/process_collector_windows.go b/prometheus/process_collector_windows.go index e0b935d..15e6873 100644 --- a/prometheus/process_collector_windows.go +++ b/prometheus/process_collector_windows.go @@ -36,15 +36,15 @@ type processMemoryCounters struct { // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_process_memory_counters_ex _ uint32 PageFaultCount uint32 - PeakWorkingSetSize uint64 - WorkingSetSize uint64 - QuotaPeakPagedPoolUsage uint64 - QuotaPagedPoolUsage uint64 - QuotaPeakNonPagedPoolUsage uint64 - QuotaNonPagedPoolUsage uint64 - PagefileUsage uint64 - PeakPagefileUsage uint64 - PrivateUsage uint64 + PeakWorkingSetSize uint + WorkingSetSize uint + QuotaPeakPagedPoolUsage uint + QuotaPagedPoolUsage uint + QuotaPeakNonPagedPoolUsage uint + QuotaNonPagedPoolUsage uint + PagefileUsage uint + PeakPagefileUsage uint + PrivateUsage uint } func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) { From c6babafd276e1385135ae3b8644d07b908d7fbd3 Mon Sep 17 00:00:00 2001 From: cobolbaby Date: Mon, 13 Apr 2020 10:43:29 +0800 Subject: [PATCH 05/74] feat: Change processMemoryCounters struct uint declaration to uintptr Signed-off-by: cobolbaby --- prometheus/process_collector_windows.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/prometheus/process_collector_windows.go b/prometheus/process_collector_windows.go index 15e6873..f973398 100644 --- a/prometheus/process_collector_windows.go +++ b/prometheus/process_collector_windows.go @@ -33,18 +33,22 @@ var ( ) type processMemoryCounters struct { - // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_process_memory_counters_ex + // System interface description + // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-process_memory_counters_ex + + // Refer to the Golang internal implementation + // https://golang.org/src/internal/syscall/windows/psapi_windows.go _ uint32 PageFaultCount uint32 - PeakWorkingSetSize uint - WorkingSetSize uint - QuotaPeakPagedPoolUsage uint - QuotaPagedPoolUsage uint - QuotaPeakNonPagedPoolUsage uint - QuotaNonPagedPoolUsage uint - PagefileUsage uint - PeakPagefileUsage uint - PrivateUsage uint + PeakWorkingSetSize uintptr + WorkingSetSize uintptr + QuotaPeakPagedPoolUsage uintptr + QuotaPagedPoolUsage uintptr + QuotaPeakNonPagedPoolUsage uintptr + QuotaNonPagedPoolUsage uintptr + PagefileUsage uintptr + PeakPagefileUsage uintptr + PrivateUsage uintptr } func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) { From 3c5e60edc120fc05700c5ead113ea625302123e5 Mon Sep 17 00:00:00 2001 From: RainbowMango Date: Thu, 23 Apr 2020 14:09:29 +0800 Subject: [PATCH 06/74] Porting promlint from prometheus/prometheus. Signed-off-by: RainbowMango --- prometheus/testutil/promlint/promlint.go | 372 +++++++++ prometheus/testutil/promlint/promlint_test.go | 788 ++++++++++++++++++ 2 files changed, 1160 insertions(+) create mode 100644 prometheus/testutil/promlint/promlint.go create mode 100644 prometheus/testutil/promlint/promlint_test.go diff --git a/prometheus/testutil/promlint/promlint.go b/prometheus/testutil/promlint/promlint.go new file mode 100644 index 0000000..4570c60 --- /dev/null +++ b/prometheus/testutil/promlint/promlint.go @@ -0,0 +1,372 @@ +// Copyright 2017 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package promlint provides a linter for Prometheus metrics. +package promlint + +import ( + "fmt" + "io" + "regexp" + "sort" + "strings" + + dto "github.com/prometheus/client_model/go" + "github.com/prometheus/common/expfmt" +) + +// A Linter is a Prometheus metrics linter. It identifies issues with metric +// names, types, and metadata, and reports them to the caller. +type Linter struct { + r io.Reader +} + +// A Problem is an issue detected by a Linter. +type Problem struct { + // The name of the metric indicated by this Problem. + Metric string + + // A description of the issue for this Problem. + Text string +} + +// problems is a slice of Problems with a helper method to easily append +// additional Problems to the slice. +type problems []Problem + +// Add appends a new Problem to the slice for the specified metric, with +// the specified issue text. +func (p *problems) Add(mf dto.MetricFamily, text string) { + *p = append(*p, Problem{ + Metric: mf.GetName(), + Text: text, + }) +} + +// New creates a new Linter that reads an input stream of Prometheus metrics. +// Only the text exposition format is supported. +func New(r io.Reader) *Linter { + return &Linter{ + r: r, + } +} + +// Lint performs a linting pass, returning a slice of Problems indicating any +// issues found in the metrics stream. The slice is sorted by metric name +// and issue description. +func (l *Linter) Lint() ([]Problem, error) { + // TODO(mdlayher): support for protobuf exposition format? + d := expfmt.NewDecoder(l.r, expfmt.FmtText) + + var problems []Problem + + var mf dto.MetricFamily + for { + if err := d.Decode(&mf); err != nil { + if err == io.EOF { + break + } + + return nil, err + } + + problems = append(problems, lint(mf)...) + } + + // Ensure deterministic output. + sort.SliceStable(problems, func(i, j int) bool { + if problems[i].Metric == problems[j].Metric { + return problems[i].Text < problems[j].Text + } + return problems[i].Metric < problems[j].Metric + }) + + return problems, nil +} + +// lint is the entry point for linting a single metric. +func lint(mf dto.MetricFamily) []Problem { + fns := []func(mf dto.MetricFamily) []Problem{ + lintHelp, + lintMetricUnits, + lintCounter, + lintHistogramSummaryReserved, + lintMetricTypeInName, + lintReservedChars, + lintCamelCase, + lintUnitAbbreviations, + } + + var problems []Problem + for _, fn := range fns { + problems = append(problems, fn(mf)...) + } + + // TODO(mdlayher): lint rules for specific metrics types. + return problems +} + +// lintHelp detects issues related to the help text for a metric. +func lintHelp(mf dto.MetricFamily) []Problem { + var problems problems + + // Expect all metrics to have help text available. + if mf.Help == nil { + problems.Add(mf, "no help text") + } + + return problems +} + +// lintMetricUnits detects issues with metric unit names. +func lintMetricUnits(mf dto.MetricFamily) []Problem { + var problems problems + + unit, base, ok := metricUnits(*mf.Name) + if !ok { + // No known units detected. + return nil + } + + // Unit is already a base unit. + if unit == base { + return nil + } + + problems.Add(mf, fmt.Sprintf("use base unit %q instead of %q", base, unit)) + + return problems +} + +// lintCounter detects issues specific to counters, as well as patterns that should +// only be used with counters. +func lintCounter(mf dto.MetricFamily) []Problem { + var problems problems + + isCounter := mf.GetType() == dto.MetricType_COUNTER + isUntyped := mf.GetType() == dto.MetricType_UNTYPED + hasTotalSuffix := strings.HasSuffix(mf.GetName(), "_total") + + switch { + case isCounter && !hasTotalSuffix: + problems.Add(mf, `counter metrics should have "_total" suffix`) + case !isUntyped && !isCounter && hasTotalSuffix: + problems.Add(mf, `non-counter metrics should not have "_total" suffix`) + } + + return problems +} + +// lintHistogramSummaryReserved detects when other types of metrics use names or labels +// reserved for use by histograms and/or summaries. +func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem { + // These rules do not apply to untyped metrics. + t := mf.GetType() + if t == dto.MetricType_UNTYPED { + return nil + } + + var problems problems + + isHistogram := t == dto.MetricType_HISTOGRAM + isSummary := t == dto.MetricType_SUMMARY + + n := mf.GetName() + + if !isHistogram && strings.HasSuffix(n, "_bucket") { + problems.Add(mf, `non-histogram metrics should not have "_bucket" suffix`) + } + if !isHistogram && !isSummary && strings.HasSuffix(n, "_count") { + problems.Add(mf, `non-histogram and non-summary metrics should not have "_count" suffix`) + } + if !isHistogram && !isSummary && strings.HasSuffix(n, "_sum") { + problems.Add(mf, `non-histogram and non-summary metrics should not have "_sum" suffix`) + } + + for _, m := range mf.GetMetric() { + for _, l := range m.GetLabel() { + ln := l.GetName() + + if !isHistogram && ln == "le" { + problems.Add(mf, `non-histogram metrics should not have "le" label`) + } + if !isSummary && ln == "quantile" { + problems.Add(mf, `non-summary metrics should not have "quantile" label`) + } + } + } + + return problems +} + +// lintMetricTypeInName detects when metric types are included in the metric name. +func lintMetricTypeInName(mf dto.MetricFamily) []Problem { + var problems problems + n := strings.ToLower(mf.GetName()) + + for i, t := range dto.MetricType_name { + if i == int32(dto.MetricType_UNTYPED) { + continue + } + + typename := strings.ToLower(t) + if strings.Contains(n, "_"+typename+"_") || strings.HasSuffix(n, "_"+typename) { + problems.Add(mf, fmt.Sprintf(`metric name should not include type '%s'`, typename)) + } + } + return problems +} + +// lintReservedChars detects colons in metric names. +func lintReservedChars(mf dto.MetricFamily) []Problem { + var problems problems + if strings.Contains(mf.GetName(), ":") { + problems.Add(mf, "metric names should not contain ':'") + } + return problems +} + +var camelCase = regexp.MustCompile(`[a-z][A-Z]`) + +// lintCamelCase detects metric names and label names written in camelCase. +func lintCamelCase(mf dto.MetricFamily) []Problem { + var problems problems + if camelCase.FindString(mf.GetName()) != "" { + problems.Add(mf, "metric names should be written in 'snake_case' not 'camelCase'") + } + + for _, m := range mf.GetMetric() { + for _, l := range m.GetLabel() { + if camelCase.FindString(l.GetName()) != "" { + problems.Add(mf, "label names should be written in 'snake_case' not 'camelCase'") + } + } + } + return problems +} + +// lintUnitAbbreviations detects abbreviated units in the metric name. +func lintUnitAbbreviations(mf dto.MetricFamily) []Problem { + var problems problems + n := strings.ToLower(mf.GetName()) + for _, s := range unitAbbreviations { + if strings.Contains(n, "_"+s+"_") || strings.HasSuffix(n, "_"+s) { + problems.Add(mf, "metric names should not contain abbreviated units") + } + } + return problems +} + +// metricUnits attempts to detect known unit types used as part of a metric name, +// e.g. "foo_bytes_total" or "bar_baz_milligrams". +func metricUnits(m string) (unit string, base string, ok bool) { + ss := strings.Split(m, "_") + + for unit, base := range units { + // Also check for "no prefix". + for _, p := range append(unitPrefixes, "") { + for _, s := range ss { + // Attempt to explicitly match a known unit with a known prefix, + // as some words may look like "units" when matching suffix. + // + // As an example, "thermometers" should not match "meters", but + // "kilometers" should. + if s == p+unit { + return p + unit, base, true + } + } + } + } + + return "", "", false +} + +// Units and their possible prefixes recognized by this library. More can be +// added over time as needed. +var ( + // map a unit to the appropriate base unit. + units = map[string]string{ + // Base units. + "amperes": "amperes", + "bytes": "bytes", + "celsius": "celsius", // Celsius is more common in practice than Kelvin. + "grams": "grams", + "joules": "joules", + "meters": "meters", // Both American and international spelling permitted. + "metres": "metres", + "seconds": "seconds", + "volts": "volts", + + // Non base units. + // Time. + "minutes": "seconds", + "hours": "seconds", + "days": "seconds", + "weeks": "seconds", + // Temperature. + "kelvin": "celsius", + "kelvins": "celsius", + "fahrenheit": "celsius", + "rankine": "celsius", + // Length. + "inches": "meters", + "yards": "meters", + "miles": "meters", + // Bytes. + "bits": "bytes", + // Energy. + "calories": "joules", + // Mass. + "pounds": "grams", + "ounces": "grams", + } + + unitPrefixes = []string{ + "pico", + "nano", + "micro", + "milli", + "centi", + "deci", + "deca", + "hecto", + "kilo", + "kibi", + "mega", + "mibi", + "giga", + "gibi", + "tera", + "tebi", + "peta", + "pebi", + } + + // Common abbreviations that we'd like to discourage. + unitAbbreviations = []string{ + "s", + "ms", + "us", + "ns", + "sec", + "b", + "kb", + "mb", + "gb", + "tb", + "pb", + "m", + "h", + "d", + } +) diff --git a/prometheus/testutil/promlint/promlint_test.go b/prometheus/testutil/promlint/promlint_test.go new file mode 100644 index 0000000..05d793e --- /dev/null +++ b/prometheus/testutil/promlint/promlint_test.go @@ -0,0 +1,788 @@ +// Copyright 2017 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package promlint_test + +import ( + "fmt" + "reflect" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil/promlint" +) + +type test struct { + name string + in string + problems []promlint.Problem +} + +func TestLintNoHelpText(t *testing.T) { + const msg = "no help text" + + tests := []test{ + { + name: "no help", + in: ` +# TYPE go_goroutines gauge +go_goroutines 24 +`, + problems: []promlint.Problem{{ + Metric: "go_goroutines", + Text: msg, + }}, + }, + { + name: "empty help", + in: ` +# HELP go_goroutines +# TYPE go_goroutines gauge +go_goroutines 24 +`, + problems: []promlint.Problem{{ + Metric: "go_goroutines", + Text: msg, + }}, + }, + { + name: "no help and empty help", + in: ` +# HELP go_goroutines +# TYPE go_goroutines gauge +go_goroutines 24 +# TYPE go_threads gauge +go_threads 10 +`, + problems: []promlint.Problem{ + { + Metric: "go_goroutines", + Text: msg, + }, + { + Metric: "go_threads", + Text: msg, + }, + }, + }, + { + name: "OK", + in: ` +# HELP go_goroutines Number of goroutines that currently exist. +# TYPE go_goroutines gauge +go_goroutines 24 +`, + }, + } + runTests(t, tests) +} + +func TestLintMetricUnits(t *testing.T) { + tests := []struct { + name string + in string + problems []promlint.Problem + }{ + // good cases. + { + name: "amperes", + in: ` +# HELP x_amperes Test metric. +# TYPE x_amperes untyped +x_amperes 10 +`, + }, + { + name: "bytes", + in: ` +# HELP x_bytes Test metric. +# TYPE x_bytes untyped +x_bytes 10 +`, + }, + { + name: "grams", + in: ` +# HELP x_grams Test metric. +# TYPE x_grams untyped +x_grams 10 +`, + }, + { + name: "celsius", + in: ` +# HELP x_celsius Test metric. +# TYPE x_celsius untyped +x_celsius 10 +`, + }, + { + name: "meters", + in: ` +# HELP x_meters Test metric. +# TYPE x_meters untyped +x_meters 10 +`, + }, + { + name: "metres", + in: ` +# HELP x_metres Test metric. +# TYPE x_metres untyped +x_metres 10 +`, + }, + { + name: "moles", + in: ` +# HELP x_moles Test metric. +# TYPE x_moles untyped +x_moles 10 +`, + }, + { + name: "seconds", + in: ` +# HELP x_seconds Test metric. +# TYPE x_seconds untyped +x_seconds 10 +`, + }, + { + name: "joules", + in: ` +# HELP x_joules Test metric. +# TYPE x_joules untyped +x_joules 10 +`, + }, + // bad cases. + { + name: "milliamperes", + in: ` +# HELP x_milliamperes Test metric. +# TYPE x_milliamperes untyped +x_milliamperes 10 +`, + problems: []promlint.Problem{{ + Metric: "x_milliamperes", + Text: `use base unit "amperes" instead of "milliamperes"`, + }}, + }, + { + name: "gigabytes", + in: ` +# HELP x_gigabytes Test metric. +# TYPE x_gigabytes untyped +x_gigabytes 10 +`, + problems: []promlint.Problem{{ + Metric: "x_gigabytes", + Text: `use base unit "bytes" instead of "gigabytes"`, + }}, + }, + { + name: "kilograms", + in: ` +# HELP x_kilograms Test metric. +# TYPE x_kilograms untyped +x_kilograms 10 +`, + problems: []promlint.Problem{{ + Metric: "x_kilograms", + Text: `use base unit "grams" instead of "kilograms"`, + }}, + }, + { + name: "nanocelsius", + in: ` +# HELP x_nanocelsius Test metric. +# TYPE x_nanocelsius untyped +x_nanocelsius 10 +`, + problems: []promlint.Problem{{ + Metric: "x_nanocelsius", + Text: `use base unit "celsius" instead of "nanocelsius"`, + }}, + }, + { + name: "kilometers", + in: ` +# HELP x_kilometers Test metric. +# TYPE x_kilometers untyped +x_kilometers 10 +`, + problems: []promlint.Problem{{ + Metric: "x_kilometers", + Text: `use base unit "meters" instead of "kilometers"`, + }}, + }, + { + name: "picometers", + in: ` +# HELP x_picometers Test metric. +# TYPE x_picometers untyped +x_picometers 10 +`, + problems: []promlint.Problem{{ + Metric: "x_picometers", + Text: `use base unit "meters" instead of "picometers"`, + }}, + }, + { + name: "microseconds", + in: ` +# HELP x_microseconds Test metric. +# TYPE x_microseconds untyped +x_microseconds 10 +`, + problems: []promlint.Problem{{ + Metric: "x_microseconds", + Text: `use base unit "seconds" instead of "microseconds"`, + }}, + }, + { + name: "minutes", + in: ` +# HELP x_minutes Test metric. +# TYPE x_minutes untyped +x_minutes 10 +`, + problems: []promlint.Problem{{ + Metric: "x_minutes", + Text: `use base unit "seconds" instead of "minutes"`, + }}, + }, + { + name: "hours", + in: ` +# HELP x_hours Test metric. +# TYPE x_hours untyped +x_hours 10 +`, + problems: []promlint.Problem{{ + Metric: "x_hours", + Text: `use base unit "seconds" instead of "hours"`, + }}, + }, + { + name: "days", + in: ` +# HELP x_days Test metric. +# TYPE x_days untyped +x_days 10 +`, + problems: []promlint.Problem{{ + Metric: "x_days", + Text: `use base unit "seconds" instead of "days"`, + }}, + }, + { + name: "kelvin", + in: ` +# HELP x_kelvin Test metric. +# TYPE x_kelvin untyped +x_kelvin 10 +`, + problems: []promlint.Problem{{ + Metric: "x_kelvin", + Text: `use base unit "celsius" instead of "kelvin"`, + }}, + }, + { + name: "kelvins", + in: ` +# HELP x_kelvins Test metric. +# TYPE x_kelvins untyped +x_kelvins 10 +`, + problems: []promlint.Problem{{ + Metric: "x_kelvins", + Text: `use base unit "celsius" instead of "kelvins"`, + }}, + }, + { + name: "fahrenheit", + in: ` +# HELP thermometers_fahrenheit Test metric. +# TYPE thermometers_fahrenheit untyped +thermometers_fahrenheit 10 +`, + problems: []promlint.Problem{{ + Metric: "thermometers_fahrenheit", + Text: `use base unit "celsius" instead of "fahrenheit"`, + }}, + }, + { + name: "rankine", + in: ` +# HELP thermometers_rankine Test metric. +# TYPE thermometers_rankine untyped +thermometers_rankine 10 +`, + problems: []promlint.Problem{{ + Metric: "thermometers_rankine", + Text: `use base unit "celsius" instead of "rankine"`, + }}, + }, { + name: "inches", + in: ` +# HELP x_inches Test metric. +# TYPE x_inches untyped +x_inches 10 +`, + problems: []promlint.Problem{{ + Metric: "x_inches", + Text: `use base unit "meters" instead of "inches"`, + }}, + }, { + name: "yards", + in: ` +# HELP x_yards Test metric. +# TYPE x_yards untyped +x_yards 10 +`, + problems: []promlint.Problem{{ + Metric: "x_yards", + Text: `use base unit "meters" instead of "yards"`, + }}, + }, { + name: "miles", + in: ` +# HELP x_miles Test metric. +# TYPE x_miles untyped +x_miles 10 +`, + problems: []promlint.Problem{{ + Metric: "x_miles", + Text: `use base unit "meters" instead of "miles"`, + }}, + }, { + name: "bits", + in: ` +# HELP x_bits Test metric. +# TYPE x_bits untyped +x_bits 10 +`, + problems: []promlint.Problem{{ + Metric: "x_bits", + Text: `use base unit "bytes" instead of "bits"`, + }}, + }, + { + name: "calories", + in: ` +# HELP x_calories Test metric. +# TYPE x_calories untyped +x_calories 10 +`, + problems: []promlint.Problem{{ + Metric: "x_calories", + Text: `use base unit "joules" instead of "calories"`, + }}, + }, + { + name: "pounds", + in: ` +# HELP x_pounds Test metric. +# TYPE x_pounds untyped +x_pounds 10 +`, + problems: []promlint.Problem{{ + Metric: "x_pounds", + Text: `use base unit "grams" instead of "pounds"`, + }}, + }, + { + name: "ounces", + in: ` +# HELP x_ounces Test metric. +# TYPE x_ounces untyped +x_ounces 10 +`, + problems: []promlint.Problem{{ + Metric: "x_ounces", + Text: `use base unit "grams" instead of "ounces"`, + }}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + l := promlint.New(strings.NewReader(tt.in)) + + problems, err := l.Lint() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if want, got := tt.problems, problems; !reflect.DeepEqual(want, got) { + t.Fatalf("unexpected problems:\n- want: %v\n- got: %v", + want, got) + } + }) + } +} + +func TestLintCounter(t *testing.T) { + tests := []test{ + { + name: "counter without _total suffix", + in: ` +# HELP x_bytes Test metric. +# TYPE x_bytes counter +x_bytes 10 +`, + problems: []promlint.Problem{{ + Metric: "x_bytes", + Text: `counter metrics should have "_total" suffix`, + }}, + }, + { + name: "gauge with _total suffix", + in: ` +# HELP x_bytes_total Test metric. +# TYPE x_bytes_total gauge +x_bytes_total 10 +`, + problems: []promlint.Problem{{ + Metric: "x_bytes_total", + Text: `non-counter metrics should not have "_total" suffix`, + }}, + }, + { + name: "counter with _total suffix", + in: ` +# HELP x_bytes_total Test metric. +# TYPE x_bytes_total counter +x_bytes_total 10 +`, + }, + { + name: "gauge without _total suffix", + in: ` +# HELP x_bytes Test metric. +# TYPE x_bytes gauge +x_bytes 10 +`, + }, + { + name: "untyped with _total suffix", + in: ` +# HELP x_bytes_total Test metric. +# TYPE x_bytes_total untyped +x_bytes_total 10 +`, + }, + { + name: "untyped without _total suffix", + in: ` +# HELP x_bytes Test metric. +# TYPE x_bytes untyped +x_bytes 10 +`, + }, + } + + runTests(t, tests) +} + +func TestLintHistogramSummaryReserved(t *testing.T) { + tests := []test{ + { + name: "gauge with _bucket suffix", + in: ` +# HELP x_bytes_bucket Test metric. +# TYPE x_bytes_bucket gauge +x_bytes_bucket 10 +`, + problems: []promlint.Problem{{ + Metric: "x_bytes_bucket", + Text: `non-histogram metrics should not have "_bucket" suffix`, + }}, + }, + { + name: "gauge with _count suffix", + in: ` +# HELP x_bytes_count Test metric. +# TYPE x_bytes_count gauge +x_bytes_count 10 +`, + problems: []promlint.Problem{{ + Metric: "x_bytes_count", + Text: `non-histogram and non-summary metrics should not have "_count" suffix`, + }}, + }, + { + name: "gauge with _sum suffix", + in: ` +# HELP x_bytes_sum Test metric. +# TYPE x_bytes_sum gauge +x_bytes_sum 10 +`, + problems: []promlint.Problem{{ + Metric: "x_bytes_sum", + Text: `non-histogram and non-summary metrics should not have "_sum" suffix`, + }}, + }, + { + name: "gauge with le label", + in: ` +# HELP x_bytes Test metric. +# TYPE x_bytes gauge +x_bytes{le="1"} 10 +`, + problems: []promlint.Problem{{ + Metric: "x_bytes", + Text: `non-histogram metrics should not have "le" label`, + }}, + }, + { + name: "gauge with quantile label", + in: ` +# HELP x_bytes Test metric. +# TYPE x_bytes gauge +x_bytes{quantile="1"} 10 +`, + problems: []promlint.Problem{{ + Metric: "x_bytes", + Text: `non-summary metrics should not have "quantile" label`, + }}, + }, + { + name: "histogram with quantile label", + in: ` +# HELP tsdb_compaction_duration Duration of compaction runs. +# TYPE tsdb_compaction_duration histogram +tsdb_compaction_duration_bucket{le="0.005",quantile="0.01"} 0 +tsdb_compaction_duration_bucket{le="0.01",quantile="0.01"} 0 +tsdb_compaction_duration_bucket{le="0.025",quantile="0.01"} 0 +tsdb_compaction_duration_bucket{le="0.05",quantile="0.01"} 0 +tsdb_compaction_duration_bucket{le="0.1",quantile="0.01"} 0 +tsdb_compaction_duration_bucket{le="0.25",quantile="0.01"} 0 +tsdb_compaction_duration_bucket{le="0.5",quantile="0.01"} 57 +tsdb_compaction_duration_bucket{le="1",quantile="0.01"} 68 +tsdb_compaction_duration_bucket{le="2.5",quantile="0.01"} 69 +tsdb_compaction_duration_bucket{le="5",quantile="0.01"} 69 +tsdb_compaction_duration_bucket{le="10",quantile="0.01"} 69 +tsdb_compaction_duration_bucket{le="+Inf",quantile="0.01"} 69 +tsdb_compaction_duration_sum 28.740810936000006 +tsdb_compaction_duration_count 69 +`, + problems: []promlint.Problem{{ + Metric: "tsdb_compaction_duration", + Text: `non-summary metrics should not have "quantile" label`, + }}, + }, + { + name: "summary with le label", + in: ` +# HELP go_gc_duration_seconds A summary of the GC invocation durations. +# TYPE go_gc_duration_seconds summary +go_gc_duration_seconds{quantile="0",le="0.01"} 4.2365e-05 +go_gc_duration_seconds{quantile="0.25",le="0.01"} 8.1492e-05 +go_gc_duration_seconds{quantile="0.5",le="0.01"} 0.000100656 +go_gc_duration_seconds{quantile="0.75",le="0.01"} 0.000113913 +go_gc_duration_seconds{quantile="1",le="0.01"} 0.021754305 +go_gc_duration_seconds_sum 1.769429004 +go_gc_duration_seconds_count 5962 +`, + problems: []promlint.Problem{{ + Metric: "go_gc_duration_seconds", + Text: `non-histogram metrics should not have "le" label`, + }}, + }, + { + name: "histogram OK", + in: ` +# HELP tsdb_compaction_duration Duration of compaction runs. +# TYPE tsdb_compaction_duration histogram +tsdb_compaction_duration_bucket{le="0.005"} 0 +tsdb_compaction_duration_bucket{le="0.01"} 0 +tsdb_compaction_duration_bucket{le="0.025"} 0 +tsdb_compaction_duration_bucket{le="0.05"} 0 +tsdb_compaction_duration_bucket{le="0.1"} 0 +tsdb_compaction_duration_bucket{le="0.25"} 0 +tsdb_compaction_duration_bucket{le="0.5"} 57 +tsdb_compaction_duration_bucket{le="1"} 68 +tsdb_compaction_duration_bucket{le="2.5"} 69 +tsdb_compaction_duration_bucket{le="5"} 69 +tsdb_compaction_duration_bucket{le="10"} 69 +tsdb_compaction_duration_bucket{le="+Inf"} 69 +tsdb_compaction_duration_sum 28.740810936000006 +tsdb_compaction_duration_count 69 +`, + }, + { + name: "summary OK", + in: ` +# HELP go_gc_duration_seconds A summary of the GC invocation durations. +# TYPE go_gc_duration_seconds summary +go_gc_duration_seconds{quantile="0"} 4.2365e-05 +go_gc_duration_seconds{quantile="0.25"} 8.1492e-05 +go_gc_duration_seconds{quantile="0.5"} 0.000100656 +go_gc_duration_seconds{quantile="0.75"} 0.000113913 +go_gc_duration_seconds{quantile="1"} 0.021754305 +go_gc_duration_seconds_sum 1.769429004 +go_gc_duration_seconds_count 5962 +`, + }, + } + runTests(t, tests) +} + +func TestLintMetricTypeInName(t *testing.T) { + genTest := func(n, t, err string, problems ...promlint.Problem) test { + return test{ + name: fmt.Sprintf("%s with _%s suffix", t, t), + in: fmt.Sprintf(` +# HELP %s Test metric. +# TYPE %s %s +%s 10 +`, n, n, t, n), + problems: append(problems, promlint.Problem{ + Metric: n, + Text: fmt.Sprintf(`metric name should not include type '%s'`, err), + }), + } + } + + twoProbTest := genTest("http_requests_counter", "counter", "counter", promlint.Problem{ + Metric: "http_requests_counter", + Text: `counter metrics should have "_total" suffix`, + }) + + tests := []test{ + twoProbTest, + genTest("instance_memory_limit_bytes_gauge", "gauge", "gauge"), + genTest("request_duration_seconds_summary", "summary", "summary"), + genTest("request_duration_seconds_summary", "histogram", "summary"), + genTest("request_duration_seconds_histogram", "histogram", "histogram"), + genTest("request_duration_seconds_HISTOGRAM", "histogram", "histogram"), + + genTest("instance_memory_limit_gauge_bytes", "gauge", "gauge"), + } + runTests(t, tests) +} + +func TestLintReservedChars(t *testing.T) { + tests := []test{ + { + name: "request_duration::_seconds", + in: ` +# HELP request_duration::_seconds Test metric. +# TYPE request_duration::_seconds histogram +request_duration::_seconds 10 +`, + problems: []promlint.Problem{ + { + Metric: "request_duration::_seconds", + Text: "metric names should not contain ':'", + }, + }, + }, + } + runTests(t, tests) +} + +func TestLintCamelCase(t *testing.T) { + tests := []test{ + { + name: "requestDuration_seconds", + in: ` +# HELP requestDuration_seconds Test metric. +# TYPE requestDuration_seconds histogram +requestDuration_seconds 10 +`, + problems: []promlint.Problem{ + { + Metric: "requestDuration_seconds", + Text: "metric names should be written in 'snake_case' not 'camelCase'", + }, + }, + }, + { + name: "request_duration_seconds", + in: ` +# HELP request_duration_seconds Test metric. +# TYPE request_duration_seconds histogram +request_duration_seconds{httpService="foo"} 10 +`, + problems: []promlint.Problem{ + { + Metric: "request_duration_seconds", + Text: "label names should be written in 'snake_case' not 'camelCase'", + }, + }, + }, + } + runTests(t, tests) +} + +func TestLintUnitAbbreviations(t *testing.T) { + genTest := func(n string) test { + return test{ + name: fmt.Sprintf("%s with abbreviated unit", n), + in: fmt.Sprintf(` +# HELP %s Test metric. +# TYPE %s gauge +%s 10 +`, n, n, n), + problems: []promlint.Problem{ + { + Metric: n, + Text: "metric names should not contain abbreviated units", + }, + }, + } + } + tests := []test{ + genTest("instance_memory_limit_b"), + genTest("instance_memory_limit_kb"), + genTest("instance_memory_limit_mb"), + genTest("instance_memory_limit_MB"), + genTest("instance_memory_limit_gb"), + genTest("instance_memory_limit_tb"), + genTest("instance_memory_limit_pb"), + + genTest("request_duration_s"), + genTest("request_duration_ms"), + genTest("request_duration_us"), + genTest("request_duration_ns"), + genTest("request_duration_sec"), + genTest("request_sec_duration"), + genTest("request_duration_m"), + genTest("request_duration_h"), + genTest("request_duration_d"), + } + runTests(t, tests) +} + +func runTests(t *testing.T, tests []test) { + t.Helper() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + l := promlint.New(strings.NewReader(tt.in)) + + problems, err := l.Lint() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if want, got := tt.problems, problems; !reflect.DeepEqual(want, got) { + t.Fatalf("unexpected problems:\n- want: %v\n- got: %v", + want, got) + } + }) + } +} From af6ade7230522a649b315c041cb74a301d6360e7 Mon Sep 17 00:00:00 2001 From: RainbowMango Date: Thu, 23 Apr 2020 15:14:34 +0800 Subject: [PATCH 07/74] Fix unit test failing with Go1.14+ Signed-off-by: RainbowMango --- prometheus/promhttp/instrument_client_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/prometheus/promhttp/instrument_client_test.go b/prometheus/promhttp/instrument_client_test.go index 50d64bd..aab8dbe 100644 --- a/prometheus/promhttp/instrument_client_test.go +++ b/prometheus/promhttp/instrument_client_test.go @@ -15,10 +15,10 @@ package promhttp import ( "context" - "fmt" "log" "net/http" "net/http/httptest" + "strings" "testing" "time" @@ -186,8 +186,9 @@ func TestClientMiddlewareAPIWithRequestContextTimeout(t *testing.T) { if err == nil { t.Fatal("did not get timeout error") } - if want, got := fmt.Sprintf("Get %s: context deadline exceeded", backend.URL), err.Error(); want != got { - t.Fatalf("want error %q, got %q", want, got) + expectedMsg := "context deadline exceeded" + if !strings.Contains(err.Error(), expectedMsg) { + t.Fatalf("unexpected error: %q, expect error: %q", err.Error(), expectedMsg) } } From 7bbc897b25cb03a79d297278209b53c4231d0da5 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 23 Apr 2020 17:19:33 +0200 Subject: [PATCH 08/74] Add Go 1.14 Signed-off-by: beorn7 --- .circleci/config.yml | 4 ++++ .travis.yml | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 26df813..6f1e023 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,5 +70,9 @@ workflows: name: go-1-13 go_version: "1.13" run_lint: true + - test: + name: go-1-14 + go_version: "1.14" + run_lint: true # Style is only checked against the latest supported Go version. run_style: true diff --git a/.travis.yml b/.travis.yml index 2c8f06f..f2082c3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,10 @@ go: - 1.11.x - 1.12.x - 1.13.x - + - 1.14.x + script: - make check_license unused test-short - - if [[ ! $TRAVIS_GO_VERSION =~ ^1\.(9|10)\. ]]; then make lint; fi + - if [[ ! $TRAVIS_GO_VERSION =~ ^1\.(9|10|11)\. ]]; then make lint; fi # Style is only checked against the latest supported Go version. - - if [[ $TRAVIS_GO_VERSION =~ ^1\.(13)\. ]]; then make style; fi + - if [[ $TRAVIS_GO_VERSION =~ ^1\.(14)\. ]]; then make style; fi From 50cda505d18d9b349401421557dc6b068c37d792 Mon Sep 17 00:00:00 2001 From: RainbowMango Date: Thu, 23 Apr 2020 14:10:45 +0800 Subject: [PATCH 09/74] fix static check warnings by Goland. Signed-off-by: RainbowMango --- prometheus/testutil/promlint/promlint.go | 64 +++++++++---------- prometheus/testutil/promlint/promlint_test.go | 2 +- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/prometheus/testutil/promlint/promlint.go b/prometheus/testutil/promlint/promlint.go index 4570c60..2e00822 100644 --- a/prometheus/testutil/promlint/promlint.go +++ b/prometheus/testutil/promlint/promlint.go @@ -1,4 +1,4 @@ -// Copyright 2017 The Prometheus Authors +// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -21,8 +21,9 @@ import ( "sort" "strings" - dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" + + dto "github.com/prometheus/client_model/go" ) // A Linter is a Prometheus metrics linter. It identifies issues with metric @@ -40,21 +41,16 @@ type Problem struct { Text string } -// problems is a slice of Problems with a helper method to easily append -// additional Problems to the slice. -type problems []Problem - -// Add appends a new Problem to the slice for the specified metric, with -// the specified issue text. -func (p *problems) Add(mf dto.MetricFamily, text string) { - *p = append(*p, Problem{ +// newProblem is helper function to create a Problem. +func newProblem(mf dto.MetricFamily, text string) Problem { + return Problem{ Metric: mf.GetName(), Text: text, - }) + } } // New creates a new Linter that reads an input stream of Prometheus metrics. -// Only the text exposition format is supported. +// Only the Prometheus text exposition format is supported. func New(r io.Reader) *Linter { return &Linter{ r: r, @@ -118,11 +114,11 @@ func lint(mf dto.MetricFamily) []Problem { // lintHelp detects issues related to the help text for a metric. func lintHelp(mf dto.MetricFamily) []Problem { - var problems problems + var problems []Problem // Expect all metrics to have help text available. if mf.Help == nil { - problems.Add(mf, "no help text") + problems = append(problems, newProblem(mf, "no help text")) } return problems @@ -130,7 +126,7 @@ func lintHelp(mf dto.MetricFamily) []Problem { // lintMetricUnits detects issues with metric unit names. func lintMetricUnits(mf dto.MetricFamily) []Problem { - var problems problems + var problems []Problem unit, base, ok := metricUnits(*mf.Name) if !ok { @@ -143,7 +139,7 @@ func lintMetricUnits(mf dto.MetricFamily) []Problem { return nil } - problems.Add(mf, fmt.Sprintf("use base unit %q instead of %q", base, unit)) + problems = append(problems, newProblem(mf, fmt.Sprintf("use base unit %q instead of %q", base, unit))) return problems } @@ -151,7 +147,7 @@ func lintMetricUnits(mf dto.MetricFamily) []Problem { // lintCounter detects issues specific to counters, as well as patterns that should // only be used with counters. func lintCounter(mf dto.MetricFamily) []Problem { - var problems problems + var problems []Problem isCounter := mf.GetType() == dto.MetricType_COUNTER isUntyped := mf.GetType() == dto.MetricType_UNTYPED @@ -159,9 +155,9 @@ func lintCounter(mf dto.MetricFamily) []Problem { switch { case isCounter && !hasTotalSuffix: - problems.Add(mf, `counter metrics should have "_total" suffix`) + problems = append(problems, newProblem(mf, `counter metrics should have "_total" suffix`)) case !isUntyped && !isCounter && hasTotalSuffix: - problems.Add(mf, `non-counter metrics should not have "_total" suffix`) + problems = append(problems, newProblem(mf, `non-counter metrics should not have "_total" suffix`)) } return problems @@ -176,7 +172,7 @@ func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem { return nil } - var problems problems + var problems []Problem isHistogram := t == dto.MetricType_HISTOGRAM isSummary := t == dto.MetricType_SUMMARY @@ -184,13 +180,13 @@ func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem { n := mf.GetName() if !isHistogram && strings.HasSuffix(n, "_bucket") { - problems.Add(mf, `non-histogram metrics should not have "_bucket" suffix`) + problems = append(problems, newProblem(mf, `non-histogram metrics should not have "_bucket" suffix`)) } if !isHistogram && !isSummary && strings.HasSuffix(n, "_count") { - problems.Add(mf, `non-histogram and non-summary metrics should not have "_count" suffix`) + problems = append(problems, newProblem(mf, `non-histogram and non-summary metrics should not have "_count" suffix`)) } if !isHistogram && !isSummary && strings.HasSuffix(n, "_sum") { - problems.Add(mf, `non-histogram and non-summary metrics should not have "_sum" suffix`) + problems = append(problems, newProblem(mf, `non-histogram and non-summary metrics should not have "_sum" suffix`)) } for _, m := range mf.GetMetric() { @@ -198,10 +194,10 @@ func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem { ln := l.GetName() if !isHistogram && ln == "le" { - problems.Add(mf, `non-histogram metrics should not have "le" label`) + problems = append(problems, newProblem(mf, `non-histogram metrics should not have "le" label`)) } if !isSummary && ln == "quantile" { - problems.Add(mf, `non-summary metrics should not have "quantile" label`) + problems = append(problems, newProblem(mf, `non-summary metrics should not have "quantile" label`)) } } } @@ -211,7 +207,7 @@ func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem { // lintMetricTypeInName detects when metric types are included in the metric name. func lintMetricTypeInName(mf dto.MetricFamily) []Problem { - var problems problems + var problems []Problem n := strings.ToLower(mf.GetName()) for i, t := range dto.MetricType_name { @@ -221,7 +217,7 @@ func lintMetricTypeInName(mf dto.MetricFamily) []Problem { typename := strings.ToLower(t) if strings.Contains(n, "_"+typename+"_") || strings.HasSuffix(n, "_"+typename) { - problems.Add(mf, fmt.Sprintf(`metric name should not include type '%s'`, typename)) + problems = append(problems, newProblem(mf, fmt.Sprintf(`metric name should not include type '%s'`, typename))) } } return problems @@ -229,9 +225,9 @@ func lintMetricTypeInName(mf dto.MetricFamily) []Problem { // lintReservedChars detects colons in metric names. func lintReservedChars(mf dto.MetricFamily) []Problem { - var problems problems + var problems []Problem if strings.Contains(mf.GetName(), ":") { - problems.Add(mf, "metric names should not contain ':'") + problems = append(problems, newProblem(mf, "metric names should not contain ':'")) } return problems } @@ -240,15 +236,15 @@ var camelCase = regexp.MustCompile(`[a-z][A-Z]`) // lintCamelCase detects metric names and label names written in camelCase. func lintCamelCase(mf dto.MetricFamily) []Problem { - var problems problems + var problems []Problem if camelCase.FindString(mf.GetName()) != "" { - problems.Add(mf, "metric names should be written in 'snake_case' not 'camelCase'") + problems = append(problems, newProblem(mf, "metric names should be written in 'snake_case' not 'camelCase'")) } for _, m := range mf.GetMetric() { for _, l := range m.GetLabel() { if camelCase.FindString(l.GetName()) != "" { - problems.Add(mf, "label names should be written in 'snake_case' not 'camelCase'") + problems = append(problems, newProblem(mf, "label names should be written in 'snake_case' not 'camelCase'")) } } } @@ -257,11 +253,11 @@ func lintCamelCase(mf dto.MetricFamily) []Problem { // lintUnitAbbreviations detects abbreviated units in the metric name. func lintUnitAbbreviations(mf dto.MetricFamily) []Problem { - var problems problems + var problems []Problem n := strings.ToLower(mf.GetName()) for _, s := range unitAbbreviations { if strings.Contains(n, "_"+s+"_") || strings.HasSuffix(n, "_"+s) { - problems.Add(mf, "metric names should not contain abbreviated units") + problems = append(problems, newProblem(mf, "metric names should not contain abbreviated units")) } } return problems diff --git a/prometheus/testutil/promlint/promlint_test.go b/prometheus/testutil/promlint/promlint_test.go index 05d793e..c2d9980 100644 --- a/prometheus/testutil/promlint/promlint_test.go +++ b/prometheus/testutil/promlint/promlint_test.go @@ -1,4 +1,4 @@ -// Copyright 2017 The Prometheus Authors +// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at From 38045061c36d44bfd979b40d2dac9ad47f638b1a Mon Sep 17 00:00:00 2001 From: Oleg Zaytsev Date: Tue, 21 Apr 2020 10:56:51 +0200 Subject: [PATCH 10/74] GaugeFunc: ConstLabels godoc example Document the example usage of ConstLabels to register several GaugeFuncs on the same metric name. Also reference it from the NewCounterFunc documentation as it's similar. Ref: https://github.com/prometheus/client_golang/pull/736 Signed-off-by: Oleg Zaytsev --- prometheus/counter.go | 2 ++ prometheus/examples_test.go | 40 ++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/prometheus/counter.go b/prometheus/counter.go index df72fcf..0e1b48c 100644 --- a/prometheus/counter.go +++ b/prometheus/counter.go @@ -309,6 +309,8 @@ type CounterFunc interface { // provided function must be concurrency-safe. The function should also honor // the contract for a Counter (values only go up, not down), but compliance will // not be checked. +// +// Check out the ExampleGaugeFunc examples for the similar GaugeFunc. func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc { return newValueFunc(NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), diff --git a/prometheus/examples_test.go b/prometheus/examples_test.go index bdb567e..903d4d9 100644 --- a/prometheus/examples_test.go +++ b/prometheus/examples_test.go @@ -72,7 +72,7 @@ func ExampleGaugeVec() { opsQueued.With(prometheus.Labels{"type": "delete", "user": "alice"}).Inc() } -func ExampleGaugeFunc() { +func ExampleGaugeFunc_simple() { if err := prometheus.Register(prometheus.NewGaugeFunc( prometheus.GaugeOpts{ Subsystem: "runtime", @@ -90,6 +90,44 @@ func ExampleGaugeFunc() { // GaugeFunc 'goroutines_count' registered. } +func ExampleGaugeFunc_constLabels() { + // primaryDB and secondaryDB represent two example *sql.DB connections we want to instrument. + var primaryDB, secondaryDB interface { + Stats() struct{ OpenConnections int } + } + + if err := prometheus.Register(prometheus.NewGaugeFunc( + prometheus.GaugeOpts{ + Namespace: "mysql", + Name: "connections_open", + Help: "Number of mysql connections open.", + ConstLabels: prometheus.Labels{"destination": "primary"}, + }, + func() float64 { return float64(primaryDB.Stats().OpenConnections) }, + )); err == nil { + fmt.Println(`GaugeFunc 'connections_open' for primary DB connection registered with labels {destination="primary"}`) + } + + if err := prometheus.Register(prometheus.NewGaugeFunc( + prometheus.GaugeOpts{ + Namespace: "mysql", + Name: "connections_open", + Help: "Number of mysql connections open.", + ConstLabels: prometheus.Labels{"destination": "secondary"}, + }, + func() float64 { return float64(secondaryDB.Stats().OpenConnections) }, + )); err == nil { + fmt.Println(`GaugeFunc 'connections_open' for secondary DB connection registered with labels {destination="secondary"}`) + } + + // Note that we can register more than once GaugeFunc with same metric name + // as long as their const labels are consistent. + + // Output: + // GaugeFunc 'connections_open' for primary DB connection registered with labels {destination="primary"} + // GaugeFunc 'connections_open' for secondary DB connection registered with labels {destination="secondary"} +} + func ExampleCounterVec() { httpReqs := prometheus.NewCounterVec( prometheus.CounterOpts{ From 35355f03a2249db2e170285958fb6e9471e5512b Mon Sep 17 00:00:00 2001 From: Simon Pasquier Date: Fri, 24 Apr 2020 17:22:20 +0200 Subject: [PATCH 11/74] Remove Travis CI Signed-off-by: Simon Pasquier --- .travis.yml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f2082c3..0000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go - -go: - - 1.9.x # See README.md for current minimum version. - - 1.10.x - - 1.11.x - - 1.12.x - - 1.13.x - - 1.14.x - -script: - - make check_license unused test-short - - if [[ ! $TRAVIS_GO_VERSION =~ ^1\.(9|10|11)\. ]]; then make lint; fi - # Style is only checked against the latest supported Go version. - - if [[ $TRAVIS_GO_VERSION =~ ^1\.(14)\. ]]; then make style; fi From 6433bcf819e24b6d1841cfc3a05e688fe6083480 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Fri, 24 Apr 2020 23:42:49 +0200 Subject: [PATCH 12/74] Add the capability to lint MetricFamilies directly Also, change all the `dto.MetricFamily` arguments to pointers to be more consistent with what we do in client_golang in general. Signed-off-by: beorn7 --- prometheus/testutil/promlint/promlint.go | 63 ++++++++++++++---------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/prometheus/testutil/promlint/promlint.go b/prometheus/testutil/promlint/promlint.go index 2e00822..18ca942 100644 --- a/prometheus/testutil/promlint/promlint.go +++ b/prometheus/testutil/promlint/promlint.go @@ -29,7 +29,8 @@ import ( // A Linter is a Prometheus metrics linter. It identifies issues with metric // names, types, and metadata, and reports them to the caller. type Linter struct { - r io.Reader + r io.Reader + mfs []*dto.MetricFamily } // A Problem is an issue detected by a Linter. @@ -42,40 +43,52 @@ type Problem struct { } // newProblem is helper function to create a Problem. -func newProblem(mf dto.MetricFamily, text string) Problem { +func newProblem(mf *dto.MetricFamily, text string) Problem { return Problem{ Metric: mf.GetName(), Text: text, } } -// New creates a new Linter that reads an input stream of Prometheus metrics. -// Only the Prometheus text exposition format is supported. +// New creates a new Linter that reads an input stream of Prometheus metrics in +// the Prometheus text exposition format. func New(r io.Reader) *Linter { return &Linter{ r: r, } } +// NewWithMetricFamilies creates a new Linter that reads from a slice of +// MetricFamily protobuf messages. +func NewWithMetricFamilies(mfs []*dto.MetricFamily) *Linter { + return &Linter{ + mfs: mfs, + } +} + // Lint performs a linting pass, returning a slice of Problems indicating any -// issues found in the metrics stream. The slice is sorted by metric name +// issues found in the metrics stream. The slice is sorted by metric name // and issue description. func (l *Linter) Lint() ([]Problem, error) { - // TODO(mdlayher): support for protobuf exposition format? - d := expfmt.NewDecoder(l.r, expfmt.FmtText) - var problems []Problem - var mf dto.MetricFamily - for { - if err := d.Decode(&mf); err != nil { - if err == io.EOF { - break + if l.r != nil { + d := expfmt.NewDecoder(l.r, expfmt.FmtText) + + mf := &dto.MetricFamily{} + for { + if err := d.Decode(mf); err != nil { + if err == io.EOF { + break + } + + return nil, err } - return nil, err + problems = append(problems, lint(mf)...) } - + } + for _, mf := range l.mfs { problems = append(problems, lint(mf)...) } @@ -91,8 +104,8 @@ func (l *Linter) Lint() ([]Problem, error) { } // lint is the entry point for linting a single metric. -func lint(mf dto.MetricFamily) []Problem { - fns := []func(mf dto.MetricFamily) []Problem{ +func lint(mf *dto.MetricFamily) []Problem { + fns := []func(mf *dto.MetricFamily) []Problem{ lintHelp, lintMetricUnits, lintCounter, @@ -113,7 +126,7 @@ func lint(mf dto.MetricFamily) []Problem { } // lintHelp detects issues related to the help text for a metric. -func lintHelp(mf dto.MetricFamily) []Problem { +func lintHelp(mf *dto.MetricFamily) []Problem { var problems []Problem // Expect all metrics to have help text available. @@ -125,7 +138,7 @@ func lintHelp(mf dto.MetricFamily) []Problem { } // lintMetricUnits detects issues with metric unit names. -func lintMetricUnits(mf dto.MetricFamily) []Problem { +func lintMetricUnits(mf *dto.MetricFamily) []Problem { var problems []Problem unit, base, ok := metricUnits(*mf.Name) @@ -146,7 +159,7 @@ func lintMetricUnits(mf dto.MetricFamily) []Problem { // lintCounter detects issues specific to counters, as well as patterns that should // only be used with counters. -func lintCounter(mf dto.MetricFamily) []Problem { +func lintCounter(mf *dto.MetricFamily) []Problem { var problems []Problem isCounter := mf.GetType() == dto.MetricType_COUNTER @@ -165,7 +178,7 @@ func lintCounter(mf dto.MetricFamily) []Problem { // lintHistogramSummaryReserved detects when other types of metrics use names or labels // reserved for use by histograms and/or summaries. -func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem { +func lintHistogramSummaryReserved(mf *dto.MetricFamily) []Problem { // These rules do not apply to untyped metrics. t := mf.GetType() if t == dto.MetricType_UNTYPED { @@ -206,7 +219,7 @@ func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem { } // lintMetricTypeInName detects when metric types are included in the metric name. -func lintMetricTypeInName(mf dto.MetricFamily) []Problem { +func lintMetricTypeInName(mf *dto.MetricFamily) []Problem { var problems []Problem n := strings.ToLower(mf.GetName()) @@ -224,7 +237,7 @@ func lintMetricTypeInName(mf dto.MetricFamily) []Problem { } // lintReservedChars detects colons in metric names. -func lintReservedChars(mf dto.MetricFamily) []Problem { +func lintReservedChars(mf *dto.MetricFamily) []Problem { var problems []Problem if strings.Contains(mf.GetName(), ":") { problems = append(problems, newProblem(mf, "metric names should not contain ':'")) @@ -235,7 +248,7 @@ func lintReservedChars(mf dto.MetricFamily) []Problem { var camelCase = regexp.MustCompile(`[a-z][A-Z]`) // lintCamelCase detects metric names and label names written in camelCase. -func lintCamelCase(mf dto.MetricFamily) []Problem { +func lintCamelCase(mf *dto.MetricFamily) []Problem { var problems []Problem if camelCase.FindString(mf.GetName()) != "" { problems = append(problems, newProblem(mf, "metric names should be written in 'snake_case' not 'camelCase'")) @@ -252,7 +265,7 @@ func lintCamelCase(mf dto.MetricFamily) []Problem { } // lintUnitAbbreviations detects abbreviated units in the metric name. -func lintUnitAbbreviations(mf dto.MetricFamily) []Problem { +func lintUnitAbbreviations(mf *dto.MetricFamily) []Problem { var problems []Problem n := strings.ToLower(mf.GetName()) for _, s := range unitAbbreviations { From 39dbb24d13f7528d65c323822259c8bf3d09fd84 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Fri, 24 Apr 2020 23:44:21 +0200 Subject: [PATCH 13/74] Add helper functions for linting to testutil Signed-off-by: beorn7 --- prometheus/testutil/lint.go | 46 +++++++++++++++++++++ prometheus/testutil/lint_test.go | 70 ++++++++++++++++++++++++++++++++ prometheus/testutil/testutil.go | 4 ++ 3 files changed, 120 insertions(+) create mode 100644 prometheus/testutil/lint.go create mode 100644 prometheus/testutil/lint_test.go diff --git a/prometheus/testutil/lint.go b/prometheus/testutil/lint.go new file mode 100644 index 0000000..1e006f3 --- /dev/null +++ b/prometheus/testutil/lint.go @@ -0,0 +1,46 @@ +// Copyright 2020 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package testutil + +import ( + "fmt" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil/promlint" +) + +// CollectAndLint registers the provided Collector with a newly created +// pedantic Registry. It then does the same as GatherAndLint, gathering the +// metrics from the pedantic Registry. +func CollectAndLint(c prometheus.Collector, metricNames ...string) ([]promlint.Problem, error) { + reg := prometheus.NewPedanticRegistry() + if err := reg.Register(c); err != nil { + return nil, fmt.Errorf("registering collector failed: %s", err) + } + return GatherAndLint(reg, metricNames...) +} + +// GatherAndLint gathers all metrics from the provided Gatherer and checks them +// with the linter in the promlint package. If any metricNames are provided, +// only metrics with those names are checked. +func GatherAndLint(g prometheus.Gatherer, metricNames ...string) ([]promlint.Problem, error) { + got, err := g.Gather() + if err != nil { + return nil, fmt.Errorf("gathering metrics failed: %s", err) + } + if metricNames != nil { + got = filterMetrics(got, metricNames) + } + return promlint.NewWithMetricFamilies(got).Lint() +} diff --git a/prometheus/testutil/lint_test.go b/prometheus/testutil/lint_test.go new file mode 100644 index 0000000..1230cc6 --- /dev/null +++ b/prometheus/testutil/lint_test.go @@ -0,0 +1,70 @@ +// Copyright 2020 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package testutil + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus" +) + +func TestCollectAndLintGood(t *testing.T) { + cnt := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "some_total", + Help: "A value that represents a counter.", + ConstLabels: prometheus.Labels{ + "label1": "value1", + }, + }, + []string{"foo"}, + ) + cnt.WithLabelValues("bar") + cnt.WithLabelValues("baz") + + problems, err := CollectAndLint(cnt) + if err != nil { + t.Error("Unexpected error:", err) + } + if len(problems) > 0 { + t.Error("Unexpected lint problems:", problems) + } +} + +func TestCollectAndLintBad(t *testing.T) { + cnt := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "someThing_ms", + Help: "A value that represents a counter.", + ConstLabels: prometheus.Labels{ + "label1": "value1", + }, + }, + []string{"fooBar"}, + ) + cnt.WithLabelValues("bar") + cnt.WithLabelValues("baz") + + problems, err := CollectAndLint(cnt) + if err != nil { + t.Error("Unexpected error:", err) + } + if len(problems) < 5 { + // The exact nature of the lint problems found is tested within + // the promlint package itself. Here we only want to make sure + // that the collector successfully hit the linter and got enough + // problems flagged. + t.Error("Not enough lint problems found.") + } +} diff --git a/prometheus/testutil/testutil.go b/prometheus/testutil/testutil.go index cb09839..0e32d9d 100644 --- a/prometheus/testutil/testutil.go +++ b/prometheus/testutil/testutil.go @@ -31,6 +31,10 @@ // testing custom prometheus.Collector implementations and in particular whole // exporters, i.e. programs that retrieve telemetry data from a 3rd party source // and convert it into Prometheus metrics. +// +// In a similar pattern, CollectAndLint and GatherAndLint can be used to detect +// metrics that have issues with their name, type, or metadata without being +// necessarily invalid, e.g. a counter with a name missing the “_total” suffix. package testutil import ( From dc79bd60935b46c7a47b0e82d34db3912cca0083 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Sat, 25 Apr 2020 15:59:53 +0200 Subject: [PATCH 14/74] Improve various comments Signed-off-by: beorn7 --- prometheus/testutil/lint.go | 6 +++--- prometheus/testutil/lint_test.go | 5 +++-- prometheus/testutil/promlint/promlint.go | 5 +++++ prometheus/testutil/testutil.go | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/prometheus/testutil/lint.go b/prometheus/testutil/lint.go index 1e006f3..7681877 100644 --- a/prometheus/testutil/lint.go +++ b/prometheus/testutil/lint.go @@ -20,9 +20,9 @@ import ( "github.com/prometheus/client_golang/prometheus/testutil/promlint" ) -// CollectAndLint registers the provided Collector with a newly created -// pedantic Registry. It then does the same as GatherAndLint, gathering the -// metrics from the pedantic Registry. +// CollectAndLint registers the provided Collector with a newly created pedantic +// Registry. It then calls GatherAndLint with that Registry and with the +// provided metricNames. func CollectAndLint(c prometheus.Collector, metricNames ...string) ([]promlint.Problem, error) { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { diff --git a/prometheus/testutil/lint_test.go b/prometheus/testutil/lint_test.go index 1230cc6..547465d 100644 --- a/prometheus/testutil/lint_test.go +++ b/prometheus/testutil/lint_test.go @@ -63,8 +63,9 @@ func TestCollectAndLintBad(t *testing.T) { if len(problems) < 5 { // The exact nature of the lint problems found is tested within // the promlint package itself. Here we only want to make sure - // that the collector successfully hit the linter and got enough - // problems flagged. + // that the collector successfully hits the linter and that at + // least the five problems that the linter could recognize at + // the time of writing this test are flagged. t.Error("Not enough lint problems found.") } } diff --git a/prometheus/testutil/promlint/promlint.go b/prometheus/testutil/promlint/promlint.go index 18ca942..e48e4d4 100644 --- a/prometheus/testutil/promlint/promlint.go +++ b/prometheus/testutil/promlint/promlint.go @@ -29,6 +29,11 @@ import ( // A Linter is a Prometheus metrics linter. It identifies issues with metric // names, types, and metadata, and reports them to the caller. type Linter struct { + // The linter will read metrics in the Prometheus text format from r and + // then lint it, _and_ it will lint the metrics provided directly as + // MetricFamily proto messages in mfs. Note, however, that the current + // constructor functions New and NewWithMetricFamilies only ever set one + // of them. r io.Reader mfs []*dto.MetricFamily } diff --git a/prometheus/testutil/testutil.go b/prometheus/testutil/testutil.go index 0e32d9d..c47373c 100644 --- a/prometheus/testutil/testutil.go +++ b/prometheus/testutil/testutil.go @@ -140,8 +140,8 @@ func CollectAndCount(c prometheus.Collector) int { } // CollectAndCompare registers the provided Collector with a newly created -// pedantic Registry. It then does the same as GatherAndCompare, gathering the -// metrics from the pedantic Registry. +// pedantic Registry. It then calls GatherAndCompare with that Registry and with +// the provided metricNames. func CollectAndCompare(c prometheus.Collector, expected io.Reader, metricNames ...string) error { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { From 332f3243f110cad9755fa6b63047c4041546fa32 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Mon, 27 Apr 2020 18:18:59 +0200 Subject: [PATCH 15/74] Update dependencies Signed-off-by: beorn7 --- go.mod | 7 +++---- go.sum | 22 ++++++++++++++++++---- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 9d5bd9d..61b13ed 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,14 @@ module github.com/prometheus/client_golang require ( github.com/beorn7/perks v1.0.1 github.com/cespare/xxhash/v2 v2.1.1 - github.com/golang/protobuf v1.3.2 - github.com/google/go-cmp v0.4.0 // indirect + github.com/golang/protobuf v1.4.0 github.com/json-iterator/go v1.1.9 github.com/kr/pretty v0.1.0 // indirect github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.9.1 - github.com/prometheus/procfs v0.0.8 + github.com/prometheus/procfs v0.0.11 github.com/stretchr/testify v1.4.0 // indirect - golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 + golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.5 // indirect ) diff --git a/go.sum b/go.sum index e805d46..8932e64 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,13 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= @@ -80,8 +87,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI= +github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -108,11 +115,18 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5 h1:mzjBh+S5frKOsOBobWIMAbXav golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 9c28cb92b456ed5dc761e2a98e712da6d7c82201 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Mon, 27 Apr 2020 18:57:41 +0200 Subject: [PATCH 16/74] Cut v1.6.0 Signed-off-by: beorn7 --- CHANGELOG.md | 8 +++++++- VERSION | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd44c4d..2481d3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ +## 1.6.0 / 2020-04-28 + +* [FEATURE] testutil: Add lint checks for metrics, including a sub-package `promlint` to expose the linter engine for external usage. #739 #743 +* [ENHANCEMENT] API client: Improve error messages. #731 +* [BUGFIX] process collector: Fix `process_resident_memory_bytes` on 32bit MS Windows. #734 + ## 1.5.1 / 2020-03-14 -* [BUGFIX] promhttp: Remove another superfluous `WriteHeader` call. +* [BUGFIX] promhttp: Remove another superfluous `WriteHeader` call. #726 ## 1.5.0 / 2020-03-03 diff --git a/VERSION b/VERSION index 26ca594..dc1e644 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.1 +1.6.0 From be019d1f2443f345b28be58eeec3b06bf3dde1c8 Mon Sep 17 00:00:00 2001 From: Michael Cristina Date: Sat, 2 May 2020 10:38:33 -0500 Subject: [PATCH 17/74] Fix typo in godoc help text Signed-off-by: Michael Cristina --- prometheus/promauto/auto.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prometheus/promauto/auto.go b/prometheus/promauto/auto.go index 3c10c85..6f864f6 100644 --- a/prometheus/promauto/auto.go +++ b/prometheus/promauto/auto.go @@ -98,7 +98,7 @@ // requestCount = promauto.With(reg).NewCounterVec( // prometheus.CounterOpts{ // Name: "http_requests_total", -// Help: "Total number of HTTP requests by status code end method.", +// Help: "Total number of HTTP requests by status code and method.", // }, // []string{"code", "method"}, // ) @@ -117,7 +117,7 @@ // requestCount = factory.NewCounterVec( // prometheus.CounterOpts{ // Name: "http_requests_total", -// Help: "Total number of HTTP requests by status code end method.", +// Help: "Total number of HTTP requests by status code and method.", // }, // []string{"code", "method"}, // ) From 389d3c3b9ac6865dcd3cb4cb0ab4b134c31c049f Mon Sep 17 00:00:00 2001 From: beorn7 Date: Wed, 13 May 2020 23:35:31 +0200 Subject: [PATCH 18/74] Properly handle empty job and label values An empty job name was always an error, but it was previously only detected when pushing to the PGW and receiving an error. With this commit, the error is detected before pushing. An empty label value should have been OK but was encoded in a way that couldn't be pushed to the PGW. Cf. https://github.com/prometheus/pushgateway/issues/344 . This commit changes the creation of the path in the URL so that it works with empty label values. Signed-off-by: beorn7 --- prometheus/push/push.go | 29 ++++++++++++++++++++--------- prometheus/push/push_test.go | 31 ++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/prometheus/push/push.go b/prometheus/push/push.go index 77ce9c8..c1a6cb9 100644 --- a/prometheus/push/push.go +++ b/prometheus/push/push.go @@ -37,6 +37,7 @@ package push import ( "bytes" "encoding/base64" + "errors" "fmt" "io/ioutil" "net/http" @@ -56,6 +57,8 @@ const ( base64Suffix = "@base64" ) +var errJobEmpty = errors.New("job name is empty") + // HTTPDoer is an interface for the one method of http.Client that is used by Pusher type HTTPDoer interface { Do(*http.Request) (*http.Response, error) @@ -80,14 +83,17 @@ type Pusher struct { } // New creates a new Pusher to push to the provided URL with the provided job -// name. You can use just host:port or ip:port as url, in which case “http://” -// is added automatically. Alternatively, include the schema in the -// URL. However, do not include the “/metrics/jobs/…” part. +// name (which must not be empty). You can use just host:port or ip:port as url, +// in which case “http://” is added automatically. Alternatively, include the +// schema in the URL. However, do not include the “/metrics/jobs/…” part. func New(url, job string) *Pusher { var ( reg = prometheus.NewRegistry() err error ) + if job == "" { + err = errJobEmpty + } if !strings.Contains(url, "://") { url = "http://" + url } @@ -267,7 +273,7 @@ func (p *Pusher) push(method string) error { return err } defer resp.Body.Close() - // Pushgateway 0.10+ responds with StatusOK, earlier versions with StatusAccepted. + // Depending on version and configuration of the PGW, StatusOK or StatusAccepted may be returned. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted { body, _ := ioutil.ReadAll(resp.Body) // Ignore any further error as this is for an error message only. return fmt.Errorf("unexpected status code %d while pushing to %s: %s", resp.StatusCode, p.fullURL(), body) @@ -278,9 +284,11 @@ func (p *Pusher) push(method string) error { // fullURL assembles the URL used to push/delete metrics and returns it as a // string. The job name and any grouping label values containing a '/' will // trigger a base64 encoding of the affected component and proper suffixing of -// the preceding component. If the component does not contain a '/' but other -// special character, the usual url.QueryEscape is used for compatibility with -// older versions of the Pushgateway and for better readability. +// the preceding component. Similarly, an empty grouping label value will be +// encoded as base64 just with a single `=` padding character (to avoid an empty +// path component). If the component does not contain a '/' but other special +// characters, the usual url.QueryEscape is used for compatibility with older +// versions of the Pushgateway and for better readability. func (p *Pusher) fullURL() string { urlComponents := []string{} if encodedJob, base64 := encodeComponent(p.job); base64 { @@ -299,9 +307,12 @@ func (p *Pusher) fullURL() string { } // encodeComponent encodes the provided string with base64.RawURLEncoding in -// case it contains '/'. If not, it uses url.QueryEscape instead. It returns -// true in the former case. +// case it contains '/' and as "=" in case it is empty. If neither is the case, +// it uses url.QueryEscape instead. It returns true in the former two cases. func encodeComponent(s string) (string, bool) { + if s == "" { + return "=", true + } if strings.Contains(s, "/") { return base64.RawURLEncoding.EncodeToString([]byte(s)), true } diff --git a/prometheus/push/push_test.go b/prometheus/push/push_test.go index 1fabe39..99155b0 100644 --- a/prometheus/push/push_test.go +++ b/prometheus/push/push_test.go @@ -176,6 +176,36 @@ func TestPush(t *testing.T) { t.Error("unexpected path:", lastPath) } + // Empty label value triggers special base64 encoding. + if err := New(pgwOK.URL, "testjob"). + Grouping("empty", ""). + Collector(metric1). + Collector(metric2). + Push(); err != nil { + t.Fatal(err) + } + if lastMethod != http.MethodPut { + t.Errorf("got method %q for Push, want %q", lastMethod, http.MethodPut) + } + if !bytes.Equal(lastBody, wantBody) { + t.Errorf("got body %v, want %v", lastBody, wantBody) + } + if lastPath != "/metrics/job/testjob/empty@base64/=" { + t.Error("unexpected path:", lastPath) + } + + // Empty job name results in error. + if err := New(pgwErr.URL, ""). + Collector(metric1). + Collector(metric2). + Push(); err == nil { + t.Error("push with empty job succeded") + } else { + if got, want := err, errJobEmpty; got != want { + t.Errorf("got error %q, want %q", got, want) + } + } + // Push some Collectors with a broken PGW. if err := New(pgwErr.URL, "testjob"). Collector(metric1). @@ -251,5 +281,4 @@ func TestPush(t *testing.T) { if lastPath != "/metrics/job/testjob/a/x/b/y" && lastPath != "/metrics/job/testjob/b/y/a/x" { t.Error("unexpected path:", lastPath) } - } From 0577ef6c57494933d4139f19dd2960359736ad1e Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 14 May 2020 00:17:45 +0200 Subject: [PATCH 19/74] Improve CollectAndCount Now that we have also added CollectAndLint and GatherAndLint, I thought we should bring CollectAndCount in line. So: - Add GatherAndCount. - Add filtering by metric name. - Add tests. Minor wart: CollectAndCount should now return `(int, error)`, but that would be a breaking change as the current version just returns `int`. I decided to let the new version panic when it should return an error. An error is anyway very unlikely, so the biggest annoyance here is really just the inconsistency. Signed-off-by: beorn7 --- prometheus/testutil/testutil.go | 58 +++++++++++++++++----------- prometheus/testutil/testutil_test.go | 27 +++++++++++++ 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/prometheus/testutil/testutil.go b/prometheus/testutil/testutil.go index c47373c..9af60ce 100644 --- a/prometheus/testutil/testutil.go +++ b/prometheus/testutil/testutil.go @@ -112,31 +112,43 @@ func ToFloat64(c prometheus.Collector) float64 { panic(fmt.Errorf("collected a non-gauge/counter/untyped metric: %s", pb)) } -// CollectAndCount collects all Metrics from the provided Collector and returns their number. -// -// This can be used to assert the number of metrics collected by a given collector after certain operations. -// -// This function is only for testing purposes, and even for testing, other approaches -// are often more appropriate (see this package's documentation). -func CollectAndCount(c prometheus.Collector) int { - var ( - mCount int - mChan = make(chan prometheus.Metric) - done = make(chan struct{}) - ) +// CollectAndCount registers the provided Collector with a newly created +// pedantic Registry. It then calls GatherAndCount with that Registry and with +// the provided metricNames. In the unlikely case that the registration or the +// gathering fails, this function panics. (This is inconsistent with the other +// CollectAnd… functions in this package and has historical reasons. Changing +// the function signature would be a breaking change and will therefore only +// happen with the next major version bump.) +func CollectAndCount(c prometheus.Collector, metricNames ...string) int { + reg := prometheus.NewPedanticRegistry() + if err := reg.Register(c); err != nil { + panic(fmt.Errorf("registering collector failed: %s", err)) + } + result, err := GatherAndCount(reg, metricNames...) + if err != nil { + panic(err) + } + return result +} - go func() { - for range mChan { - mCount++ - } - close(done) - }() +// GatherAndCount gathers all metrics from the provided Gatherer and counts +// them. It returns the number of metric children in all gathered metric +// families together. If any metricNames are provided, only metrics with those +// names are counted. +func GatherAndCount(g prometheus.Gatherer, metricNames ...string) (int, error) { + got, err := g.Gather() + if err != nil { + return 0, fmt.Errorf("gathering metrics failed: %s", err) + } + if metricNames != nil { + got = filterMetrics(got, metricNames) + } - c.Collect(mChan) - close(mChan) - <-done - - return mCount + result := 0 + for _, mf := range got { + result += len(mf.GetMetric()) + } + return result, nil } // CollectAndCompare registers the provided Collector with a newly created diff --git a/prometheus/testutil/testutil_test.go b/prometheus/testutil/testutil_test.go index aaf6707..56d9933 100644 --- a/prometheus/testutil/testutil_test.go +++ b/prometheus/testutil/testutil_test.go @@ -306,3 +306,30 @@ some_total{label1="value1"} 1 t.Errorf("Expected\n%#+v\nGot:\n%#+v", expectedError, err.Error()) } } + +func TestCollectAndCount(t *testing.T) { + c := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "some_total", + Help: "A value that represents a counter.", + }, + []string{"foo"}, + ) + if got, want := CollectAndCount(c), 0; got != want { + t.Errorf("unexpected metric count, got %d, want %d", got, want) + } + c.WithLabelValues("bar") + if got, want := CollectAndCount(c), 1; got != want { + t.Errorf("unexpected metric count, got %d, want %d", got, want) + } + c.WithLabelValues("baz") + if got, want := CollectAndCount(c), 2; got != want { + t.Errorf("unexpected metric count, got %d, want %d", got, want) + } + if got, want := CollectAndCount(c, "some_total"), 2; got != want { + t.Errorf("unexpected metric count, got %d, want %d", got, want) + } + if got, want := CollectAndCount(c, "some_other_total"), 0; got != want { + t.Errorf("unexpected metric count, got %d, want %d", got, want) + } +} From dba1478b8a68bebf5553ebc220c84532c977a0c1 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 14 May 2020 20:04:11 +0200 Subject: [PATCH 20/74] Add lint:ignore for protobuf deprecation `github.com/golang/protobuf/proto` is deprecated in lieu of `google.golang.org/protobuf/proto`. However, we cannot simply migrate. Types from the proto package are exposed to users of packages in this repo. If we migrate here, users have to migrate to. Thus, we could only migrate with a major version bump. In different news, with all the inline lint:ignore comments, including the existing ones, there is no need to repeat the exception in the Makefile. A current version of `staticcheck` is happy with the code after this commit. golangci-lint is broken at the moment, however, and ignores the lint:ignore comments in the code as well as those via envvar. Signed-off-by: beorn7 --- Makefile | 7 ------- prometheus/counter_test.go | 1 + prometheus/desc.go | 1 + prometheus/examples_test.go | 1 + prometheus/histogram.go | 1 + prometheus/histogram_test.go | 1 + prometheus/metric.go | 1 + prometheus/registry.go | 1 + prometheus/registry_test.go | 1 + prometheus/summary.go | 1 + prometheus/value.go | 1 + prometheus/wrap.go | 1 + prometheus/wrap_test.go | 1 + 13 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index b25fb83..f35cf58 100644 --- a/Makefile +++ b/Makefile @@ -13,13 +13,6 @@ include Makefile.common -# http.CloseNotifier is deprecated but we don't want to remove support -# from client_golang to not break anybody still using it. -STATICCHECK_IGNORE = \ - github.com/prometheus/client_golang/prometheus/promhttp/delegator*.go:SA1019 \ - github.com/prometheus/client_golang/prometheus/promhttp/instrument_server_test.go:SA1019 \ - github.com/prometheus/client_golang/prometheus/http.go:SA1019 - .PHONY: test test: deps common-test diff --git a/prometheus/counter_test.go b/prometheus/counter_test.go index e2e31fc..56652a0 100644 --- a/prometheus/counter_test.go +++ b/prometheus/counter_test.go @@ -19,6 +19,7 @@ import ( "testing" "time" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" diff --git a/prometheus/desc.go b/prometheus/desc.go index e3232d7..2f19f5e 100644 --- a/prometheus/desc.go +++ b/prometheus/desc.go @@ -20,6 +20,7 @@ import ( "strings" "github.com/cespare/xxhash/v2" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/model" diff --git a/prometheus/examples_test.go b/prometheus/examples_test.go index 903d4d9..8bc051a 100644 --- a/prometheus/examples_test.go +++ b/prometheus/examples_test.go @@ -22,6 +22,7 @@ import ( "strings" "time" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/expfmt" diff --git a/prometheus/histogram.go b/prometheus/histogram.go index 4271f43..3a5aac7 100644 --- a/prometheus/histogram.go +++ b/prometheus/histogram.go @@ -22,6 +22,7 @@ import ( "sync/atomic" "time" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" diff --git a/prometheus/histogram_test.go b/prometheus/histogram_test.go index 2e8f4b8..0b4826c 100644 --- a/prometheus/histogram_test.go +++ b/prometheus/histogram_test.go @@ -24,6 +24,7 @@ import ( "testing/quick" "time" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" diff --git a/prometheus/metric.go b/prometheus/metric.go index 0df1eff..35bd8bd 100644 --- a/prometheus/metric.go +++ b/prometheus/metric.go @@ -17,6 +17,7 @@ import ( "strings" "time" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/model" diff --git a/prometheus/registry.go b/prometheus/registry.go index c05d6ee..ba94405 100644 --- a/prometheus/registry.go +++ b/prometheus/registry.go @@ -26,6 +26,7 @@ import ( "unicode/utf8" "github.com/cespare/xxhash/v2" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/expfmt" diff --git a/prometheus/registry_test.go b/prometheus/registry_test.go index 67e4fcb..48596cd 100644 --- a/prometheus/registry_test.go +++ b/prometheus/registry_test.go @@ -33,6 +33,7 @@ import ( dto "github.com/prometheus/client_model/go" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/expfmt" diff --git a/prometheus/summary.go b/prometheus/summary.go index ae42e76..f3c1440 100644 --- a/prometheus/summary.go +++ b/prometheus/summary.go @@ -23,6 +23,7 @@ import ( "time" "github.com/beorn7/perks/quantile" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" diff --git a/prometheus/value.go b/prometheus/value.go index 2be470c..6206928 100644 --- a/prometheus/value.go +++ b/prometheus/value.go @@ -19,6 +19,7 @@ import ( "time" "unicode/utf8" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" diff --git a/prometheus/wrap.go b/prometheus/wrap.go index e303eef..da6896a 100644 --- a/prometheus/wrap.go +++ b/prometheus/wrap.go @@ -17,6 +17,7 @@ import ( "fmt" "sort" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" diff --git a/prometheus/wrap_test.go b/prometheus/wrap_test.go index 0fbb78c..256875a 100644 --- a/prometheus/wrap_test.go +++ b/prometheus/wrap_test.go @@ -19,6 +19,7 @@ import ( "strings" "testing" + //lint:ignore SA1019 Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" From c9e3c020a93da7fe04e71f10f58ac1aac1062bb9 Mon Sep 17 00:00:00 2001 From: Lili Cosic Date: Mon, 18 May 2020 16:52:37 +0200 Subject: [PATCH 21/74] api/prometheus/v1/api.go: Add support for /runtimeinfo endpoint Signed-off-by: Lili Cosic --- api/prometheus/v1/api.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index fa35ddd..a18d2c7 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -137,6 +137,7 @@ const ( epCleanTombstones = apiPrefix + "/admin/tsdb/clean_tombstones" epConfig = apiPrefix + "/status/config" epFlags = apiPrefix + "/status/flags" + epRuntimeinfo = apiPrefix + "/status/runtimeinfo" ) // AlertState models the state of an alert. @@ -238,6 +239,8 @@ type API interface { Query(ctx context.Context, query string, ts time.Time) (model.Value, Warnings, error) // QueryRange performs a query for the given range. QueryRange(ctx context.Context, query string, r Range) (model.Value, Warnings, error) + // Runtimeinfo returns the various runtime information properties about the Prometheus server. + Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) // Series finds series by label matchers. Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, Warnings, error) // Snapshot creates a snapshot of all current data into snapshots/- @@ -277,6 +280,22 @@ type ConfigResult struct { // FlagsResult contains the result from querying the flag endpoint. type FlagsResult map[string]string +// RuntimeinfoResult contains the result from querying the runtimeinfo endpoint. +type RuntimeinfoResult struct { + StartTime string `json:"startTime"` + CWD string `json:"CWD"` + ReloadConfigSuccess bool `json:"reloadConfigSuccess"` + LastConfigTime string `json:"lastConfigTime"` + ChunkCount int `json:"chunkCount"` + TimeSeriesCount int `json:"timeSeriesCount"` + CorruptionCount int `json:"corruptionCount"` + GoroutineCount int `json:"goroutineCount"` + GOMAXPROCS int `json:"GOMAXPROCS"` + GOGC string `json:"GOGC"` + GODEBUG string `json:"GODEBUG"` + StorageRetention string `json:"storageRetention"` +} + // SnapshotResult contains the result from querying the snapshot endpoint. type SnapshotResult struct { Name string `json:"name"` @@ -640,6 +659,23 @@ func (h *httpAPI) Flags(ctx context.Context) (FlagsResult, error) { return res, json.Unmarshal(body, &res) } +func (h *httpAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) { + u := h.client.URL(epRuntimeinfo, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return RuntimeinfoResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return RuntimeinfoResult{}, err + } + + var res RuntimeinfoResult + return res, json.Unmarshal(body, &res) +} + func (h *httpAPI) LabelNames(ctx context.Context) ([]string, Warnings, error) { u := h.client.URL(epLabels, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) From 6c43f2ebc25a88f7d96b60fd9e66181ab13e694a Mon Sep 17 00:00:00 2001 From: Lili Cosic Date: Mon, 18 May 2020 20:08:59 +0200 Subject: [PATCH 22/74] api/prometheus/v1/api_test.go: Add test case for runtimeinfo endpoint Signed-off-by: Lili Cosic --- api/prometheus/v1/api_test.go | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index b36c380..cb6eaa5 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -144,6 +144,13 @@ func TestAPIs(t *testing.T) { } } + doRuntimeinfo := func() func() (interface{}, Warnings, error) { + return func() (interface{}, Warnings, error) { + v, err := promAPI.Runtimeinfo(context.Background()) + return v, nil, err + } + } + doLabelNames := func(label string) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { return promAPI.LabelNames(context.Background()) @@ -605,6 +612,48 @@ func TestAPIs(t *testing.T) { err: fmt.Errorf("some error"), }, + { + do: doRuntimeinfo(), + reqMethod: "GET", + reqPath: "/api/v1/status/runtimeinfo", + inErr: fmt.Errorf("some error"), + err: fmt.Errorf("some error"), + }, + + { + do: doRuntimeinfo(), + reqMethod: "GET", + reqPath: "/api/v1/status/runtimeinfo", + inRes: map[string]interface{}{ + "startTime": "2020-05-18T15:52:53.4503113Z", + "CWD": "/prometheus", + "reloadConfigSuccess": true, + "lastConfigTime": "2020-05-18T15:52:56Z", + "chunkCount": 72692, + "timeSeriesCount": 18476, + "corruptionCount": 0, + "goroutineCount": 217, + "GOMAXPROCS": 2, + "GOGC": "100", + "GODEBUG": "allocfreetrace", + "storageRetention": "1d", + }, + res: RuntimeinfoResult{ + StartTime: "2020-05-18T15:52:53.4503113Z", + CWD: "/prometheus", + ReloadConfigSuccess: true, + LastConfigTime: "2020-05-18T15:52:56Z", + ChunkCount: 72692, + TimeSeriesCount: 18476, + CorruptionCount: 0, + GoroutineCount: 217, + GOMAXPROCS: 2, + GOGC: "100", + GODEBUG: "allocfreetrace", + StorageRetention: "1d", + }, + }, + { do: doAlertManagers(), reqMethod: "GET", From 6090117ca16e5b685f9a42b2b7dc2133d1083c03 Mon Sep 17 00:00:00 2001 From: prombot Date: Tue, 19 May 2020 00:08:43 +0000 Subject: [PATCH 23/74] makefile: update Makefile.common with newer version Signed-off-by: prombot --- Makefile.common | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Makefile.common b/Makefile.common index b978dfc..9320176 100644 --- a/Makefile.common +++ b/Makefile.common @@ -150,6 +150,17 @@ else $(GO) get $(GOOPTS) -t ./... endif +.PHONY: update-go-deps +update-go-deps: + @echo ">> updating Go dependencies" + @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ + $(GO) get $$m; \ + done + GO111MODULE=$(GO111MODULE) $(GO) mod tidy +ifneq (,$(wildcard vendor)) + GO111MODULE=$(GO111MODULE) $(GO) mod vendor +endif + .PHONY: common-test-short common-test-short: $(GOTEST_DIR) @echo ">> running short tests" From 93cac27dd59791a1706278a3ea280868184cf60d Mon Sep 17 00:00:00 2001 From: RainbowMango Date: Tue, 19 May 2020 11:38:06 +0800 Subject: [PATCH 24/74] Bump github.com/golang/protobuf to v1.4.2 Signed-off-by: RainbowMango --- go.mod | 2 +- go.sum | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 61b13ed..ae48bf4 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/prometheus/client_golang require ( github.com/beorn7/perks v1.0.1 github.com/cespare/xxhash/v2 v2.1.1 - github.com/golang/protobuf v1.4.0 + github.com/golang/protobuf v1.4.2 github.com/json-iterator/go v1.1.9 github.com/kr/pretty v0.1.0 // indirect github.com/prometheus/client_model v0.2.0 diff --git a/go.sum b/go.sum index 8932e64..8be557c 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,8 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -127,6 +129,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 3afa5ab1e1ff72930328750c5b7feb10b42cc8da Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Thu, 28 May 2020 11:05:16 -0400 Subject: [PATCH 25/74] testutil/promlint: allow Kelvin as a base unit for color temperature Signed-off-by: Matt Layher --- prometheus/testutil/promlint/promlint.go | 6 ++--- prometheus/testutil/promlint/promlint_test.go | 22 ++++++++----------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/prometheus/testutil/promlint/promlint.go b/prometheus/testutil/promlint/promlint.go index e48e4d4..ec80617 100644 --- a/prometheus/testutil/promlint/promlint.go +++ b/prometheus/testutil/promlint/promlint.go @@ -313,9 +313,10 @@ var ( // Base units. "amperes": "amperes", "bytes": "bytes", - "celsius": "celsius", // Celsius is more common in practice than Kelvin. + "celsius": "celsius", // Also allow Celsius because it is common in typical Prometheus use cases. "grams": "grams", "joules": "joules", + "kelvin": "kelvin", // SI base unit, used in special cases (e.g. color temperature, scientific measurements). "meters": "meters", // Both American and international spelling permitted. "metres": "metres", "seconds": "seconds", @@ -328,8 +329,7 @@ var ( "days": "seconds", "weeks": "seconds", // Temperature. - "kelvin": "celsius", - "kelvins": "celsius", + "kelvins": "kelvin", "fahrenheit": "celsius", "rankine": "celsius", // Length. diff --git a/prometheus/testutil/promlint/promlint_test.go b/prometheus/testutil/promlint/promlint_test.go index c2d9980..f545322 100644 --- a/prometheus/testutil/promlint/promlint_test.go +++ b/prometheus/testutil/promlint/promlint_test.go @@ -164,6 +164,14 @@ x_seconds 10 # HELP x_joules Test metric. # TYPE x_joules untyped x_joules 10 +`, + }, + { + name: "kelvin", + in: ` +# HELP x_kelvin Test metric. +# TYPE x_kelvin untyped +x_kelvin 10 `, }, // bad cases. @@ -287,18 +295,6 @@ x_days 10 Text: `use base unit "seconds" instead of "days"`, }}, }, - { - name: "kelvin", - in: ` -# HELP x_kelvin Test metric. -# TYPE x_kelvin untyped -x_kelvin 10 -`, - problems: []promlint.Problem{{ - Metric: "x_kelvin", - Text: `use base unit "celsius" instead of "kelvin"`, - }}, - }, { name: "kelvins", in: ` @@ -308,7 +304,7 @@ x_kelvins 10 `, problems: []promlint.Problem{{ Metric: "x_kelvins", - Text: `use base unit "celsius" instead of "kelvins"`, + Text: `use base unit "kelvin" instead of "kelvins"`, }}, }, { From 3ba240a80fdd1c7cfb6c4f38afe8586ece5962ac Mon Sep 17 00:00:00 2001 From: beorn7 Date: Wed, 3 Jun 2020 13:56:49 +0200 Subject: [PATCH 26/74] Improve doc comments in promauto In particular, point out that `With(nil)` is valid. Signed-off-by: beorn7 --- prometheus/promauto/auto.go | 50 +++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/prometheus/promauto/auto.go b/prometheus/promauto/auto.go index 6f864f6..f8d50d1 100644 --- a/prometheus/promauto/auto.go +++ b/prometheus/promauto/auto.go @@ -127,29 +127,30 @@ // separate package? // // The main problem is that registration may fail, e.g. if a metric inconsistent -// with the newly to be registered one is already registered. Therefore, the -// Register method in the prometheus.Registerer interface returns an error, and -// the same is the case for the top-level prometheus.Register function that -// registers with the global registry. The prometheus package also provides -// MustRegister versions for both. They panic if the registration fails, and -// they clearly call this out by using the Must… idiom. Panicking is a bit -// problematic here because it doesn't just happen on input provided by the -// caller that is invalid on its own. Things are a bit more subtle here: Metric -// creation and registration tend to be spread widely over the codebase. It can -// easily happen that an incompatible metric is added to an unrelated part of -// the code, and suddenly code that used to work perfectly fine starts to panic -// (provided that the registration of the newly added metric happens before the -// registration of the previously existing metric). This may come as an even -// bigger surprise with the global registry, where simply importing another -// package can trigger a panic (if the newly imported package registers metrics -// in its init function). At least, in the prometheus package, creation of -// metrics and other collectors is separate from registration. You first create -// the metric, and then you decide explicitly if you want to register it with a -// local or the global registry, and if you want to handle the error or risk a -// panic. With the constructors in the promauto package, registration is -// automatic, and if it fails, it will always panic. Furthermore, the -// constructors will often be called in the var section of a file, which means -// that panicking will happen as a side effect of merely importing a package. +// with or equal to the newly to be registered one is already registered. +// Therefore, the Register method in the prometheus.Registerer interface returns +// an error, and the same is the case for the top-level prometheus.Register +// function that registers with the global registry. The prometheus package also +// provides MustRegister versions for both. They panic if the registration +// fails, and they clearly call this out by using the Must… idiom. Panicking is +// problematic in this case because it doesn't just happen on input provided by +// the caller that is invalid on its own. Things are a bit more subtle here: +// Metric creation and registration tend to be spread widely over the +// codebase. It can easily happen that an incompatible metric is added to an +// unrelated part of the code, and suddenly code that used to work perfectly +// fine starts to panic (provided that the registration of the newly added +// metric happens before the registration of the previously existing +// metric). This may come as an even bigger surprise with the global registry, +// where simply importing another package can trigger a panic (if the newly +// imported package registers metrics in its init function). At least, in the +// prometheus package, creation of metrics and other collectors is separate from +// registration. You first create the metric, and then you decide explicitly if +// you want to register it with a local or the global registry, and if you want +// to handle the error or risk a panic. With the constructors in the promauto +// package, registration is automatic, and if it fails, it will always +// panic. Furthermore, the constructors will often be called in the var section +// of a file, which means that panicking will happen as a side effect of merely +// importing a package. // // A separate package allows conservative users to entirely ignore it. And // whoever wants to use it, will do so explicitly, with an opportunity to read @@ -252,7 +253,8 @@ type Factory struct { } // With creates a Factory using the provided Registerer for registration of the -// created Collectors. +// created Collectors. If the provided Registerer is nil, the returned Factory +// creates Collectors that are not registered with any Registerer. func With(r prometheus.Registerer) Factory { return Factory{r} } // NewCounter works like the function of the same name in the prometheus package From 8961609f911516b04f81ac75fc4b0e0b8e455c2e Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 4 Jun 2020 10:30:51 +0100 Subject: [PATCH 27/74] Ensure that nil registers are treat as a no-op, even when wrapping. Signed-off-by: Tom Wilkie --- prometheus/promauto/auto_test.go | 29 +++++++++++++++++++++++++++++ prometheus/wrap.go | 9 +++++++++ 2 files changed, 38 insertions(+) create mode 100644 prometheus/promauto/auto_test.go diff --git a/prometheus/promauto/auto_test.go b/prometheus/promauto/auto_test.go new file mode 100644 index 0000000..5b9c7fe --- /dev/null +++ b/prometheus/promauto/auto_test.go @@ -0,0 +1,29 @@ +// Copyright 2020 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package promauto + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus" +) + +func TestWrapNil(t *testing.T) { + // A nil registerer should be treated as a no-op by promauto, even when wrapped. + registerer := prometheus.WrapRegistererWith(prometheus.Labels{"foo": "bar"}, nil) + c := With(registerer).NewCounter(prometheus.CounterOpts{ + Name: "test", + }) + c.Inc() +} diff --git a/prometheus/wrap.go b/prometheus/wrap.go index da6896a..ef6fdec 100644 --- a/prometheus/wrap.go +++ b/prometheus/wrap.go @@ -81,6 +81,9 @@ type wrappingRegisterer struct { } func (r *wrappingRegisterer) Register(c Collector) error { + if r.wrappedRegisterer == nil { + return nil + } return r.wrappedRegisterer.Register(&wrappingCollector{ wrappedCollector: c, prefix: r.prefix, @@ -89,6 +92,9 @@ func (r *wrappingRegisterer) Register(c Collector) error { } func (r *wrappingRegisterer) MustRegister(cs ...Collector) { + if r.wrappedRegisterer == nil { + return + } for _, c := range cs { if err := r.Register(c); err != nil { panic(err) @@ -97,6 +103,9 @@ func (r *wrappingRegisterer) MustRegister(cs ...Collector) { } func (r *wrappingRegisterer) Unregister(c Collector) bool { + if r.wrappedRegisterer == nil { + return false + } return r.wrappedRegisterer.Unregister(&wrappingCollector{ wrappedCollector: c, prefix: r.prefix, From 614377c5501cb1666a3b057dd23c094d6d13ab24 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 4 Jun 2020 10:57:40 +0100 Subject: [PATCH 28/74] Review feedback: use one line. Signed-off-by: Tom Wilkie --- prometheus/promauto/auto_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/prometheus/promauto/auto_test.go b/prometheus/promauto/auto_test.go index 5b9c7fe..e93817b 100644 --- a/prometheus/promauto/auto_test.go +++ b/prometheus/promauto/auto_test.go @@ -22,8 +22,6 @@ import ( func TestWrapNil(t *testing.T) { // A nil registerer should be treated as a no-op by promauto, even when wrapped. registerer := prometheus.WrapRegistererWith(prometheus.Labels{"foo": "bar"}, nil) - c := With(registerer).NewCounter(prometheus.CounterOpts{ - Name: "test", - }) + c := With(registerer).NewCounter(prometheus.CounterOpts{Name: "test"}) c.Inc() } From 9c8ba1f9451a222e7918818ecff91bac5626dd48 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 4 Jun 2020 11:51:51 +0100 Subject: [PATCH 29/74] Review feedback: add comment and tests for WrapRegistererWith. Signed-off-by: Tom Wilkie --- prometheus/promauto/auto_test.go | 8 +++----- prometheus/wrap.go | 4 +++- prometheus/wrap_test.go | 9 +++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/prometheus/promauto/auto_test.go b/prometheus/promauto/auto_test.go index e93817b..44805cb 100644 --- a/prometheus/promauto/auto_test.go +++ b/prometheus/promauto/auto_test.go @@ -19,9 +19,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -func TestWrapNil(t *testing.T) { - // A nil registerer should be treated as a no-op by promauto, even when wrapped. - registerer := prometheus.WrapRegistererWith(prometheus.Labels{"foo": "bar"}, nil) - c := With(registerer).NewCounter(prometheus.CounterOpts{Name: "test"}) - c.Inc() +func TestNil(t *testing.T) { + // A nil registerer should be treated as a no-op by promauto. + With(nil).NewCounter(prometheus.CounterOpts{Name: "test"}).Inc() } diff --git a/prometheus/wrap.go b/prometheus/wrap.go index ef6fdec..438aa5e 100644 --- a/prometheus/wrap.go +++ b/prometheus/wrap.go @@ -28,7 +28,8 @@ import ( // registered with the wrapped Registerer in a modified way. The modified // Collector adds the provided Labels to all Metrics it collects (as // ConstLabels). The Metrics collected by the unmodified Collector must not -// duplicate any of those labels. +// duplicate any of those labels. Wrapping a nil value is valid, resulting +// in a no-op Registerer. // // WrapRegistererWith provides a way to add fixed labels to a subset of // Collectors. It should not be used to add fixed labels to all metrics exposed. @@ -51,6 +52,7 @@ func WrapRegistererWith(labels Labels, reg Registerer) Registerer { // Registerer. Collectors registered with the returned Registerer will be // registered with the wrapped Registerer in a modified way. The modified // Collector adds the provided prefix to the name of all Metrics it collects. +// Wrapping a nil value is valid, resulting in a no-op Registerer. // // WrapRegistererWithPrefix is useful to have one place to prefix all metrics of // a sub-system. To make this work, register metrics of the sub-system with the diff --git a/prometheus/wrap_test.go b/prometheus/wrap_test.go index 256875a..003544e 100644 --- a/prometheus/wrap_test.go +++ b/prometheus/wrap_test.go @@ -321,3 +321,12 @@ func TestWrap(t *testing.T) { } } + +func TestNil(t *testing.T) { + // A wrapped nil registerer should be treated as a no-op, and not panic. + c := NewCounter(CounterOpts{Name: "test"}) + err := WrapRegistererWith(Labels{"foo": "bar"}, nil).Register(c) + if err != nil { + t.Fatal("registering failed:", err) + } +} From 6ce5f2ca8ad23ffb3ed2389acc285bc04bdb0089 Mon Sep 17 00:00:00 2001 From: Augustin Husson Date: Thu, 11 Jun 2020 13:02:32 +0200 Subject: [PATCH 30/74] add start/end parameter for LabelNames Signed-off-by: Augustin Husson --- api/prometheus/v1/api.go | 8 ++++++-- api/prometheus/v1/api_test.go | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index a18d2c7..42ccf42 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -232,7 +232,7 @@ type API interface { // Flags returns the flag values that Prometheus was launched with. Flags(ctx context.Context) (FlagsResult, error) // LabelNames returns all the unique label names present in the block in sorted order. - LabelNames(ctx context.Context) ([]string, Warnings, error) + LabelNames(ctx context.Context, startTime time.Time, endTime time.Time) ([]string, Warnings, error) // LabelValues performs a query for the values of the given label. LabelValues(ctx context.Context, label string) (model.LabelValues, Warnings, error) // Query performs a query for the given time. @@ -676,8 +676,12 @@ func (h *httpAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) { return res, json.Unmarshal(body, &res) } -func (h *httpAPI) LabelNames(ctx context.Context) ([]string, Warnings, error) { +func (h *httpAPI) LabelNames(ctx context.Context, startTime time.Time, endTime time.Time) ([]string, Warnings, error) { u := h.client.URL(epLabels, nil) + q := u.Query() + q.Set("start", formatTime(startTime)) + q.Set("end", formatTime(endTime)) + req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, nil, err diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index cb6eaa5..24800ba 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -153,7 +153,7 @@ func TestAPIs(t *testing.T) { doLabelNames := func(label string) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { - return promAPI.LabelNames(context.Background()) + return promAPI.LabelNames(context.Background(), time.Now().Add(-100*time.Hour), time.Now()) } } From 3defbd9c7c086d0b0d24b0e0f3db541cea084964 Mon Sep 17 00:00:00 2001 From: Augustin Husson Date: Thu, 11 Jun 2020 15:45:46 +0200 Subject: [PATCH 31/74] add start/end parameter for LabelValues Signed-off-by: Augustin Husson --- api/prometheus/v1/api.go | 8 ++++++-- api/prometheus/v1/api_test.go | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 42ccf42..b772947 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -234,7 +234,7 @@ type API interface { // LabelNames returns all the unique label names present in the block in sorted order. LabelNames(ctx context.Context, startTime time.Time, endTime time.Time) ([]string, Warnings, error) // LabelValues performs a query for the values of the given label. - LabelValues(ctx context.Context, label string) (model.LabelValues, Warnings, error) + LabelValues(ctx context.Context, label string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) // Query performs a query for the given time. Query(ctx context.Context, query string, ts time.Time) (model.Value, Warnings, error) // QueryRange performs a query for the given range. @@ -694,8 +694,12 @@ func (h *httpAPI) LabelNames(ctx context.Context, startTime time.Time, endTime t return labelNames, w, json.Unmarshal(body, &labelNames) } -func (h *httpAPI) LabelValues(ctx context.Context, label string) (model.LabelValues, Warnings, error) { +func (h *httpAPI) LabelValues(ctx context.Context, label string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) { u := h.client.URL(epLabelValues, map[string]string{"name": label}) + q := u.Query() + q.Set("start", formatTime(startTime)) + q.Set("end", formatTime(endTime)) + req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, nil, err diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 24800ba..4bc4d53 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -159,7 +159,7 @@ func TestAPIs(t *testing.T) { doLabelValues := func(label string) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { - return promAPI.LabelValues(context.Background(), label) + return promAPI.LabelValues(context.Background(), label, time.Now().Add(-100*time.Hour), time.Now()) } } From 3c8b15fa0d84373bf5e35c6a0f0626650c513b32 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Tue, 16 Jun 2020 20:57:28 +0200 Subject: [PATCH 32/74] Update dependencies Signed-off-by: beorn7 --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index ae48bf4..c91a433 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,13 @@ require ( github.com/beorn7/perks v1.0.1 github.com/cespare/xxhash/v2 v2.1.1 github.com/golang/protobuf v1.4.2 - github.com/json-iterator/go v1.1.9 + github.com/json-iterator/go v1.1.10 github.com/kr/pretty v0.1.0 // indirect github.com/prometheus/client_model v0.2.0 - github.com/prometheus/common v0.9.1 - github.com/prometheus/procfs v0.0.11 + github.com/prometheus/common v0.10.0 + github.com/prometheus/procfs v0.1.3 github.com/stretchr/testify v1.4.0 // indirect - golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f + golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.5 // indirect ) diff --git a/go.sum b/go.sum index 8be557c..1b92f6e 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= @@ -84,13 +84,13 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI= -github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -118,8 +118,8 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From cc5731c16cbea6ec23e3398f27ba14dc0ff7b709 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Tue, 16 Jun 2020 21:13:43 +0200 Subject: [PATCH 33/74] Cut v1.7.0 Signed-off-by: beorn7 --- CHANGELOG.md | 9 +++++++++ VERSION | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2481d3d..5374b99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.7.0 / 2020-06-17 + +* [CHANGE] API client: Add start/end parameters to `LabelNames` and `LabelValues`. #767 +* [FEATURE] testutil: Add `GatherAndCount` and enable filtering in `CollectAndCount` #753 +* [FEATURE] API client: Add support for `status` and `runtimeinfo` endpoints. #755 +* [ENHANCEMENT] Wrapping `nil` with a `WrapRegistererWith...` function creates a no-op `Registerer`. #764 +* [ENHANCEMENT] promlint: Allow Kelvin as a base unit for cases like color temperature. #761 +* [BUGFIX] push: Properly handle empty job and label values. #752 + ## 1.6.0 / 2020-04-28 * [FEATURE] testutil: Add lint checks for metrics, including a sub-package `promlint` to expose the linter engine for external usage. #739 #743 diff --git a/VERSION b/VERSION index dc1e644..bd8bf88 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.6.0 +1.7.0 From 94ae5774fdd77dffafd988902ec36325c02dd583 Mon Sep 17 00:00:00 2001 From: yeya24 Date: Fri, 19 Jun 2020 18:57:25 -0400 Subject: [PATCH 34/74] fix time parameter propagation in labels API Signed-off-by: yeya24 --- api/prometheus/v1/api.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index b772947..13b3646 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -682,6 +682,8 @@ func (h *httpAPI) LabelNames(ctx context.Context, startTime time.Time, endTime t q.Set("start", formatTime(startTime)) q.Set("end", formatTime(endTime)) + u.RawQuery = q.Encode() + req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, nil, err @@ -700,6 +702,8 @@ func (h *httpAPI) LabelValues(ctx context.Context, label string, startTime time. q.Set("start", formatTime(startTime)) q.Set("end", formatTime(endTime)) + u.RawQuery = q.Encode() + req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, nil, err From 7687ac213756cfe1b1849e1334f8cfb2ce15e039 Mon Sep 17 00:00:00 2001 From: Mark Hansen Date: Sun, 21 Jun 2020 13:45:59 +1000 Subject: [PATCH 35/74] histogram.go: fix copy/paste typo This method calls NewConstHistogram. Signed-off-by: Mark Hansen --- prometheus/histogram.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus/histogram.go b/prometheus/histogram.go index 3a5aac7..d4ea301 100644 --- a/prometheus/histogram.go +++ b/prometheus/histogram.go @@ -607,7 +607,7 @@ func NewConstHistogram( } // MustNewConstHistogram is a version of NewConstHistogram that panics where -// NewConstMetric would have returned an error. +// NewConstHistogram would have returned an error. func MustNewConstHistogram( desc *Desc, count uint64, From 2cbf08beaa3cd90574b458645f1d889a289c5da6 Mon Sep 17 00:00:00 2001 From: prombot Date: Tue, 23 Jun 2020 00:08:53 +0000 Subject: [PATCH 36/74] Update common Prometheus files Signed-off-by: prombot --- CODE_OF_CONDUCT.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..9a1aff4 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +## Prometheus Community Code of Conduct + +Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). From c5ba3869b101d76776810470d34dc603f8e6a355 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Tue, 23 Jun 2020 20:16:09 +0200 Subject: [PATCH 37/74] Cut v1.7.1 Signed-off-by: beorn7 --- CHANGELOG.md | 4 ++++ VERSION | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5374b99..5647371 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.1 / 2020-06-23 + +* [BUGFIX] API client: Actually propagate start/end parameters of `LabelNames` and `LabelValues`. #771 + ## 1.7.0 / 2020-06-17 * [CHANGE] API client: Add start/end parameters to `LabelNames` and `LabelValues`. #767 diff --git a/VERSION b/VERSION index bd8bf88..943f9cb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7.0 +1.7.1 From 6cd29bd38a75f22022e2af25f265c7d96cfea7bf Mon Sep 17 00:00:00 2001 From: Hima Varsha Date: Wed, 24 Jun 2020 07:35:25 -0400 Subject: [PATCH 38/74] Add support for tsdb endpoint (#773) Signed-off-by: Hima Varsha --- api/prometheus/v1/api.go | 35 +++++++++++++++++ api/prometheus/v1/api_test.go | 73 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 13b3646..9b4fc57 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -138,6 +138,7 @@ const ( epConfig = apiPrefix + "/status/config" epFlags = apiPrefix + "/status/flags" epRuntimeinfo = apiPrefix + "/status/runtimeinfo" + epTSDB = apiPrefix + "/status/tsdb" ) // AlertState models the state of an alert. @@ -254,6 +255,8 @@ type API interface { TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, error) // Metadata returns metadata about metrics currently scraped by the metric name. Metadata(ctx context.Context, metric string, limit string) (map[string][]Metadata, error) + // TSDB returns the cardinality statistics. + TSDB(ctx context.Context) (TSDBResult, error) } // AlertsResult contains the result from querying the alerts endpoint. @@ -404,6 +407,20 @@ type queryResult struct { v model.Value } +// TSDBResult contains the result from querying the tsdb endpoint. +type TSDBResult struct { + SeriesCountByMetricName []Stat `json:"seriesCountByMetricName"` + LabelValueCountByLabelName []Stat `json:"labelValueCountByLabelName"` + MemoryInBytesByLabelName []Stat `json:"memoryInBytesByLabelName"` + SeriesCountByLabelValuePair []Stat `json:"seriesCountByLabelValuePair"` +} + +// Stat models information about statistic value. +type Stat struct { + Name string `json:"name"` + Value uint64 `json:"value"` +} + func (rg *RuleGroup) UnmarshalJSON(b []byte) error { v := struct { Name string `json:"name"` @@ -883,6 +900,24 @@ func (h *httpAPI) Metadata(ctx context.Context, metric string, limit string) (ma return res, json.Unmarshal(body, &res) } +func (h *httpAPI) TSDB(ctx context.Context) (TSDBResult, error) { + u := h.client.URL(epTSDB, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return TSDBResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return TSDBResult{}, err + } + + var res TSDBResult + return res, json.Unmarshal(body, &res) + +} + // Warnings is an array of non critical errors type Warnings []string diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 4bc4d53..1cc6d20 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -216,6 +216,13 @@ func TestAPIs(t *testing.T) { } } + doTSDB := func() func() (interface{}, Warnings, error) { + return func() (interface{}, Warnings, error) { + v, err := promAPI.TSDB(context.Background()) + return v, nil, err + } + } + queryTests := []apiTest{ { do: doQuery("2", testTime), @@ -953,6 +960,72 @@ func TestAPIs(t *testing.T) { }, err: fmt.Errorf("some error"), }, + + { + do: doTSDB(), + reqMethod: "GET", + reqPath: "/api/v1/status/tsdb", + inErr: fmt.Errorf("some error"), + err: fmt.Errorf("some error"), + }, + + { + do: doTSDB(), + reqMethod: "GET", + reqPath: "/api/v1/status/tsdb", + inRes: map[string]interface{}{ + "seriesCountByMetricName": []interface{}{ + map[string]interface{}{ + "name": "kubelet_http_requests_duration_seconds_bucket", + "value": 1000, + }, + }, + "labelValueCountByLabelName": []interface{}{ + map[string]interface{}{ + "name": "__name__", + "value": 200, + }, + }, + "memoryInBytesByLabelName": []interface{}{ + map[string]interface{}{ + "name": "id", + "value": 4096, + }, + }, + "seriesCountByLabelValuePair": []interface{}{ + map[string]interface{}{ + "name": "job=kubelet", + "value": 30000, + }, + }, + }, + res: TSDBResult{ + SeriesCountByMetricName: []Stat{ + { + Name: "kubelet_http_requests_duration_seconds_bucket", + Value: 1000, + }, + }, + LabelValueCountByLabelName: []Stat{ + { + Name: "__name__", + Value: 200, + }, + }, + MemoryInBytesByLabelName: []Stat{ + { + Name: "id", + Value: 4096, + }, + }, + SeriesCountByLabelValuePair: []Stat{ + { + Name: "job=kubelet", + Value: 30000, + }, + }, + }, + }, } var tests []apiTest From b0cdec211b8bf9d5b1edabff4d32088a11f18310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Ga=C3=9F?= Date: Wed, 24 Jun 2020 17:55:36 +0200 Subject: [PATCH 39/74] Use time.Time for timestamps in Runtimeinfo (#777) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maximilian Gaß --- api/prometheus/v1/api.go | 24 ++++++++++++------------ api/prometheus/v1/api_test.go | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 9b4fc57..6af67f5 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -285,18 +285,18 @@ type FlagsResult map[string]string // RuntimeinfoResult contains the result from querying the runtimeinfo endpoint. type RuntimeinfoResult struct { - StartTime string `json:"startTime"` - CWD string `json:"CWD"` - ReloadConfigSuccess bool `json:"reloadConfigSuccess"` - LastConfigTime string `json:"lastConfigTime"` - ChunkCount int `json:"chunkCount"` - TimeSeriesCount int `json:"timeSeriesCount"` - CorruptionCount int `json:"corruptionCount"` - GoroutineCount int `json:"goroutineCount"` - GOMAXPROCS int `json:"GOMAXPROCS"` - GOGC string `json:"GOGC"` - GODEBUG string `json:"GODEBUG"` - StorageRetention string `json:"storageRetention"` + StartTime time.Time `json:"startTime"` + CWD string `json:"CWD"` + ReloadConfigSuccess bool `json:"reloadConfigSuccess"` + LastConfigTime time.Time `json:"lastConfigTime"` + ChunkCount int `json:"chunkCount"` + TimeSeriesCount int `json:"timeSeriesCount"` + CorruptionCount int `json:"corruptionCount"` + GoroutineCount int `json:"goroutineCount"` + GOMAXPROCS int `json:"GOMAXPROCS"` + GOGC string `json:"GOGC"` + GODEBUG string `json:"GODEBUG"` + StorageRetention string `json:"storageRetention"` } // SnapshotResult contains the result from querying the snapshot endpoint. diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 1cc6d20..6a37c71 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -646,10 +646,10 @@ func TestAPIs(t *testing.T) { "storageRetention": "1d", }, res: RuntimeinfoResult{ - StartTime: "2020-05-18T15:52:53.4503113Z", + StartTime: time.Date(2020, 5, 18, 15, 52, 53, 450311300, time.UTC), CWD: "/prometheus", ReloadConfigSuccess: true, - LastConfigTime: "2020-05-18T15:52:56Z", + LastConfigTime: time.Date(2020, 5, 18, 15, 52, 56, 0, time.UTC), ChunkCount: 72692, TimeSeriesCount: 18476, CorruptionCount: 0, From 916659fee0fe8ca403ce46f56ffce728666f702e Mon Sep 17 00:00:00 2001 From: Mitsuo Heijo Date: Mon, 6 Jul 2020 09:58:12 +0900 Subject: [PATCH 40/74] fix tests warning about string(int) type conversions See https://github.com/golang/go/issues/32479 Signed-off-by: Mitsuo Heijo --- prometheus/gauge_test.go | 4 ++-- prometheus/histogram_test.go | 4 ++-- prometheus/summary_test.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/prometheus/gauge_test.go b/prometheus/gauge_test.go index a2e3c14..b70da7d 100644 --- a/prometheus/gauge_test.go +++ b/prometheus/gauge_test.go @@ -139,7 +139,7 @@ func TestGaugeVecConcurrency(t *testing.T) { start.Wait() for i, v := range vals { sStreams[pick[i]] <- v - gge.WithLabelValues(string('A' + pick[i])).Add(v) + gge.WithLabelValues(string('A' + rune(pick[i]))).Add(v) } end.Done() }(vals) @@ -147,7 +147,7 @@ func TestGaugeVecConcurrency(t *testing.T) { start.Done() for i := range sStreams { - if expected, got := <-results[i], math.Float64frombits(gge.WithLabelValues(string('A'+i)).(*gauge).valBits); math.Abs(expected-got) > 0.000001 { + if expected, got := <-results[i], math.Float64frombits(gge.WithLabelValues(string('A'+rune(i))).(*gauge).valBits); math.Abs(expected-got) > 0.000001 { t.Fatalf("expected approx. %f, got %f", expected, got) return false } diff --git a/prometheus/histogram_test.go b/prometheus/histogram_test.go index 0b4826c..e779c1a 100644 --- a/prometheus/histogram_test.go +++ b/prometheus/histogram_test.go @@ -279,7 +279,7 @@ func TestHistogramVecConcurrency(t *testing.T) { go func(vals []float64) { start.Wait() for i, v := range vals { - his.WithLabelValues(string('A' + picks[i])).Observe(v) + his.WithLabelValues(string('A' + rune(picks[i]))).Observe(v) } end.Done() }(vals) @@ -292,7 +292,7 @@ func TestHistogramVecConcurrency(t *testing.T) { for i := 0; i < vecLength; i++ { m := &dto.Metric{} - s := his.WithLabelValues(string('A' + i)) + s := his.WithLabelValues(string('A' + rune(i))) s.(Histogram).Write(m) if got, want := len(m.Histogram.Bucket), len(testBuckets)-1; got != want { diff --git a/prometheus/summary_test.go b/prometheus/summary_test.go index 43b8396..eff733a 100644 --- a/prometheus/summary_test.go +++ b/prometheus/summary_test.go @@ -321,7 +321,7 @@ func TestSummaryVecConcurrency(t *testing.T) { go func(vals []float64) { start.Wait() for i, v := range vals { - sum.WithLabelValues(string('A' + picks[i])).Observe(v) + sum.WithLabelValues(string('A' + rune(picks[i]))).Observe(v) } end.Done() }(vals) @@ -334,7 +334,7 @@ func TestSummaryVecConcurrency(t *testing.T) { for i := 0; i < vecLength; i++ { m := &dto.Metric{} - s := sum.WithLabelValues(string('A' + i)) + s := sum.WithLabelValues(string('A' + rune(i))) s.(Summary).Write(m) if got, want := int(*m.Summary.SampleCount), len(allVars[i]); got != want { t.Errorf("got sample count %d for label %c, want %d", got, 'A'+i, want) From 47596498769bd438949c617efac5a77909998bc3 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Wed, 22 Jul 2020 01:42:37 +0200 Subject: [PATCH 41/74] Update collector comment about GC stop-the-world Signed-off-by: Julien Pivotto --- prometheus/go_collector.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/prometheus/go_collector.go b/prometheus/go_collector.go index ea05cf4..6f67d10 100644 --- a/prometheus/go_collector.go +++ b/prometheus/go_collector.go @@ -58,9 +58,10 @@ type goCollector struct { // collector will use the memstats from a previous collection if // runtime.ReadMemStats takes more than 1s. However, if there are no previously // collected memstats, or their collection is more than 5m ago, the collection -// will block until runtime.ReadMemStats succeeds. (The problem might be solved -// in Go1.13, see https://github.com/golang/go/issues/19812 for the related Go -// issue.) +// will block until runtime.ReadMemStats succeeds. +// +// NOTE: The problem is solved in Go 1.15, see +// https://github.com/golang/go/issues/19812 for the related Go issue. func NewGoCollector() Collector { return &goCollector{ goroutinesDesc: NewDesc( From 0c48254b6250f99d4c693efc7c6ce33c1c9083d5 Mon Sep 17 00:00:00 2001 From: Dima Kozlov Date: Wed, 22 Jul 2020 23:12:23 +0300 Subject: [PATCH 42/74] remove reference to metrics after reslicing Signed-off-by: Dima Kozlov --- prometheus/vec.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prometheus/vec.go b/prometheus/vec.go index d53848d..abe9163 100644 --- a/prometheus/vec.go +++ b/prometheus/vec.go @@ -276,7 +276,9 @@ func (m *metricMap) deleteByHashWithLabelValues( } if len(metrics) > 1 { + old := metrics m.metrics[h] = append(metrics[:i], metrics[i+1:]...) + old[len(old)-1] = metricWithLabelValues{} } else { delete(m.metrics, h) } @@ -302,7 +304,9 @@ func (m *metricMap) deleteByHashWithLabels( } if len(metrics) > 1 { + old := metrics m.metrics[h] = append(metrics[:i], metrics[i+1:]...) + old[len(old)-1] = metricWithLabelValues{} } else { delete(m.metrics, h) } From 8e5b4c249f85f2c34bc36676bf71d617de0cf870 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 14 Aug 2020 18:00:47 +0200 Subject: [PATCH 43/74] Support go 1.15 Signed-off-by: Julien Pivotto --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6f1e023..397b477 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -74,5 +74,9 @@ workflows: name: go-1-14 go_version: "1.14" run_lint: true + - test: + name: go-1-15 + go_version: "1.15" + run_lint: true # Style is only checked against the latest supported Go version. run_style: true From 32a545bf616b70a4302c266b6ca078cc56652dc1 Mon Sep 17 00:00:00 2001 From: johncming Date: Sat, 22 Aug 2020 19:32:48 +0800 Subject: [PATCH 44/74] Replace with the standard library constant. Signed-off-by: johncming --- api/prometheus/v1/api.go | 4 +--- api/prometheus/v1/api_test.go | 12 ++++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 6af67f5..549cc8d 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -117,8 +117,6 @@ func marshalPointJSONIsEmpty(ptr unsafe.Pointer) bool { } const ( - statusAPIError = 422 - apiPrefix = "/api/v1" epAlerts = apiPrefix + "/alerts" @@ -943,7 +941,7 @@ type apiResponse struct { func apiError(code int) bool { // These are the codes that Prometheus sends when it returns an error. - return code == statusAPIError || code == http.StatusBadRequest + return code == http.StatusUnprocessableEntity || code == http.StatusBadRequest } func errorTypeAndMsgFor(resp *http.Response) (ErrorType, string) { diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 6a37c71..2107575 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -84,7 +84,7 @@ func (c *apiTestClient) Do(ctx context.Context, req *http.Request) (*http.Respon if test.inStatusCode != 0 { resp.StatusCode = test.inStatusCode } else if test.inErr != nil { - resp.StatusCode = statusAPIError + resp.StatusCode = http.StatusUnprocessableEntity } else { resp.StatusCode = http.StatusOK } @@ -1118,7 +1118,7 @@ func (c *testClient) Do(ctx context.Context, req *http.Request) (*http.Response, func TestAPIClientDo(t *testing.T) { tests := []apiClientTest{ { - code: statusAPIError, + code: http.StatusUnprocessableEntity, response: &apiResponse{ Status: "error", Data: json.RawMessage(`null`), @@ -1132,7 +1132,7 @@ func TestAPIClientDo(t *testing.T) { expectedBody: `null`, }, { - code: statusAPIError, + code: http.StatusUnprocessableEntity, response: &apiResponse{ Status: "error", Data: json.RawMessage(`"test"`), @@ -1177,7 +1177,7 @@ func TestAPIClientDo(t *testing.T) { }, }, { - code: statusAPIError, + code: http.StatusUnprocessableEntity, response: "bad json", expectedErr: &Error{ Type: ErrBadResponse, @@ -1185,7 +1185,7 @@ func TestAPIClientDo(t *testing.T) { }, }, { - code: statusAPIError, + code: http.StatusUnprocessableEntity, response: &apiResponse{ Status: "success", Data: json.RawMessage(`"test"`), @@ -1196,7 +1196,7 @@ func TestAPIClientDo(t *testing.T) { }, }, { - code: statusAPIError, + code: http.StatusUnprocessableEntity, response: &apiResponse{ Status: "success", Data: json.RawMessage(`"test"`), From 64721be1b5f39aa2dd71bc41ccab5aa9bec1a3ee Mon Sep 17 00:00:00 2001 From: prombot Date: Thu, 3 Sep 2020 00:08:53 +0000 Subject: [PATCH 45/74] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index 9320176..3f3d02c 100644 --- a/Makefile.common +++ b/Makefile.common @@ -78,7 +78,7 @@ ifneq ($(shell which gotestsum),) endif endif -PROMU_VERSION ?= 0.5.0 +PROMU_VERSION ?= 0.6.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz GOLANGCI_LINT := From b54b73c7b192c9010f3a9100199d17e39ceb7071 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Mon, 7 Sep 2020 22:31:29 +0200 Subject: [PATCH 46/74] Remove spurious commas from links to the docs site I assume older Nanoc versions rendered the anchors with commas, but the current doesn't. Also, this adds the same link to another doc comment where it is also relevant. Signed-off-by: beorn7 --- prometheus/metric.go | 2 +- prometheus/summary.go | 2 +- prometheus/wrap.go | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/prometheus/metric.go b/prometheus/metric.go index 35bd8bd..a2b80b1 100644 --- a/prometheus/metric.go +++ b/prometheus/metric.go @@ -89,7 +89,7 @@ type Opts struct { // better covered by target labels set by the scraping Prometheus // server, or by one specific metric (e.g. a build_info or a // machine_role metric). See also - // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels,-not-static-scraped-labels + // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels ConstLabels Labels } diff --git a/prometheus/summary.go b/prometheus/summary.go index f3c1440..e8f3f15 100644 --- a/prometheus/summary.go +++ b/prometheus/summary.go @@ -110,7 +110,7 @@ type SummaryOpts struct { // better covered by target labels set by the scraping Prometheus // server, or by one specific metric (e.g. a build_info or a // machine_role metric). See also - // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels,-not-static-scraped-labels + // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels ConstLabels Labels // Objectives defines the quantile rank estimates with their respective diff --git a/prometheus/wrap.go b/prometheus/wrap.go index 438aa5e..c1b12f0 100644 --- a/prometheus/wrap.go +++ b/prometheus/wrap.go @@ -32,7 +32,9 @@ import ( // in a no-op Registerer. // // WrapRegistererWith provides a way to add fixed labels to a subset of -// Collectors. It should not be used to add fixed labels to all metrics exposed. +// Collectors. It should not be used to add fixed labels to all metrics +// exposed. See also +// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels // // Conflicts between Collectors registered through the original Registerer with // Collectors registered through the wrapping Registerer will still be From 64b4a9cf9dd5fff0b66a14ed685a2c686d4a4766 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 10 Sep 2020 13:14:07 +0200 Subject: [PATCH 47/74] API client: Enable fallback on status code 501, too When discussing #801, I remembered #794. While dealing with the latter, I read the HTTP RFC, stumbling upon the following: When a request method is received that is unrecognized or not implemented by an origin server, the origin server SHOULD respond with the 501 (Not Implemented) status code. When a request method is received that is known by an origin server but not allowed for the target resource, the origin server SHOULD respond with the 405 (Method Not Allowed) status code. Concluding from that, it is possible that a server desiring a fallback to GET will send a status code of 501. It is even preferred if that server does not offer any resource to be used with the POST method. Therefore, I think we should fallback to GET on a 501, too. Signed-off-by: beorn7 --- api/prometheus/v1/api.go | 5 +++-- api/prometheus/v1/api_test.go | 29 ++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 549cc8d..138a33b 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -1004,7 +1004,8 @@ func (h *apiClientImpl) Do(ctx context.Context, req *http.Request) (*http.Respon } -// DoGetFallback will attempt to do the request as-is, and on a 405 it will fallback to a GET request. +// DoGetFallback will attempt to do the request as-is, and on a 405 or 501 it +// will fallback to a GET request. func (h *apiClientImpl) DoGetFallback(ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Warnings, error) { req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(args.Encode())) if err != nil { @@ -1013,7 +1014,7 @@ func (h *apiClientImpl) DoGetFallback(ctx context.Context, u *url.URL, args url. req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, body, warnings, err := h.Do(ctx, req) - if resp != nil && resp.StatusCode == http.StatusMethodNotAllowed { + if resp != nil && (resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotImplemented) { u.RawQuery = args.Encode() req, err = http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 2107575..a85a2ab 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -1447,12 +1447,19 @@ func TestDoGetFallback(t *testing.T) { body, _ := json.Marshal(apiResp) if req.Method == http.MethodPost { - if req.URL.Path == "/blockPost" { + if req.URL.Path == "/blockPost405" { http.Error(w, string(body), http.StatusMethodNotAllowed) return } } + if req.Method == http.MethodPost { + if req.URL.Path == "/blockPost501" { + http.Error(w, string(body), http.StatusNotImplemented) + return + } + } + w.Write(body) })) // Close the server when test finishes. @@ -1483,8 +1490,24 @@ func TestDoGetFallback(t *testing.T) { t.Fatalf("Mismatch in values") } - // Do a fallbcak to a get. - u.Path = "/blockPost" + // Do a fallback to a get on 405. + u.Path = "/blockPost405" + _, b, _, err = api.DoGetFallback(context.TODO(), u, v) + if err != nil { + t.Fatalf("Error doing local request: %v", err) + } + if err := json.Unmarshal(b, resp); err != nil { + t.Fatal(err) + } + if resp.Method != http.MethodGet { + t.Fatalf("Mismatch method") + } + if resp.Values != v.Encode() { + t.Fatalf("Mismatch in values") + } + + // Do a fallback to a get on 501. + u.Path = "/blockPost501" _, b, _, err = api.DoGetFallback(context.TODO(), u, v) if err != nil { t.Fatalf("Error doing local request: %v", err) From 85aa957f631d2e252dade63ca7138946197a772c Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 10 Sep 2020 18:05:44 +0200 Subject: [PATCH 48/74] Export MetricVec (again) MetricVec was already exported in early versions of this library, but nobody really used it to implement vectors of custom Metric implementations. Now #796 has shown up with a fairly special use case for which I'd prefer a custom implementation of a special "auto-sampling histogram" outside of this library. Therefore, I'd like to reinstate support for creating vectors of custom Metric implementations. I played around for quite some while with the option of a separate package providing the tools one would need to create vectors of custom Metric implementations. However, with the current structure of the prometheus/client_golang/prometheus package, this leads to a lot of complications with circular dependencies. (The new package would need the primitives from the prometheus package, while the existing metric vectors like GaugeVec need to import the new vector package to not duplicate the implementation. Separating vector types from the main prometheus package is out of the question at this point because that would be a breaking change.) Signed-off-by: beorn7 --- prometheus/counter.go | 20 ++-- prometheus/desc.go | 2 +- prometheus/example_metricvec_test.go | 163 +++++++++++++++++++++++++++ prometheus/gauge.go | 20 ++-- prometheus/histogram.go | 22 ++-- prometheus/summary.go | 24 ++-- prometheus/value.go | 13 ++- prometheus/vec.go | 108 ++++++++++++++---- 8 files changed, 305 insertions(+), 67 deletions(-) create mode 100644 prometheus/example_metricvec_test.go diff --git a/prometheus/counter.go b/prometheus/counter.go index 0e1b48c..3f8fd79 100644 --- a/prometheus/counter.go +++ b/prometheus/counter.go @@ -163,7 +163,7 @@ func (c *counter) updateExemplar(v float64, l Labels) { // (e.g. number of HTTP requests, partitioned by response code and // method). Create instances with NewCounterVec. type CounterVec struct { - *metricVec + *MetricVec } // NewCounterVec creates a new CounterVec based on the provided CounterOpts and @@ -176,11 +176,11 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { opts.ConstLabels, ) return &CounterVec{ - metricVec: newMetricVec(desc, func(lvs ...string) Metric { + MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { if len(lvs) != len(desc.variableLabels) { panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs)) } - result := &counter{desc: desc, labelPairs: makeLabelPairs(desc, lvs), now: time.Now} + result := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: time.Now} result.init(result) // Init self-collection. return result }), @@ -188,7 +188,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { } // GetMetricWithLabelValues returns the Counter for the given slice of label -// values (same order as the VariableLabels in Desc). If that combination of +// values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Counter is created. // // It is possible to call this method without using the returned Counter to only @@ -202,7 +202,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { // Counter with the same label values is created later. // // An error is returned if the number of label values is not the same as the -// number of VariableLabels in Desc (minus any curried labels). +// number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as @@ -211,7 +211,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { // with a performance overhead (for creating and processing the Labels map). // See also the GaugeVec example. func (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) { - metric, err := v.metricVec.getMetricWithLabelValues(lvs...) + metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) if metric != nil { return metric.(Counter), err } @@ -219,19 +219,19 @@ func (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) { } // GetMetricWith returns the Counter for the given Labels map (the label names -// must match those of the VariableLabels in Desc). If that label map is +// must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Counter is created. Implications of // creating a Counter without using it and keeping the Counter for later use are // the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent -// with those of the VariableLabels in Desc (minus any curried labels). +// with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) { - metric, err := v.metricVec.getMetricWith(labels) + metric, err := v.MetricVec.GetMetricWith(labels) if metric != nil { return metric.(Counter), err } @@ -275,7 +275,7 @@ func (v *CounterVec) With(labels Labels) Counter { // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. func (v *CounterVec) CurryWith(labels Labels) (*CounterVec, error) { - vec, err := v.curryWith(labels) + vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &CounterVec{vec}, err } diff --git a/prometheus/desc.go b/prometheus/desc.go index 2f19f5e..957d93a 100644 --- a/prometheus/desc.go +++ b/prometheus/desc.go @@ -51,7 +51,7 @@ type Desc struct { // constLabelPairs contains precalculated DTO label pairs based on // the constant labels. constLabelPairs []*dto.LabelPair - // VariableLabels contains names of labels for which the metric + // variableLabels contains names of labels for which the metric // maintains variable values. variableLabels []string // id is a hash of the values of the ConstLabels and fqName. This diff --git a/prometheus/example_metricvec_test.go b/prometheus/example_metricvec_test.go new file mode 100644 index 0000000..8e893e5 --- /dev/null +++ b/prometheus/example_metricvec_test.go @@ -0,0 +1,163 @@ +// Copyright 2020 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package prometheus_test + +import ( + //lint:ignore SA1019 Need to keep deprecated package for compatibility. + "fmt" + + "github.com/golang/protobuf/proto" + + dto "github.com/prometheus/client_model/go" + + "github.com/prometheus/client_golang/prometheus" +) + +// Info implements an info pseudo-metric, which is modeled as a Gauge that +// always has a value of 1. In practice, you would just use a Gauge directly, +// but for this example, we pretend it would be useful to have a “native” +// implementation. +type Info struct { + desc *prometheus.Desc + labelPairs []*dto.LabelPair +} + +func (i Info) Desc() *prometheus.Desc { + return i.desc +} + +func (i Info) Write(out *dto.Metric) error { + out.Label = i.labelPairs + out.Gauge = &dto.Gauge{Value: proto.Float64(1)} + return nil +} + +// InfoVec is the vector version for Info. As an info metric never changes, we +// wouldn't really need to wrap GetMetricWithLabelValues and GetMetricWith +// because Info has no additional methods compared to the vanilla Metric that +// the unwrapped MetricVec methods return. However, to demonstrate all there is +// to do to fully implement a vector for a custom Metric implementation, we do +// it in this example anyway. +type InfoVec struct { + *prometheus.MetricVec +} + +func NewInfoVec(name, help string, labelNames []string) *InfoVec { + desc := prometheus.NewDesc(name, help, labelNames, nil) + return &InfoVec{ + MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric { + if len(lvs) != len(labelNames) { + panic("inconsistent label cardinality") + } + return Info{desc: desc, labelPairs: prometheus.MakeLabelPairs(desc, lvs)} + }), + } +} + +func (v *InfoVec) GetMetricWithLabelValues(lvs ...string) (Info, error) { + metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) + return metric.(Info), err +} + +func (v *InfoVec) GetMetricWith(labels prometheus.Labels) (Info, error) { + metric, err := v.MetricVec.GetMetricWith(labels) + return metric.(Info), err +} + +func (v *InfoVec) WithLabelValues(lvs ...string) Info { + i, err := v.GetMetricWithLabelValues(lvs...) + if err != nil { + panic(err) + } + return i +} + +func (v *InfoVec) With(labels prometheus.Labels) Info { + i, err := v.GetMetricWith(labels) + if err != nil { + panic(err) + } + return i +} + +func (v *InfoVec) CurryWith(labels prometheus.Labels) (*InfoVec, error) { + vec, err := v.MetricVec.CurryWith(labels) + if vec != nil { + return &InfoVec{vec}, err + } + return nil, err +} + +func (v *InfoVec) MustCurryWith(labels prometheus.Labels) *InfoVec { + vec, err := v.CurryWith(labels) + if err != nil { + panic(err) + } + return vec +} + +func ExampleMetricVec() { + + infoVec := NewInfoVec( + "library_version_info", + "Versions of the libraries used in this binary.", + []string{"library", "version"}, + ) + + infoVec.WithLabelValues("prometheus/client_golang", "1.7.1") + infoVec.WithLabelValues("k8s.io/client-go", "0.18.8") + + // Just for demonstration, let's check the state of the InfoVec by + // registering it with a custom registry and then let it collect the + // metrics. + reg := prometheus.NewRegistry() + reg.MustRegister(infoVec) + + metricFamilies, err := reg.Gather() + if err != nil || len(metricFamilies) != 1 { + panic("unexpected behavior of custom test registry") + } + fmt.Println(proto.MarshalTextString(metricFamilies[0])) + + // Output: + // name: "library_version_info" + // help: "Versions of the libraries used in this binary." + // type: GAUGE + // metric: < + // label: < + // name: "library" + // value: "k8s.io/client-go" + // > + // label: < + // name: "version" + // value: "0.18.8" + // > + // gauge: < + // value: 1 + // > + // > + // metric: < + // label: < + // name: "library" + // value: "prometheus/client_golang" + // > + // label: < + // name: "version" + // value: "1.7.1" + // > + // gauge: < + // value: 1 + // > + // > +} diff --git a/prometheus/gauge.go b/prometheus/gauge.go index d67573f..bd0733d 100644 --- a/prometheus/gauge.go +++ b/prometheus/gauge.go @@ -132,7 +132,7 @@ func (g *gauge) Write(out *dto.Metric) error { // (e.g. number of operations queued, partitioned by user and operation // type). Create instances with NewGaugeVec. type GaugeVec struct { - *metricVec + *MetricVec } // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and @@ -145,11 +145,11 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { opts.ConstLabels, ) return &GaugeVec{ - metricVec: newMetricVec(desc, func(lvs ...string) Metric { + MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { if len(lvs) != len(desc.variableLabels) { panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs)) } - result := &gauge{desc: desc, labelPairs: makeLabelPairs(desc, lvs)} + result := &gauge{desc: desc, labelPairs: MakeLabelPairs(desc, lvs)} result.init(result) // Init self-collection. return result }), @@ -157,7 +157,7 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { } // GetMetricWithLabelValues returns the Gauge for the given slice of label -// values (same order as the VariableLabels in Desc). If that combination of +// values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Gauge is created. // // It is possible to call this method without using the returned Gauge to only @@ -172,7 +172,7 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { // example. // // An error is returned if the number of label values is not the same as the -// number of VariableLabels in Desc (minus any curried labels). +// number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as @@ -180,7 +180,7 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) { - metric, err := v.metricVec.getMetricWithLabelValues(lvs...) + metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) if metric != nil { return metric.(Gauge), err } @@ -188,19 +188,19 @@ func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) { } // GetMetricWith returns the Gauge for the given Labels map (the label names -// must match those of the VariableLabels in Desc). If that label map is +// must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Gauge is created. Implications of // creating a Gauge without using it and keeping the Gauge for later use are // the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent -// with those of the VariableLabels in Desc (minus any curried labels). +// with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { - metric, err := v.metricVec.getMetricWith(labels) + metric, err := v.MetricVec.GetMetricWith(labels) if metric != nil { return metric.(Gauge), err } @@ -244,7 +244,7 @@ func (v *GaugeVec) With(labels Labels) Gauge { // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. func (v *GaugeVec) CurryWith(labels Labels) (*GaugeVec, error) { - vec, err := v.curryWith(labels) + vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &GaugeVec{vec}, err } diff --git a/prometheus/histogram.go b/prometheus/histogram.go index d4ea301..f71e286 100644 --- a/prometheus/histogram.go +++ b/prometheus/histogram.go @@ -192,7 +192,7 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr h := &histogram{ desc: desc, upperBounds: opts.Buckets, - labelPairs: makeLabelPairs(desc, labelValues), + labelPairs: MakeLabelPairs(desc, labelValues), counts: [2]*histogramCounts{{}, {}}, now: time.Now, } @@ -409,7 +409,7 @@ func (h *histogram) updateExemplar(v float64, bucket int, l Labels) { // (e.g. HTTP request latencies, partitioned by status code and method). Create // instances with NewHistogramVec. type HistogramVec struct { - *metricVec + *MetricVec } // NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and @@ -422,14 +422,14 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec { opts.ConstLabels, ) return &HistogramVec{ - metricVec: newMetricVec(desc, func(lvs ...string) Metric { + MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { return newHistogram(desc, opts, lvs...) }), } } // GetMetricWithLabelValues returns the Histogram for the given slice of label -// values (same order as the VariableLabels in Desc). If that combination of +// values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Histogram is created. // // It is possible to call this method without using the returned Histogram to only @@ -444,7 +444,7 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec { // example. // // An error is returned if the number of label values is not the same as the -// number of VariableLabels in Desc (minus any curried labels). +// number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as @@ -453,7 +453,7 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec { // with a performance overhead (for creating and processing the Labels map). // See also the GaugeVec example. func (v *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { - metric, err := v.metricVec.getMetricWithLabelValues(lvs...) + metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) if metric != nil { return metric.(Observer), err } @@ -461,19 +461,19 @@ func (v *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) } // GetMetricWith returns the Histogram for the given Labels map (the label names -// must match those of the VariableLabels in Desc). If that label map is +// must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Histogram is created. Implications of // creating a Histogram without using it and keeping the Histogram for later use // are the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent -// with those of the VariableLabels in Desc (minus any curried labels). +// with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (v *HistogramVec) GetMetricWith(labels Labels) (Observer, error) { - metric, err := v.metricVec.getMetricWith(labels) + metric, err := v.MetricVec.GetMetricWith(labels) if metric != nil { return metric.(Observer), err } @@ -517,7 +517,7 @@ func (v *HistogramVec) With(labels Labels) Observer { // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. func (v *HistogramVec) CurryWith(labels Labels) (ObserverVec, error) { - vec, err := v.curryWith(labels) + vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &HistogramVec{vec}, err } @@ -602,7 +602,7 @@ func NewConstHistogram( count: count, sum: sum, buckets: buckets, - labelPairs: makeLabelPairs(desc, labelValues), + labelPairs: MakeLabelPairs(desc, labelValues), }, nil } diff --git a/prometheus/summary.go b/prometheus/summary.go index e8f3f15..cf70071 100644 --- a/prometheus/summary.go +++ b/prometheus/summary.go @@ -208,7 +208,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary { // Use the lock-free implementation of a Summary without objectives. s := &noObjectivesSummary{ desc: desc, - labelPairs: makeLabelPairs(desc, labelValues), + labelPairs: MakeLabelPairs(desc, labelValues), counts: [2]*summaryCounts{{}, {}}, } s.init(s) // Init self-collection. @@ -221,7 +221,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary { objectives: opts.Objectives, sortedObjectives: make([]float64, 0, len(opts.Objectives)), - labelPairs: makeLabelPairs(desc, labelValues), + labelPairs: MakeLabelPairs(desc, labelValues), hotBuf: make([]float64, 0, opts.BufCap), coldBuf: make([]float64, 0, opts.BufCap), @@ -513,7 +513,7 @@ func (s quantSort) Less(i, j int) bool { // (e.g. HTTP request latencies, partitioned by status code and method). Create // instances with NewSummaryVec. type SummaryVec struct { - *metricVec + *MetricVec } // NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and @@ -535,14 +535,14 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { opts.ConstLabels, ) return &SummaryVec{ - metricVec: newMetricVec(desc, func(lvs ...string) Metric { + MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { return newSummary(desc, opts, lvs...) }), } } // GetMetricWithLabelValues returns the Summary for the given slice of label -// values (same order as the VariableLabels in Desc). If that combination of +// values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Summary is created. // // It is possible to call this method without using the returned Summary to only @@ -557,7 +557,7 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { // example. // // An error is returned if the number of label values is not the same as the -// number of VariableLabels in Desc (minus any curried labels). +// number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as @@ -566,7 +566,7 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { // with a performance overhead (for creating and processing the Labels map). // See also the GaugeVec example. func (v *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { - metric, err := v.metricVec.getMetricWithLabelValues(lvs...) + metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) if metric != nil { return metric.(Observer), err } @@ -574,19 +574,19 @@ func (v *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { } // GetMetricWith returns the Summary for the given Labels map (the label names -// must match those of the VariableLabels in Desc). If that label map is +// must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Summary is created. Implications of // creating a Summary without using it and keeping the Summary for later use are // the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent -// with those of the VariableLabels in Desc (minus any curried labels). +// with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error) { - metric, err := v.metricVec.getMetricWith(labels) + metric, err := v.MetricVec.GetMetricWith(labels) if metric != nil { return metric.(Observer), err } @@ -630,7 +630,7 @@ func (v *SummaryVec) With(labels Labels) Observer { // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. func (v *SummaryVec) CurryWith(labels Labels) (ObserverVec, error) { - vec, err := v.curryWith(labels) + vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &SummaryVec{vec}, err } @@ -716,7 +716,7 @@ func NewConstSummary( count: count, sum: sum, quantiles: quantiles, - labelPairs: makeLabelPairs(desc, labelValues), + labelPairs: MakeLabelPairs(desc, labelValues), }, nil } diff --git a/prometheus/value.go b/prometheus/value.go index 6206928..8304de4 100644 --- a/prometheus/value.go +++ b/prometheus/value.go @@ -63,7 +63,7 @@ func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *val desc: desc, valType: valueType, function: function, - labelPairs: makeLabelPairs(desc, nil), + labelPairs: MakeLabelPairs(desc, nil), } result.init(result) return result @@ -95,7 +95,7 @@ func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues desc: desc, valType: valueType, val: value, - labelPairs: makeLabelPairs(desc, labelValues), + labelPairs: MakeLabelPairs(desc, labelValues), }, nil } @@ -145,7 +145,14 @@ func populateMetric( return nil } -func makeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { +// MakeLabelPairs is a helper function to create protobuf LabelPairs from the +// variable and constant labels in the provided Desc. The values for the +// variable labels are defined by the labelValues slice, which must be in the +// same order as the corresponding variable labels in the Desc. +// +// This function is only needed for custom Metric implementations. See MetricVec +// example. +func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { totalLen := len(desc.variableLabels) + len(desc.constLabelPairs) if totalLen == 0 { // Super fast path. diff --git a/prometheus/vec.go b/prometheus/vec.go index abe9163..6ba49d8 100644 --- a/prometheus/vec.go +++ b/prometheus/vec.go @@ -20,12 +20,20 @@ import ( "github.com/prometheus/common/model" ) -// metricVec is a Collector to bundle metrics of the same name that differ in -// their label values. metricVec is not used directly (and therefore -// unexported). It is used as a building block for implementations of vectors of -// a given metric type, like GaugeVec, CounterVec, SummaryVec, and HistogramVec. -// It also handles label currying. -type metricVec struct { +// MetricVec is a Collector to bundle metrics of the same name that differ in +// their label values. MetricVec is not used directly but as a building block +// for implementations of vectors of a given metric type, like GaugeVec, +// CounterVec, SummaryVec, and HistogramVec. It is exported so that it can be +// used for custom Metric implementations. +// +// To create a FooVec for custom Metric Foo, embed a pointer to MetricVec in +// FooVec and initialize it with NewMetricVec. Implement wrappers for +// GetMetricWithLabelValues and GetMetricWith that return (Foo, error) rather +// than (Metric, error). Similarly, create a wrapper for CurryWith that returns +// (*FooVec, error) rather than (*MetricVec, error). It is recommended to also +// add the convenience methods WithLabelValues, With, and MustCurryWith, which +// panic instead of returning errors. See also the MetricVec example. +type MetricVec struct { *metricMap curry []curriedLabelValue @@ -35,9 +43,9 @@ type metricVec struct { hashAddByte func(h uint64, b byte) uint64 } -// newMetricVec returns an initialized metricVec. -func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *metricVec { - return &metricVec{ +// NewMetricVec returns an initialized metricVec. +func NewMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec { + return &MetricVec{ metricMap: &metricMap{ metrics: map[uint64][]metricWithLabelValues{}, desc: desc, @@ -63,7 +71,7 @@ func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *metricVec { // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). // See also the CounterVec example. -func (m *metricVec) DeleteLabelValues(lvs ...string) bool { +func (m *MetricVec) DeleteLabelValues(lvs ...string) bool { h, err := m.hashLabelValues(lvs) if err != nil { return false @@ -82,7 +90,7 @@ func (m *metricVec) DeleteLabelValues(lvs ...string) bool { // // This method is used for the same purpose as DeleteLabelValues(...string). See // there for pros and cons of the two methods. -func (m *metricVec) Delete(labels Labels) bool { +func (m *MetricVec) Delete(labels Labels) bool { h, err := m.hashLabels(labels) if err != nil { return false @@ -95,15 +103,32 @@ func (m *metricVec) Delete(labels Labels) bool { // show up in GoDoc. // Describe implements Collector. -func (m *metricVec) Describe(ch chan<- *Desc) { m.metricMap.Describe(ch) } +func (m *MetricVec) Describe(ch chan<- *Desc) { m.metricMap.Describe(ch) } // Collect implements Collector. -func (m *metricVec) Collect(ch chan<- Metric) { m.metricMap.Collect(ch) } +func (m *MetricVec) Collect(ch chan<- Metric) { m.metricMap.Collect(ch) } // Reset deletes all metrics in this vector. -func (m *metricVec) Reset() { m.metricMap.Reset() } +func (m *MetricVec) Reset() { m.metricMap.Reset() } -func (m *metricVec) curryWith(labels Labels) (*metricVec, error) { +// CurryWith returns a vector curried with the provided labels, i.e. the +// returned vector has those labels pre-set for all labeled operations performed +// on it. The cardinality of the curried vector is reduced accordingly. The +// order of the remaining labels stays the same (just with the curried labels +// taken out of the sequence – which is relevant for the +// (GetMetric)WithLabelValues methods). It is possible to curry a curried +// vector, but only with labels not yet used for currying before. +// +// The metrics contained in the MetricVec are shared between the curried and +// uncurried vectors. They are just accessed differently. Curried and uncurried +// vectors behave identically in terms of collection. Only one must be +// registered with a given registry (usually the uncurried version). The Reset +// method deletes all metrics, even if called on a curried vector. +// +// Note that CurryWith is usually not called directly but through a wrapper +// around MetricVec, implementing a vector for a specific Metric +// implementation, for example GaugeVec. +func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) { var ( newCurry []curriedLabelValue oldCurry = m.curry @@ -128,7 +153,7 @@ func (m *metricVec) curryWith(labels Labels) (*metricVec, error) { return nil, fmt.Errorf("%d unknown label(s) found during currying", l) } - return &metricVec{ + return &MetricVec{ metricMap: m.metricMap, curry: newCurry, hashAdd: m.hashAdd, @@ -136,7 +161,34 @@ func (m *metricVec) curryWith(labels Labels) (*metricVec, error) { }, nil } -func (m *metricVec) getMetricWithLabelValues(lvs ...string) (Metric, error) { +// GetMetricWithLabelValues returns the Metric for the given slice of label +// values (same order as the variable labels in Desc). If that combination of +// label values is accessed for the first time, a new Metric is created (by +// calling the newMetric function provided during construction of the +// MetricVec). +// +// It is possible to call this method without using the returned Metry to only +// create the new Metric but leave it in its intitial state. +// +// Keeping the Metric for later use is possible (and should be considered if +// performance is critical), but keep in mind that Reset, DeleteLabelValues and +// Delete can be used to delete the Metric from the MetricVec. In that case, the +// Metric will still exist, but it will not be exported anymore, even if a +// Metric with the same label values is created later. +// +// An error is returned if the number of label values is not the same as the +// number of variable labels in Desc (minus any curried labels). +// +// Note that for more than one label value, this method is prone to mistakes +// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as +// an alternative to avoid that type of mistake. For higher label numbers, the +// latter has a much more readable (albeit more verbose) syntax, but it comes +// with a performance overhead (for creating and processing the Labels map). +// +// Note that GetMetricWithLabelValues is usually not called directly but through +// a wrapper around MetricVec, implementing a vector for a specific Metric +// implementation, for example GaugeVec. +func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { h, err := m.hashLabelValues(lvs) if err != nil { return nil, err @@ -145,7 +197,23 @@ func (m *metricVec) getMetricWithLabelValues(lvs ...string) (Metric, error) { return m.metricMap.getOrCreateMetricWithLabelValues(h, lvs, m.curry), nil } -func (m *metricVec) getMetricWith(labels Labels) (Metric, error) { +// GetMetricWith returns the Metric for the given Labels map (the label names +// must match those of the variable labels in Desc). If that label map is +// accessed for the first time, a new Metric is created. Implications of +// creating a Metric without using it and keeping the Metric for later use +// are the same as for GetMetricWithLabelValues. +// +// An error is returned if the number and names of the Labels are inconsistent +// with those of the variable labels in Desc (minus any curried labels). +// +// This method is used for the same purpose as +// GetMetricWithLabelValues(...string). See there for pros and cons of the two +// methods. +// +// Note that GetMetricWith is usually not called directly but through a wrapper +// around MetricVec, implementing a vector for a specific Metric implementation, +// for example GaugeVec. +func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) { h, err := m.hashLabels(labels) if err != nil { return nil, err @@ -154,7 +222,7 @@ func (m *metricVec) getMetricWith(labels Labels) (Metric, error) { return m.metricMap.getOrCreateMetricWithLabels(h, labels, m.curry), nil } -func (m *metricVec) hashLabelValues(vals []string) (uint64, error) { +func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) { if err := validateLabelValues(vals, len(m.desc.variableLabels)-len(m.curry)); err != nil { return 0, err } @@ -177,7 +245,7 @@ func (m *metricVec) hashLabelValues(vals []string) (uint64, error) { return h, nil } -func (m *metricVec) hashLabels(labels Labels) (uint64, error) { +func (m *MetricVec) hashLabels(labels Labels) (uint64, error) { if err := validateValuesInLabels(labels, len(m.desc.variableLabels)-len(m.curry)); err != nil { return 0, err } From 3d1759b4c60802e6525503486a0fb1209cd46ab9 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 15 Oct 2020 17:56:09 +0200 Subject: [PATCH 49/74] Run check for unused/missing Go packages only against latest Go version The tidied up `go.mod` file tends to change between Go versions. Signed-off-by: beorn7 --- .circleci/config.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 397b477..4ad70af 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,7 +9,7 @@ jobs: parameters: go_version: type: string - run_style: + run_style_and_unused: type: boolean default: false run_lint: @@ -28,15 +28,15 @@ jobs: steps: - go/load-cache: key: v1-go<< parameters.go_version >> - - run: make check_license unused test + - run: make check_license test - when: condition: << parameters.run_lint >> steps: - run: make lint - when: - condition: << parameters.run_style >> + condition: << parameters.run_style_and_unused >> steps: - - run: make style + - run: make style unused - when: condition: << parameters.use_gomod_cache >> steps: @@ -78,5 +78,6 @@ workflows: name: go-1-15 go_version: "1.15" run_lint: true - # Style is only checked against the latest supported Go version. - run_style: true + # Style and unused/missing packages are only checked against + # the latest supported Go version. + run_style_and_unused: true From ded247442080dbf80b322f90d38e0309f18761fd Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 15 Oct 2020 14:56:43 +0200 Subject: [PATCH 50/74] Update dependencies Signed-off-by: beorn7 --- go.mod | 12 +-- go.sum | 302 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 306 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index c91a433..40be933 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,12 @@ module github.com/prometheus/client_golang require ( github.com/beorn7/perks v1.0.1 github.com/cespare/xxhash/v2 v2.1.1 - github.com/golang/protobuf v1.4.2 + github.com/golang/protobuf v1.4.3 github.com/json-iterator/go v1.1.10 - github.com/kr/pretty v0.1.0 // indirect github.com/prometheus/client_model v0.2.0 - github.com/prometheus/common v0.10.0 - github.com/prometheus/procfs v0.1.3 - github.com/stretchr/testify v1.4.0 // indirect - golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect - gopkg.in/yaml.v2 v2.2.5 // indirect + github.com/prometheus/common v0.14.0 + github.com/prometheus/procfs v0.2.0 + golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 ) go 1.11 diff --git a/go.sum b/go.sum index 1b92f6e..b6a460a 100644 --- a/go.sum +++ b/go.sum @@ -1,30 +1,85 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= 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/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 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/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= @@ -39,6 +94,12 @@ github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -46,12 +107,56 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -59,8 +164,23 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 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/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -69,31 +189,95 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= 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/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4= +github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= @@ -102,27 +286,128 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5 h1:mzjBh+S5frKOsOBobWIMAbXavqjmgO17k/2puhcFR94= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= +golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -134,11 +419,28 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 67f573aafe0f2bf815446c4a98d5ba96e7b61325 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 15 Oct 2020 14:56:55 +0200 Subject: [PATCH 51/74] Cut v1.8.0 Signed-off-by: beorn7 --- CHANGELOG.md | 8 ++++++++ VERSION | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5647371..8c995e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.8.0 / 2020-10-15 + +* [CHANGE] API client: Use `time.Time` rather than `string` for timestamps in `RuntimeinfoResult`. #777 +* [FEATURE] Export `MetricVec` to facilitate implementation of vectors of custom `Metric` types. #803 +* [FEATURE API client: Support `/status/tsdb` endpoint. #773 +* [ENHANCEMENT] API client: Enable GET fallback on status code 501. #802 +* [ENHANCEMENT] Remove `Metric` references after reslicing to free up more memory. #784 + ## 1.7.1 / 2020-06-23 * [BUGFIX] API client: Actually propagate start/end parameters of `LabelNames` and `LabelValues`. #771 diff --git a/VERSION b/VERSION index 943f9cb..27f9cd3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7.1 +1.8.0 From aa8191ab24a0bbcf4ed10f5d86d9fe9990700e10 Mon Sep 17 00:00:00 2001 From: prombot Date: Fri, 23 Oct 2020 00:08:36 +0000 Subject: [PATCH 52/74] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.common b/Makefile.common index 3f3d02c..4e325f5 100644 --- a/Makefile.common +++ b/Makefile.common @@ -245,10 +245,12 @@ common-docker-publish: $(PUBLISH_DOCKER_ARCHS) $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" +DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION))) .PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS) common-docker-tag-latest: $(TAG_DOCKER_ARCHS) $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" + docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" .PHONY: common-docker-manifest common-docker-manifest: From 469ec2747b6f7c53600f2b6df40cf3e46e582eb1 Mon Sep 17 00:00:00 2001 From: sbookworm Date: Sat, 10 Oct 2020 16:37:17 +0800 Subject: [PATCH 53/74] add the NewPidFileFn to helper Signed-off-by: sbookworm --- prometheus/process_collector.go | 21 +++++++++ prometheus/process_collector_test.go | 64 ++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/prometheus/process_collector.go b/prometheus/process_collector.go index 9b80979..c46702d 100644 --- a/prometheus/process_collector.go +++ b/prometheus/process_collector.go @@ -15,7 +15,11 @@ package prometheus import ( "errors" + "fmt" + "io/ioutil" "os" + "strconv" + "strings" ) type processCollector struct { @@ -149,3 +153,20 @@ func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) } ch <- NewInvalidMetric(desc, err) } + +// NewPidFileFn returns a function that retrieves a pid from the specified file. +// It is meant to be used for the PidFn field in ProcessCollectorOpts. +func NewPidFileFn(pidFilePath string) func() (int, error) { + return func() (int, error) { + content, err := ioutil.ReadFile(pidFilePath) + if err != nil { + return 0, fmt.Errorf("can't read pid file %q: %+v", pidFilePath, err) + } + pid, err := strconv.Atoi(strings.TrimSpace(string(content))) + if err != nil { + return 0, fmt.Errorf("can't parse pid file %q: %+v", pidFilePath, err) + } + + return pid, nil + } +} diff --git a/prometheus/process_collector_test.go b/prometheus/process_collector_test.go index 8651d4f..7b19c5e 100644 --- a/prometheus/process_collector_test.go +++ b/prometheus/process_collector_test.go @@ -18,8 +18,11 @@ package prometheus import ( "bytes" "errors" + "fmt" "os" + "path/filepath" "regexp" + "strings" "testing" "github.com/prometheus/common/expfmt" @@ -101,3 +104,64 @@ func TestProcessCollector(t *testing.T) { t.Errorf("%d metrics collected, want 1", n) } } + +func TestNewPidFileFn(t *testing.T) { + folderPath, err := os.Getwd() + if err != nil { + t.Error("failed to get current path") + } + mockPidFilePath := filepath.Join(folderPath, "mockPidFile") + defer os.Remove(mockPidFilePath) + + testCases := []struct { + mockPidFile func() + expectedErrPrefix string + expectedPid int + desc string + }{ + { + mockPidFile: func() { + os.Remove(mockPidFilePath) + }, + expectedErrPrefix: "can't read pid file", + expectedPid: 0, + desc: "no existed pid file", + }, + { + mockPidFile: func() { + os.Remove(mockPidFilePath) + f, _ := os.Create(mockPidFilePath) + f.Write([]byte("abc")) + f.Close() + }, + expectedErrPrefix: "can't parse pid file", + expectedPid: 0, + desc: "existed pid file, error pid number", + }, + { + mockPidFile: func() { + os.Remove(mockPidFilePath) + f, _ := os.Create(mockPidFilePath) + f.Write([]byte("123")) + f.Close() + }, + expectedErrPrefix: "", + expectedPid: 123, + desc: "existed pid file, correct pid number", + }, + } + + for _, tc := range testCases { + fn := NewPidFileFn(mockPidFilePath) + if fn == nil { + t.Error("Should not get nil PidFileFn") + } + + tc.mockPidFile() + + if pid, err := fn(); pid != tc.expectedPid || (err != nil && !strings.HasPrefix(err.Error(), tc.expectedErrPrefix)) { + fmt.Println(err.Error()) + t.Error(tc.desc) + } + } +} From c2caa7a1e99fb1a6c9ec1d5de0ddfbd38c05e410 Mon Sep 17 00:00:00 2001 From: prombot Date: Wed, 4 Nov 2020 00:08:58 +0000 Subject: [PATCH 54/74] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index 4e325f5..3ac29c6 100644 --- a/Makefile.common +++ b/Makefile.common @@ -78,7 +78,7 @@ ifneq ($(shell which gotestsum),) endif endif -PROMU_VERSION ?= 0.6.0 +PROMU_VERSION ?= 0.7.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz GOLANGCI_LINT := From 39b478e90c0bbd869817725d4553687513b7cf01 Mon Sep 17 00:00:00 2001 From: Bartlomiej Plotka Date: Fri, 20 Nov 2020 20:58:16 +0100 Subject: [PATCH 55/74] Added example api code showing how to add auth tokens and user agents to prom client. (#817) * Added example api code showing how to add auth tokens and user agents to prom client. Signed-off-by: Bartlomiej Plotka * Ran go mod tidy. Signed-off-by: Bartlomiej Plotka --- api/prometheus/v1/example_test.go | 114 ++++++++++++++++++++++++++++++ go.sum | 4 ++ 2 files changed, 118 insertions(+) diff --git a/api/prometheus/v1/example_test.go b/api/prometheus/v1/example_test.go index ac7189a..1ff5d10 100644 --- a/api/prometheus/v1/example_test.go +++ b/api/prometheus/v1/example_test.go @@ -18,11 +18,13 @@ package v1_test import ( "context" "fmt" + "net/http" "os" "time" "github.com/prometheus/client_golang/api" v1 "github.com/prometheus/client_golang/api/prometheus/v1" + "github.com/prometheus/common/config" ) func ExampleAPI_query() { @@ -76,6 +78,118 @@ func ExampleAPI_queryRange() { fmt.Printf("Result:\n%v\n", result) } +type userAgentRoundTripper struct { + name string + rt http.RoundTripper +} + +// RoundTrip implements the http.RoundTripper interface. +func (u userAgentRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + if r.UserAgent() == "" { + // The specification of http.RoundTripper says that it shouldn't mutate + // the request so make a copy of req.Header since this is all that is + // modified. + r2 := new(http.Request) + *r2 = *r + r2.Header = make(http.Header) + for k, s := range r.Header { + r2.Header[k] = s + } + r2.Header.Set("User-Agent", u.name) + r = r2 + } + return u.rt.RoundTrip(r) +} + +func ExampleAPI_queryRangeWithUserAgent() { + client, err := api.NewClient(api.Config{ + Address: "http://demo.robustperception.io:9090", + RoundTripper: userAgentRoundTripper{name: "Client-Golang", rt: api.DefaultRoundTripper}, + }) + if err != nil { + fmt.Printf("Error creating client: %v\n", err) + os.Exit(1) + } + + v1api := v1.NewAPI(client) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + r := v1.Range{ + Start: time.Now().Add(-time.Hour), + End: time.Now(), + Step: time.Minute, + } + result, warnings, err := v1api.QueryRange(ctx, "rate(prometheus_tsdb_head_samples_appended_total[5m])", r) + if err != nil { + fmt.Printf("Error querying Prometheus: %v\n", err) + os.Exit(1) + } + if len(warnings) > 0 { + fmt.Printf("Warnings: %v\n", warnings) + } + fmt.Printf("Result:\n%v\n", result) +} + +func ExampleAPI_queryRangeWithBasicAuth() { + client, err := api.NewClient(api.Config{ + Address: "http://demo.robustperception.io:9090", + // We can use amazing github.com/prometheus/common/config helper! + RoundTripper: config.NewBasicAuthRoundTripper("me", "defintely_me", "", api.DefaultRoundTripper), + }) + if err != nil { + fmt.Printf("Error creating client: %v\n", err) + os.Exit(1) + } + + v1api := v1.NewAPI(client) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + r := v1.Range{ + Start: time.Now().Add(-time.Hour), + End: time.Now(), + Step: time.Minute, + } + result, warnings, err := v1api.QueryRange(ctx, "rate(prometheus_tsdb_head_samples_appended_total[5m])", r) + if err != nil { + fmt.Printf("Error querying Prometheus: %v\n", err) + os.Exit(1) + } + if len(warnings) > 0 { + fmt.Printf("Warnings: %v\n", warnings) + } + fmt.Printf("Result:\n%v\n", result) +} + +func ExampleAPI_queryRangeWithAuthBearerToken() { + client, err := api.NewClient(api.Config{ + Address: "http://demo.robustperception.io:9090", + // We can use amazing github.com/prometheus/common/config helper! + RoundTripper: config.NewBearerAuthRoundTripper("secret_token", api.DefaultRoundTripper), + }) + if err != nil { + fmt.Printf("Error creating client: %v\n", err) + os.Exit(1) + } + + v1api := v1.NewAPI(client) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + r := v1.Range{ + Start: time.Now().Add(-time.Hour), + End: time.Now(), + Step: time.Minute, + } + result, warnings, err := v1api.QueryRange(ctx, "rate(prometheus_tsdb_head_samples_appended_total[5m])", r) + if err != nil { + fmt.Printf("Error querying Prometheus: %v\n", err) + os.Exit(1) + } + if len(warnings) > 0 { + fmt.Printf("Warnings: %v\n", warnings) + } + fmt.Printf("Result:\n%v\n", result) +} + func ExampleAPI_series() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", diff --git a/go.sum b/go.sum index b6a460a..4d4fa85 100644 --- a/go.sum +++ b/go.sum @@ -143,6 +143,7 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -189,6 +190,7 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= @@ -333,6 +335,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -370,6 +373,7 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From cf6dc827807a19a925656652203f34a788f1c035 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sun, 29 Nov 2020 11:59:33 +0100 Subject: [PATCH 56/74] Correct spelling: possibilites -> possibilities Signed-off-by: Michael Vetter --- prometheus/promhttp/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus/promhttp/http.go b/prometheus/promhttp/http.go index 5e1c454..c95f9c8 100644 --- a/prometheus/promhttp/http.go +++ b/prometheus/promhttp/http.go @@ -99,7 +99,7 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { inFlightSem = make(chan struct{}, opts.MaxRequestsInFlight) } if opts.Registry != nil { - // Initialize all possibilites that can occur below. + // Initialize all possibilities that can occur below. errCnt.WithLabelValues("gathering") errCnt.WithLabelValues("encoding") if err := opts.Registry.Register(errCnt); err != nil { From 34ca1203775369991cf963e1b71fe1f230064dc5 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Wed, 2 Dec 2020 19:53:38 +0100 Subject: [PATCH 57/74] Be more explicit about the multi-line properties of MultiError Signed-off-by: beorn7 --- prometheus/promhttp/http.go | 8 ++++++-- prometheus/registry.go | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/prometheus/promhttp/http.go b/prometheus/promhttp/http.go index c95f9c8..d86d0cf 100644 --- a/prometheus/promhttp/http.go +++ b/prometheus/promhttp/http.go @@ -303,8 +303,12 @@ type Logger interface { // HandlerOpts specifies options how to serve metrics via an http.Handler. The // zero value of HandlerOpts is a reasonable default. type HandlerOpts struct { - // ErrorLog specifies an optional logger for errors collecting and - // serving metrics. If nil, errors are not logged at all. + // ErrorLog specifies an optional Logger for errors collecting and + // serving metrics. If nil, errors are not logged at all. Note that the + // type of a reported error is often prometheus.MultiError, which + // formats into a multi-line error string. If you want to avoid the + // latter, create a Logger implementation that detects a + // prometheus.MultiError and formats the contained errors into one line. ErrorLog Logger // ErrorHandling defines how errors are handled. Note that errors are // logged regardless of the configured ErrorHandling provided ErrorLog diff --git a/prometheus/registry.go b/prometheus/registry.go index ba94405..48f5ef9 100644 --- a/prometheus/registry.go +++ b/prometheus/registry.go @@ -215,6 +215,8 @@ func (err AlreadyRegisteredError) Error() string { // by a Gatherer to report multiple errors during MetricFamily gathering. type MultiError []error +// Error formats the contained errors as a bullet point list, preceded by the +// total number of errors. Note that this results in a multi-line string. func (errs MultiError) Error() string { if len(errs) == 0 { return "" From 98eb6cbf7ccf0487b869d70efeebbb09dab53be1 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Wed, 9 Dec 2020 17:58:53 +0100 Subject: [PATCH 58/74] promhttp: Correctly detect invalid metric and label names Without this fix, the `InstrumentHandler...` middlewares get locked in an endless loop in case of an invalid Collector, eating all the memory. Signed-off-by: beorn7 --- prometheus/promhttp/instrument_server.go | 91 +++++++++++-------- prometheus/promhttp/instrument_server_test.go | 31 ++++++- 2 files changed, 79 insertions(+), 43 deletions(-) diff --git a/prometheus/promhttp/instrument_server.go b/prometheus/promhttp/instrument_server.go index 9db2438..ab037db 100644 --- a/prometheus/promhttp/instrument_server.go +++ b/prometheus/promhttp/instrument_server.go @@ -43,14 +43,14 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl // InstrumentHandlerDuration is a middleware that wraps the provided // http.Handler to observe the request duration with the provided ObserverVec. -// The ObserverVec must have zero, one, or two non-const non-curried labels. For -// those, the only allowed label names are "code" and "method". The function -// panics otherwise. The Observe method of the Observer in the ObserverVec is -// called with the request duration in seconds. Partitioning happens by HTTP -// status code and/or HTTP method if the respective instance label names are -// present in the ObserverVec. For unpartitioned observations, use an -// ObserverVec with zero labels. Note that partitioning of Histograms is -// expensive and should be used judiciously. +// The ObserverVec must have valid metric and label names and must have zero, +// one, or two non-const non-curried labels. For those, the only allowed label +// names are "code" and "method". The function panics otherwise. The Observe +// method of the Observer in the ObserverVec is called with the request duration +// in seconds. Partitioning happens by HTTP status code and/or HTTP method if +// the respective instance label names are present in the ObserverVec. For +// unpartitioned observations, use an ObserverVec with zero labels. Note that +// partitioning of Histograms is expensive and should be used judiciously. // // If the wrapped Handler does not set a status code, a status code of 200 is assumed. // @@ -79,12 +79,13 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) ht } // InstrumentHandlerCounter is a middleware that wraps the provided http.Handler -// to observe the request result with the provided CounterVec. The CounterVec -// must have zero, one, or two non-const non-curried labels. For those, the only -// allowed label names are "code" and "method". The function panics -// otherwise. Partitioning of the CounterVec happens by HTTP status code and/or -// HTTP method if the respective instance label names are present in the -// CounterVec. For unpartitioned counting, use a CounterVec with zero labels. +// to observe the request result with the provided CounterVec. The CounterVec +// must have valid metric and label names and must have zero, one, or two +// non-const non-curried labels. For those, the only allowed label names are +// "code" and "method". The function panics otherwise. Partitioning of the +// CounterVec happens by HTTP status code and/or HTTP method if the respective +// instance label names are present in the CounterVec. For unpartitioned +// counting, use a CounterVec with zero labels. // // If the wrapped Handler does not set a status code, a status code of 200 is assumed. // @@ -110,14 +111,15 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) // InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided // http.Handler to observe with the provided ObserverVec the request duration -// until the response headers are written. The ObserverVec must have zero, one, -// or two non-const non-curried labels. For those, the only allowed label names -// are "code" and "method". The function panics otherwise. The Observe method of -// the Observer in the ObserverVec is called with the request duration in -// seconds. Partitioning happens by HTTP status code and/or HTTP method if the -// respective instance label names are present in the ObserverVec. For -// unpartitioned observations, use an ObserverVec with zero labels. Note that -// partitioning of Histograms is expensive and should be used judiciously. +// until the response headers are written. The ObserverVec must have valid +// metric and label names and must have zero, one, or two non-const non-curried +// labels. For those, the only allowed label names are "code" and "method". The +// function panics otherwise. The Observe method of the Observer in the +// ObserverVec is called with the request duration in seconds. Partitioning +// happens by HTTP status code and/or HTTP method if the respective instance +// label names are present in the ObserverVec. For unpartitioned observations, +// use an ObserverVec with zero labels. Note that partitioning of Histograms is +// expensive and should be used judiciously. // // If the wrapped Handler panics before calling WriteHeader, no value is // reported. @@ -139,15 +141,15 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha } // InstrumentHandlerRequestSize is a middleware that wraps the provided -// http.Handler to observe the request size with the provided ObserverVec. The -// ObserverVec must have zero, one, or two non-const non-curried labels. For -// those, the only allowed label names are "code" and "method". The function -// panics otherwise. The Observe method of the Observer in the ObserverVec is -// called with the request size in bytes. Partitioning happens by HTTP status -// code and/or HTTP method if the respective instance label names are present in -// the ObserverVec. For unpartitioned observations, use an ObserverVec with zero -// labels. Note that partitioning of Histograms is expensive and should be used -// judiciously. +// http.Handler to observe the request size with the provided ObserverVec. The +// ObserverVec must have valid metric and label names and must have zero, one, +// or two non-const non-curried labels. For those, the only allowed label names +// are "code" and "method". The function panics otherwise. The Observe method of +// the Observer in the ObserverVec is called with the request size in +// bytes. Partitioning happens by HTTP status code and/or HTTP method if the +// respective instance label names are present in the ObserverVec. For +// unpartitioned observations, use an ObserverVec with zero labels. Note that +// partitioning of Histograms is expensive and should be used judiciously. // // If the wrapped Handler does not set a status code, a status code of 200 is assumed. // @@ -174,15 +176,15 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) } // InstrumentHandlerResponseSize is a middleware that wraps the provided -// http.Handler to observe the response size with the provided ObserverVec. The -// ObserverVec must have zero, one, or two non-const non-curried labels. For -// those, the only allowed label names are "code" and "method". The function -// panics otherwise. The Observe method of the Observer in the ObserverVec is -// called with the response size in bytes. Partitioning happens by HTTP status -// code and/or HTTP method if the respective instance label names are present in -// the ObserverVec. For unpartitioned observations, use an ObserverVec with zero -// labels. Note that partitioning of Histograms is expensive and should be used -// judiciously. +// http.Handler to observe the response size with the provided ObserverVec. The +// ObserverVec must have valid metric and label names and must have zero, one, +// or two non-const non-curried labels. For those, the only allowed label names +// are "code" and "method". The function panics otherwise. The Observe method of +// the Observer in the ObserverVec is called with the response size in +// bytes. Partitioning happens by HTTP status code and/or HTTP method if the +// respective instance label names are present in the ObserverVec. For +// unpartitioned observations, use an ObserverVec with zero labels. Note that +// partitioning of Histograms is expensive and should be used judiciously. // // If the wrapped Handler does not set a status code, a status code of 200 is assumed. // @@ -198,6 +200,11 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler }) } +// checkLabels returns whether the provided Collector has a non-const, +// non-curried label named "code" and/or "method". It panics if the provided +// Collector does not have a Desc or has more than one Desc or its Desc is +// invalid. It also panics if the Collector has any non-const, non-curried +// labels that are not named "code" or "method". func checkLabels(c prometheus.Collector) (code bool, method bool) { // TODO(beorn7): Remove this hacky way to check for instance labels // once Descriptors can have their dimensionality queried. @@ -225,6 +232,10 @@ func checkLabels(c prometheus.Collector) (code bool, method bool) { close(descc) + // Make sure the Collector has a valid Desc by registering it with a + // temporary registry. + prometheus.NewRegistry().MustRegister(c) + // Create a ConstMetric with the Desc. Since we don't know how many // variable labels there are, try for as long as it needs. for err := errors.New("dummy"); err != nil; lvs = append(lvs, magicString) { diff --git a/prometheus/promhttp/instrument_server_test.go b/prometheus/promhttp/instrument_server_test.go index 11e42f2..07387f3 100644 --- a/prometheus/promhttp/instrument_server_test.go +++ b/prometheus/promhttp/instrument_server_test.go @@ -25,6 +25,7 @@ import ( func TestLabelCheck(t *testing.T) { scenarios := map[string]struct { + metricName string // Defaults to "c". varLabels []string constLabels []string curriedLabels []string @@ -48,7 +49,7 @@ func TestLabelCheck(t *testing.T) { curriedLabels: []string{}, ok: true, }, - "cade and method as var labels": { + "code and method as var labels": { varLabels: []string{"method", "code"}, constLabels: []string{}, curriedLabels: []string{}, @@ -60,6 +61,12 @@ func TestLabelCheck(t *testing.T) { curriedLabels: []string{"dings", "bums"}, ok: true, }, + "all labels used with an invalid const label name": { + varLabels: []string{"code", "method"}, + constLabels: []string{"in-valid", "bar"}, + curriedLabels: []string{"dings", "bums"}, + ok: false, + }, "unsupported var label": { varLabels: []string{"foo"}, constLabels: []string{}, @@ -96,17 +103,35 @@ func TestLabelCheck(t *testing.T) { curriedLabels: []string{"method"}, ok: false, }, + "invalid name and otherwise empty": { + metricName: "in-valid", + varLabels: []string{}, + constLabels: []string{}, + curriedLabels: []string{}, + ok: false, + }, + "invalid name with all the otherwise valid labels": { + metricName: "in-valid", + varLabels: []string{"code", "method"}, + constLabels: []string{"foo", "bar"}, + curriedLabels: []string{"dings", "bums"}, + ok: false, + }, } for name, sc := range scenarios { t.Run(name, func(t *testing.T) { + metricName := sc.metricName + if metricName == "" { + metricName = "c" + } constLabels := prometheus.Labels{} for _, l := range sc.constLabels { constLabels[l] = "dummy" } c := prometheus.NewCounterVec( prometheus.CounterOpts{ - Name: "c", + Name: metricName, Help: "c help", ConstLabels: constLabels, }, @@ -114,7 +139,7 @@ func TestLabelCheck(t *testing.T) { ) o := prometheus.ObserverVec(prometheus.NewHistogramVec( prometheus.HistogramOpts{ - Name: "c", + Name: metricName, Help: "c help", ConstLabels: constLabels, }, From 8d16199dea38f0d689454d6e56ffaeb1d381f6bb Mon Sep 17 00:00:00 2001 From: beorn7 Date: Wed, 16 Dec 2020 20:46:34 +0100 Subject: [PATCH 59/74] Update dependencies Signed-off-by: beorn7 --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 40be933..f22bf0e 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,9 @@ require ( github.com/golang/protobuf v1.4.3 github.com/json-iterator/go v1.1.10 github.com/prometheus/client_model v0.2.0 - github.com/prometheus/common v0.14.0 + github.com/prometheus/common v0.15.0 github.com/prometheus/procfs v0.2.0 - golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 + golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e ) go 1.11 diff --git a/go.sum b/go.sum index 4d4fa85..b1338c6 100644 --- a/go.sum +++ b/go.sum @@ -248,8 +248,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4= -github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= @@ -370,8 +370,8 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= From 80ca9cdc4e154cf193f8b1b8fddb1f24a3bcc475 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Wed, 16 Dec 2020 20:46:50 +0100 Subject: [PATCH 60/74] Cut release 1.9.0 Signed-off-by: beorn7 --- CHANGELOG.md | 5 +++++ VERSION | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c995e9..e3dc6aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.9.0 / 2020-12-17 + +* [FEATURE] `NewPidFileFn` helper to create process collectors for processes whose PID is read from a file. #804 +* [BUGFIX] promhttp: Prevent endless loop in `InstrumentHandler...` middlewares with invalid metric or label names. #823 + ## 1.8.0 / 2020-10-15 * [CHANGE] API client: Use `time.Time` rather than `string` for timestamps in `RuntimeinfoResult`. #777 diff --git a/VERSION b/VERSION index 27f9cd3..f8e233b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.0 +1.9.0 From 75d7516f2a100997f739a5bc520bf08bb44a2600 Mon Sep 17 00:00:00 2001 From: yeya24 Date: Tue, 29 Dec 2020 13:49:42 -0500 Subject: [PATCH 61/74] support matchers in labels API Signed-off-by: yeya24 --- api/prometheus/v1/api.go | 14 ++++++++---- api/prometheus/v1/api_test.go | 40 ++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 138a33b..afac2fc 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -231,9 +231,9 @@ type API interface { // Flags returns the flag values that Prometheus was launched with. Flags(ctx context.Context) (FlagsResult, error) // LabelNames returns all the unique label names present in the block in sorted order. - LabelNames(ctx context.Context, startTime time.Time, endTime time.Time) ([]string, Warnings, error) + LabelNames(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]string, Warnings, error) // LabelValues performs a query for the values of the given label. - LabelValues(ctx context.Context, label string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) + LabelValues(ctx context.Context, label string, matches []string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) // Query performs a query for the given time. Query(ctx context.Context, query string, ts time.Time) (model.Value, Warnings, error) // QueryRange performs a query for the given range. @@ -691,11 +691,14 @@ func (h *httpAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) { return res, json.Unmarshal(body, &res) } -func (h *httpAPI) LabelNames(ctx context.Context, startTime time.Time, endTime time.Time) ([]string, Warnings, error) { +func (h *httpAPI) LabelNames(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]string, Warnings, error) { u := h.client.URL(epLabels, nil) q := u.Query() q.Set("start", formatTime(startTime)) q.Set("end", formatTime(endTime)) + for _, m := range matches { + q.Add("match[]", m) + } u.RawQuery = q.Encode() @@ -711,11 +714,14 @@ func (h *httpAPI) LabelNames(ctx context.Context, startTime time.Time, endTime t return labelNames, w, json.Unmarshal(body, &labelNames) } -func (h *httpAPI) LabelValues(ctx context.Context, label string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) { +func (h *httpAPI) LabelValues(ctx context.Context, label string, matches []string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) { u := h.client.URL(epLabelValues, map[string]string{"name": label}) q := u.Query() q.Set("start", formatTime(startTime)) q.Set("end", formatTime(endTime)) + for _, m := range matches { + q.Add("match[]", m) + } u.RawQuery = q.Encode() diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index a85a2ab..0529adb 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -151,15 +151,15 @@ func TestAPIs(t *testing.T) { } } - doLabelNames := func(label string) func() (interface{}, Warnings, error) { + doLabelNames := func(matches []string) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { - return promAPI.LabelNames(context.Background(), time.Now().Add(-100*time.Hour), time.Now()) + return promAPI.LabelNames(context.Background(), matches, time.Now().Add(-100*time.Hour), time.Now()) } } - doLabelValues := func(label string) func() (interface{}, Warnings, error) { + doLabelValues := func(matches []string, label string) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { - return promAPI.LabelValues(context.Background(), label, time.Now().Add(-100*time.Hour), time.Now()) + return promAPI.LabelValues(context.Background(), label, matches, time.Now().Add(-100*time.Hour), time.Now()) } } @@ -359,14 +359,14 @@ func TestAPIs(t *testing.T) { }, { - do: doLabelNames("mylabel"), + do: doLabelNames(nil), inRes: []string{"val1", "val2"}, reqMethod: "GET", reqPath: "/api/v1/labels", res: []string{"val1", "val2"}, }, { - do: doLabelNames("mylabel"), + do: doLabelNames(nil), inRes: []string{"val1", "val2"}, inWarnings: []string{"a"}, reqMethod: "GET", @@ -376,14 +376,14 @@ func TestAPIs(t *testing.T) { }, { - do: doLabelNames("mylabel"), + do: doLabelNames(nil), inErr: fmt.Errorf("some error"), reqMethod: "GET", reqPath: "/api/v1/labels", err: fmt.Errorf("some error"), }, { - do: doLabelNames("mylabel"), + do: doLabelNames(nil), inErr: fmt.Errorf("some error"), inWarnings: []string{"a"}, reqMethod: "GET", @@ -391,16 +391,24 @@ func TestAPIs(t *testing.T) { err: fmt.Errorf("some error"), warnings: []string{"a"}, }, + { + do: doLabelNames([]string{"up"}), + inRes: []string{"val1", "val2"}, + reqMethod: "GET", + reqPath: "/api/v1/labels", + reqParam: url.Values{"match[]": {"up"}}, + res: []string{"val1", "val2"}, + }, { - do: doLabelValues("mylabel"), + do: doLabelValues(nil, "mylabel"), inRes: []string{"val1", "val2"}, reqMethod: "GET", reqPath: "/api/v1/label/mylabel/values", res: model.LabelValues{"val1", "val2"}, }, { - do: doLabelValues("mylabel"), + do: doLabelValues(nil, "mylabel"), inRes: []string{"val1", "val2"}, inWarnings: []string{"a"}, reqMethod: "GET", @@ -410,14 +418,14 @@ func TestAPIs(t *testing.T) { }, { - do: doLabelValues("mylabel"), + do: doLabelValues(nil, "mylabel"), inErr: fmt.Errorf("some error"), reqMethod: "GET", reqPath: "/api/v1/label/mylabel/values", err: fmt.Errorf("some error"), }, { - do: doLabelValues("mylabel"), + do: doLabelValues(nil, "mylabel"), inErr: fmt.Errorf("some error"), inWarnings: []string{"a"}, reqMethod: "GET", @@ -425,6 +433,14 @@ func TestAPIs(t *testing.T) { err: fmt.Errorf("some error"), warnings: []string{"a"}, }, + { + do: doLabelValues([]string{"up"}, "mylabel"), + inRes: []string{"val1", "val2"}, + reqMethod: "GET", + reqPath: "/api/v1/label/mylabel/values", + reqParam: url.Values{"match[]": {"up"}}, + res: model.LabelValues{"val1", "val2"}, + }, { do: doSeries("up", testTime.Add(-time.Minute), testTime), From b6ac49fc5950dea48b1a02e8539f7336a42adb9d Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Sat, 16 Jan 2021 13:57:36 +0100 Subject: [PATCH 62/74] Add SECURITY.md This commit adds a security policy to this repository. SECURITY.md files are threated in a special way by GitHub, helping users to know how to best submit security issues for the projects. In this case, we simply point to our existing documentation on prometheus.io. The content of this file will be synced automatically with the prometheus/prometheus repository, as our security policy covers all the repositories. This sync is automated with prombot, like other files (LICENSE, Makefile.common). https://docs.github.com/en/free-pro-team@latest/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository Signed-off-by: Julien Pivotto --- SECURITY.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..67741f0 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,6 @@ +# Reporting a security issue + +The Prometheus security policy, including how to report vulnerabilities, can be +found here: + +https://prometheus.io/docs/operating/security/ From 0c0d90feb9268e7e7aae310e053299ef0bae7347 Mon Sep 17 00:00:00 2001 From: Shengjing Zhu Date: Sat, 23 Jan 2021 01:47:50 +0800 Subject: [PATCH 63/74] Bump prometheus/procfs to 0.3.0 to fix building on riscv64 This picks up https://github.com/prometheus/procfs/pull/325 Signed-off-by: Shengjing Zhu --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f22bf0e..53a92c6 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/json-iterator/go v1.1.10 github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.15.0 - github.com/prometheus/procfs v0.2.0 + github.com/prometheus/procfs v0.3.0 golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e ) diff --git a/go.sum b/go.sum index b1338c6..4b0adb0 100644 --- a/go.sum +++ b/go.sum @@ -257,8 +257,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0 h1:Uehi/mxLK0eiUc0H0++5tpMGTexB8wZ598MIgU8VpDM= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= From 595a1d580c6f36ee5ca2cb2552566a51bd27405c Mon Sep 17 00:00:00 2001 From: yeya24 Date: Wed, 3 Feb 2021 19:44:12 -0500 Subject: [PATCH 64/74] update comment Signed-off-by: yeya24 --- api/prometheus/v1/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index afac2fc..20205b9 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -230,9 +230,9 @@ type API interface { DeleteSeries(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) error // Flags returns the flag values that Prometheus was launched with. Flags(ctx context.Context) (FlagsResult, error) - // LabelNames returns all the unique label names present in the block in sorted order. + // LabelNames returns the unique label names present in the block in sorted order by given time range and matchers. LabelNames(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]string, Warnings, error) - // LabelValues performs a query for the values of the given label. + // LabelValues performs a query for the values of the given label, time range and matchers. LabelValues(ctx context.Context, label string, matches []string, startTime time.Time, endTime time.Time) (model.LabelValues, Warnings, error) // Query performs a query for the given time. Query(ctx context.Context, query string, ts time.Time) (model.Value, Warnings, error) From 9443f4449b7f4656af6e0646b1154bb527749460 Mon Sep 17 00:00:00 2001 From: debiandebiandebian Date: Mon, 8 Feb 2021 08:58:11 +0900 Subject: [PATCH 65/74] Fix typo in comments Signed-off-by: debiandebiandebian --- prometheus/metric.go | 2 +- prometheus/vec.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/prometheus/metric.go b/prometheus/metric.go index a2b80b1..bf18593 100644 --- a/prometheus/metric.go +++ b/prometheus/metric.go @@ -58,7 +58,7 @@ type Metric interface { } // Opts bundles the options for creating most Metric types. Each metric -// implementation XXX has its own XXXOpts type, but in most cases, it is just be +// implementation XXX has its own XXXOpts type, but in most cases, it is just // an alias of this type (which might change when the requirement arises.) // // It is mandatory to set Name to a non-empty string. All other fields are diff --git a/prometheus/vec.go b/prometheus/vec.go index 6ba49d8..4ababe6 100644 --- a/prometheus/vec.go +++ b/prometheus/vec.go @@ -167,8 +167,8 @@ func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) { // calling the newMetric function provided during construction of the // MetricVec). // -// It is possible to call this method without using the returned Metry to only -// create the new Metric but leave it in its intitial state. +// It is possible to call this method without using the returned Metric to only +// create the new Metric but leave it in its initial state. // // Keeping the Metric for later use is possible (and should be considered if // performance is critical), but keep in mind that Reset, DeleteLabelValues and From a60c63e31368c74a9563e1e7ea5d789fa7b6d2a9 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 11 Mar 2021 20:14:20 +0100 Subject: [PATCH 66/74] Update dependencies Signed-off-by: beorn7 --- api/prometheus/v1/example_test.go | 2 +- go.mod | 6 ++-- go.sum | 55 ++++++------------------------- 3 files changed, 14 insertions(+), 49 deletions(-) diff --git a/api/prometheus/v1/example_test.go b/api/prometheus/v1/example_test.go index 1ff5d10..8182902 100644 --- a/api/prometheus/v1/example_test.go +++ b/api/prometheus/v1/example_test.go @@ -164,7 +164,7 @@ func ExampleAPI_queryRangeWithAuthBearerToken() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", // We can use amazing github.com/prometheus/common/config helper! - RoundTripper: config.NewBearerAuthRoundTripper("secret_token", api.DefaultRoundTripper), + RoundTripper: config.NewAuthorizationCredentialsRoundTripper("Bearer", "secret_token", api.DefaultRoundTripper), }) if err != nil { fmt.Printf("Error creating client: %v\n", err) diff --git a/go.mod b/go.mod index 53a92c6..23aba57 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,9 @@ require ( github.com/golang/protobuf v1.4.3 github.com/json-iterator/go v1.1.10 github.com/prometheus/client_model v0.2.0 - github.com/prometheus/common v0.15.0 - github.com/prometheus/procfs v0.3.0 - golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e + github.com/prometheus/common v0.18.0 + github.com/prometheus/procfs v0.6.0 + golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 ) go 1.11 diff --git a/go.sum b/go.sum index 4b0adb0..853e0d5 100644 --- a/go.sum +++ b/go.sum @@ -7,7 +7,6 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -21,9 +20,7 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -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/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -59,18 +56,13 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -80,19 +72,14 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -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/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= @@ -101,11 +88,10 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -145,7 +131,6 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -158,7 +143,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -188,7 +172,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -221,7 +204,6 @@ github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9 github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -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/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= @@ -233,32 +215,26 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -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/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= -github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.3.0 h1:Uehi/mxLK0eiUc0H0++5tpMGTexB8wZ598MIgU8VpDM= -github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -268,7 +244,6 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -282,9 +257,7 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -340,21 +313,18 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5 h1:mzjBh+S5frKOsOBobWIMAbXavqjmgO17k/2puhcFR94= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -366,12 +336,11 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -416,11 +385,9 @@ google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLY google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -436,9 +403,7 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 6635a8f35b3d62935a2ef23d28c9d5086fc2de56 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 11 Mar 2021 20:45:00 +0100 Subject: [PATCH 67/74] Bump minumim required Go version to 1.13 Since 1.16 is out, we still support the last four minor releases. The bump was required by the prometheus/procfs package using the new `%w` printf directives. However, it also allows us to remove some special casing about build info. Signed-off-by: beorn7 --- .circleci/config.yml | 20 ++++---------------- README.md | 2 +- go.mod | 2 +- prometheus/build_info.go | 29 ----------------------------- prometheus/build_info_pre_1.12.go | 22 ---------------------- prometheus/go_collector.go | 7 ++++++- 6 files changed, 12 insertions(+), 70 deletions(-) delete mode 100644 prometheus/build_info.go delete mode 100644 prometheus/build_info_pre_1.12.go diff --git a/.circleci/config.yml b/.circleci/config.yml index 4ad70af..127348e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,22 +50,6 @@ workflows: client_golang: jobs: # Refer to README.md for the currently supported versions. - - test: - name: go-1-9 - go_version: "1.9" - use_gomod_cache: false - - test: - name: go-1-10 - go_version: "1.10" - use_gomod_cache: false - - test: - name: go-1-11 - go_version: "1.11" - run_lint: true - - test: - name: go-1-12 - go_version: "1.12" - run_lint: true - test: name: go-1-13 go_version: "1.13" @@ -78,6 +62,10 @@ workflows: name: go-1-15 go_version: "1.15" run_lint: true + - test: + name: go-1-16 + go_version: "1.16" + run_lint: true # Style and unused/missing packages are only checked against # the latest supported Go version. run_style_and_unused: true diff --git a/README.md b/README.md index 9bab32a..e111c36 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This is the [Go](http://golang.org) client library for instrumenting application code, and one for creating clients that talk to the Prometheus HTTP API. -__This library requires Go1.9 or later.__ The minimum required patch releases for older Go versions are Go1.9.7 and Go1.10.3. +__This library requires Go1.13 or later.__ ## Important note about releases and stability diff --git a/go.mod b/go.mod index 23aba57..65ec5a7 100644 --- a/go.mod +++ b/go.mod @@ -11,4 +11,4 @@ require ( golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 ) -go 1.11 +go 1.13 diff --git a/prometheus/build_info.go b/prometheus/build_info.go deleted file mode 100644 index 288f0e8..0000000 --- a/prometheus/build_info.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build go1.12 - -package prometheus - -import "runtime/debug" - -// readBuildInfo is a wrapper around debug.ReadBuildInfo for Go 1.12+. -func readBuildInfo() (path, version, sum string) { - path, version, sum = "unknown", "unknown", "unknown" - if bi, ok := debug.ReadBuildInfo(); ok { - path = bi.Main.Path - version = bi.Main.Version - sum = bi.Main.Sum - } - return -} diff --git a/prometheus/build_info_pre_1.12.go b/prometheus/build_info_pre_1.12.go deleted file mode 100644 index 6609e28..0000000 --- a/prometheus/build_info_pre_1.12.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build !go1.12 - -package prometheus - -// readBuildInfo is a wrapper around debug.ReadBuildInfo for Go versions before -// 1.12. Remove this whole file once the minimum supported Go version is 1.12. -func readBuildInfo() (path, version, sum string) { - return "unknown", "unknown", "unknown" -} diff --git a/prometheus/go_collector.go b/prometheus/go_collector.go index 6f67d10..db43ca5 100644 --- a/prometheus/go_collector.go +++ b/prometheus/go_collector.go @@ -384,7 +384,12 @@ type memStatsMetrics []struct { // https://github.com/povilasv/prommod for an example of a collector for the // module dependencies. func NewBuildInfoCollector() Collector { - path, version, sum := readBuildInfo() + path, version, sum := "unknown", "unknown", "unknown" + if bi, ok := debug.ReadBuildInfo(); ok { + path = bi.Main.Path + version = bi.Main.Version + sum = bi.Main.Sum + } c := &selfCollector{MustNewConstMetric( NewDesc( "go_build_info", From 4c24ae8b133eacf6753e0862a40005cd8352ca04 Mon Sep 17 00:00:00 2001 From: Kien Nguyen Date: Sat, 6 Mar 2021 14:46:30 +0700 Subject: [PATCH 68/74] Add buildinfo method Co-authored-by: Lili Cosic Signed-off-by: Kien Nguyen --- api/prometheus/v1/api.go | 30 ++++++++++++++++++++++++++++ api/prometheus/v1/api_test.go | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 20205b9..44309df 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -135,6 +135,7 @@ const ( epCleanTombstones = apiPrefix + "/admin/tsdb/clean_tombstones" epConfig = apiPrefix + "/status/config" epFlags = apiPrefix + "/status/flags" + epBuildinfo = apiPrefix + "/status/buildinfo" epRuntimeinfo = apiPrefix + "/status/runtimeinfo" epTSDB = apiPrefix + "/status/tsdb" ) @@ -238,6 +239,8 @@ type API interface { Query(ctx context.Context, query string, ts time.Time) (model.Value, Warnings, error) // QueryRange performs a query for the given range. QueryRange(ctx context.Context, query string, r Range) (model.Value, Warnings, error) + // Buildinfo returns various build information properties about the Prometheus server + Buildinfo(ctx context.Context) (BuildinfoResult, error) // Runtimeinfo returns the various runtime information properties about the Prometheus server. Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) // Series finds series by label matchers. @@ -281,6 +284,16 @@ type ConfigResult struct { // FlagsResult contains the result from querying the flag endpoint. type FlagsResult map[string]string +// BuildinfoResult contains the results from querying the buildinfo endpoint. +type BuildinfoResult struct { + Version string `json:"version"` + Revision string `json:"revision"` + Branch string `json:"branch"` + BuildUser string `json:"buildUser"` + BuildDate string `json:"buildDate"` + GoVersion string `json:"goVersion"` +} + // RuntimeinfoResult contains the result from querying the runtimeinfo endpoint. type RuntimeinfoResult struct { StartTime time.Time `json:"startTime"` @@ -674,6 +687,23 @@ func (h *httpAPI) Flags(ctx context.Context) (FlagsResult, error) { return res, json.Unmarshal(body, &res) } +func (h *httpAPI) Buildinfo(ctx context.Context) (BuildinfoResult, error) { + u := h.client.URL(epBuildinfo, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return BuildinfoResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return BuildinfoResult{}, err + } + + var res BuildinfoResult + return res, json.Unmarshal(body, &res) +} + func (h *httpAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) { u := h.client.URL(epRuntimeinfo, nil) diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 0529adb..a1f0515 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -144,6 +144,13 @@ func TestAPIs(t *testing.T) { } } + doBuildinfo := func() func() (interface{}, Warnings, error) { + return func() (interface{}, Warnings, error) { + v, err := promAPI.Buildinfo(context.Background()) + return v, nil, err + } + } + doRuntimeinfo := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Runtimeinfo(context.Background()) @@ -635,6 +642,36 @@ func TestAPIs(t *testing.T) { err: fmt.Errorf("some error"), }, + { + do: doBuildinfo(), + reqMethod: "GET", + reqPath: "/api/v1/status/buildinfo", + inErr: fmt.Errorf("some error"), + err: fmt.Errorf("some error"), + }, + + { + do: doBuildinfo(), + reqMethod: "GET", + reqPath: "/api/v1/status/buildinfo", + inRes: map[string]interface{}{ + "version": "2.23.0", + "revision": "26d89b4b0776fe4cd5a3656dfa520f119a375273", + "branch": "HEAD", + "buildUser": "root@37609b3a0a21", + "buildDate": "20201126-10:56:17", + "goVersion": "go1.15.5", + }, + res: BuildinfoResult{ + Version: "2.23.0", + Revision: "26d89b4b0776fe4cd5a3656dfa520f119a375273", + Branch: "HEAD", + BuildUser: "root@37609b3a0a21", + BuildDate: "20201126-10:56:17", + GoVersion: "go1.15.5", + }, + }, + { do: doRuntimeinfo(), reqMethod: "GET", From fbc3e40366e820f27555552640f656df7e1c11e2 Mon Sep 17 00:00:00 2001 From: prombot Date: Tue, 16 Mar 2021 00:21:09 +0100 Subject: [PATCH 69/74] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index 3ac29c6..2b73d86 100644 --- a/Makefile.common +++ b/Makefile.common @@ -83,7 +83,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_ GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v1.18.0 +GOLANGCI_LINT_VERSION ?= v1.36.0 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) From e92283d64489126e6541d425273968d7c634146d Mon Sep 17 00:00:00 2001 From: beorn7 Date: Tue, 16 Mar 2021 16:17:19 +0100 Subject: [PATCH 70/74] Fix linter ignores Signed-off-by: beorn7 --- prometheus/counter_test.go | 2 +- prometheus/desc.go | 2 +- prometheus/example_metricvec_test.go | 2 +- prometheus/examples_test.go | 2 +- prometheus/histogram.go | 2 +- prometheus/histogram_test.go | 2 +- prometheus/metric.go | 2 +- prometheus/promhttp/delegator.go | 6 ++---- prometheus/promhttp/instrument_server_test.go | 6 ++---- prometheus/registry.go | 2 +- prometheus/registry_test.go | 2 +- prometheus/summary.go | 2 +- prometheus/value.go | 2 +- prometheus/wrap.go | 2 +- prometheus/wrap_test.go | 2 +- 15 files changed, 17 insertions(+), 21 deletions(-) diff --git a/prometheus/counter_test.go b/prometheus/counter_test.go index 56652a0..6b359b1 100644 --- a/prometheus/counter_test.go +++ b/prometheus/counter_test.go @@ -19,7 +19,7 @@ import ( "testing" "time" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" diff --git a/prometheus/desc.go b/prometheus/desc.go index 957d93a..4bb816a 100644 --- a/prometheus/desc.go +++ b/prometheus/desc.go @@ -20,7 +20,7 @@ import ( "strings" "github.com/cespare/xxhash/v2" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/model" diff --git a/prometheus/example_metricvec_test.go b/prometheus/example_metricvec_test.go index 8e893e5..54f924b 100644 --- a/prometheus/example_metricvec_test.go +++ b/prometheus/example_metricvec_test.go @@ -14,9 +14,9 @@ package prometheus_test import ( - //lint:ignore SA1019 Need to keep deprecated package for compatibility. "fmt" + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" diff --git a/prometheus/examples_test.go b/prometheus/examples_test.go index 8bc051a..a73ed18 100644 --- a/prometheus/examples_test.go +++ b/prometheus/examples_test.go @@ -22,7 +22,7 @@ import ( "strings" "time" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/expfmt" diff --git a/prometheus/histogram.go b/prometheus/histogram.go index f71e286..3346fa1 100644 --- a/prometheus/histogram.go +++ b/prometheus/histogram.go @@ -22,7 +22,7 @@ import ( "sync/atomic" "time" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" diff --git a/prometheus/histogram_test.go b/prometheus/histogram_test.go index e779c1a..3514e81 100644 --- a/prometheus/histogram_test.go +++ b/prometheus/histogram_test.go @@ -24,7 +24,7 @@ import ( "testing/quick" "time" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" diff --git a/prometheus/metric.go b/prometheus/metric.go index bf18593..dc12191 100644 --- a/prometheus/metric.go +++ b/prometheus/metric.go @@ -17,7 +17,7 @@ import ( "strings" "time" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/model" diff --git a/prometheus/promhttp/delegator.go b/prometheus/promhttp/delegator.go index 5070e72..e7c0d05 100644 --- a/prometheus/promhttp/delegator.go +++ b/prometheus/promhttp/delegator.go @@ -83,8 +83,7 @@ type readerFromDelegator struct{ *responseWriterDelegator } type pusherDelegator struct{ *responseWriterDelegator } func (d closeNotifierDelegator) CloseNotify() <-chan bool { - //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to - //remove support from client_golang yet. + //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. return d.ResponseWriter.(http.CloseNotifier).CloseNotify() } func (d flusherDelegator) Flush() { @@ -348,8 +347,7 @@ func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) deleg } id := 0 - //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to - //remove support from client_golang yet. + //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. if _, ok := w.(http.CloseNotifier); ok { id += closeNotifier } diff --git a/prometheus/promhttp/instrument_server_test.go b/prometheus/promhttp/instrument_server_test.go index 07387f3..545ae4c 100644 --- a/prometheus/promhttp/instrument_server_test.go +++ b/prometheus/promhttp/instrument_server_test.go @@ -319,8 +319,7 @@ func (t *testFlusher) Flush() { t.flushCalled = true } func TestInterfaceUpgrade(t *testing.T) { w := &testResponseWriter{} d := newDelegator(w, nil) - //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to - //remove support from client_golang yet. + //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. d.(http.CloseNotifier).CloseNotify() if !w.closeNotifyCalled { t.Error("CloseNotify not called") @@ -339,8 +338,7 @@ func TestInterfaceUpgrade(t *testing.T) { f := &testFlusher{} d = newDelegator(f, nil) - //lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to - //remove support from client_golang yet. + //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. if _, ok := d.(http.CloseNotifier); ok { t.Error("delegator unexpectedly implements http.CloseNotifier") } diff --git a/prometheus/registry.go b/prometheus/registry.go index 48f5ef9..383a7f5 100644 --- a/prometheus/registry.go +++ b/prometheus/registry.go @@ -26,7 +26,7 @@ import ( "unicode/utf8" "github.com/cespare/xxhash/v2" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/expfmt" diff --git a/prometheus/registry_test.go b/prometheus/registry_test.go index 48596cd..0ff7a64 100644 --- a/prometheus/registry_test.go +++ b/prometheus/registry_test.go @@ -33,7 +33,7 @@ import ( dto "github.com/prometheus/client_model/go" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/expfmt" diff --git a/prometheus/summary.go b/prometheus/summary.go index cf70071..fb5ce22 100644 --- a/prometheus/summary.go +++ b/prometheus/summary.go @@ -23,7 +23,7 @@ import ( "time" "github.com/beorn7/perks/quantile" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" diff --git a/prometheus/value.go b/prometheus/value.go index 8304de4..c778711 100644 --- a/prometheus/value.go +++ b/prometheus/value.go @@ -19,7 +19,7 @@ import ( "time" "unicode/utf8" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" diff --git a/prometheus/wrap.go b/prometheus/wrap.go index c1b12f0..74ee932 100644 --- a/prometheus/wrap.go +++ b/prometheus/wrap.go @@ -17,7 +17,7 @@ import ( "fmt" "sort" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" diff --git a/prometheus/wrap_test.go b/prometheus/wrap_test.go index 003544e..8bd5e60 100644 --- a/prometheus/wrap_test.go +++ b/prometheus/wrap_test.go @@ -19,7 +19,7 @@ import ( "strings" "testing" - //lint:ignore SA1019 Need to keep deprecated package for compatibility. + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" From b7a5327d5a47e06f3fa707b47bee4801202c7430 Mon Sep 17 00:00:00 2001 From: prombot Date: Thu, 18 Mar 2021 00:01:39 +0000 Subject: [PATCH 71/74] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index 2b73d86..fea1103 100644 --- a/Makefile.common +++ b/Makefile.common @@ -78,7 +78,7 @@ ifneq ($(shell which gotestsum),) endif endif -PROMU_VERSION ?= 0.7.0 +PROMU_VERSION ?= 0.10.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz GOLANGCI_LINT := From 853777d20b988c8552bb7a5949f8f1ec425ebf7e Mon Sep 17 00:00:00 2001 From: beorn7 Date: Wed, 17 Mar 2021 18:46:56 +0100 Subject: [PATCH 72/74] Cut v1.10.0 Signed-off-by: beorn7 --- CHANGELOG.md | 7 +++++++ VERSION | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3dc6aa..790b9cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.10.0 / 2021-03-18 + +* [CHANGE] Minimum required Go version is now 1.13. +* [CHANGE] API client: Add matchers to `LabelNames` and `LabesValues`. #828 +* [FEATURE] API client: Add buildinfo call. #841 +* [BUGFIX] Fix build on riscv64. #833 + ## 1.9.0 / 2020-12-17 * [FEATURE] `NewPidFileFn` helper to create process collectors for processes whose PID is read from a file. #804 diff --git a/VERSION b/VERSION index f8e233b..81c871d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.9.0 +1.10.0 From 0df87794a40681fdf4294550ebfeb2482d53f7c6 Mon Sep 17 00:00:00 2001 From: prombot Date: Mon, 22 Mar 2021 00:01:45 +0000 Subject: [PATCH 73/74] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index fea1103..86b2870 100644 --- a/Makefile.common +++ b/Makefile.common @@ -78,7 +78,7 @@ ifneq ($(shell which gotestsum),) endif endif -PROMU_VERSION ?= 0.10.0 +PROMU_VERSION ?= 0.11.1 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz GOLANGCI_LINT := From 78eb8b854b29388aa59327fc879c5fa9638c6e75 Mon Sep 17 00:00:00 2001 From: prombot Date: Wed, 31 Mar 2021 00:01:21 +0000 Subject: [PATCH 74/74] Update common Prometheus files Signed-off-by: prombot --- .circleci/config.yml | 91 +++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 127348e..a62505e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,9 +1,7 @@ ---- version: 2.1 - orbs: go: circleci/go@0.2.0 - + prometheus: prometheus/prometheus@0.11.0 jobs: test: parameters: @@ -19,53 +17,52 @@ jobs: type: boolean default: true docker: - - image: circleci/golang:<< parameters.go_version >> + - image: circleci/golang:<< parameters.go_version >> working_directory: /go/src/github.com/prometheus/client_golang steps: - - checkout - - when: - condition: << parameters.use_gomod_cache >> - steps: - - go/load-cache: - key: v1-go<< parameters.go_version >> - - run: make check_license test - - when: - condition: << parameters.run_lint >> - steps: - - run: make lint - - when: - condition: << parameters.run_style_and_unused >> - steps: - - run: make style unused - - when: - condition: << parameters.use_gomod_cache >> - steps: - - go/save-cache: - key: v1-go<< parameters.go_version >> - - store_test_results: - path: test-results - + - checkout + - when: + condition: << parameters.use_gomod_cache >> + steps: + - go/load-cache: + key: v1-go<< parameters.go_version >> + - run: make check_license test + - when: + condition: << parameters.run_lint >> + steps: + - run: make lint + - when: + condition: << parameters.run_style_and_unused >> + steps: + - run: make style unused + - when: + condition: << parameters.use_gomod_cache >> + steps: + - go/save-cache: + key: v1-go<< parameters.go_version >> + - store_test_results: + path: test-results workflows: version: 2 client_golang: jobs: - # Refer to README.md for the currently supported versions. - - test: - name: go-1-13 - go_version: "1.13" - run_lint: true - - test: - name: go-1-14 - go_version: "1.14" - run_lint: true - - test: - name: go-1-15 - go_version: "1.15" - run_lint: true - - test: - name: go-1-16 - go_version: "1.16" - run_lint: true - # Style and unused/missing packages are only checked against - # the latest supported Go version. - run_style_and_unused: true + # Refer to README.md for the currently supported versions. + - test: + name: go-1-13 + go_version: "1.13" + run_lint: true + - test: + name: go-1-14 + go_version: "1.14" + run_lint: true + - test: + name: go-1-15 + go_version: "1.15" + run_lint: true + - test: + name: go-1-16 + go_version: "1.16" + run_lint: true + # Style and unused/missing packages are only checked against + # the latest supported Go version. + run_style_and_unused: true