bump client golang to v1.6.0 (#7191)

* bump github.com/prometheus/client_golang to v1.6.0

Signed-off-by: RainbowMango <renhongcai@huawei.com>
This commit is contained in:
Hongcai Ren 2020-04-30 19:24:47 +08:00 committed by GitHub
parent 05038b48bd
commit 1c48005911
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 461 additions and 20 deletions

4
go.mod
View File

@ -26,7 +26,6 @@ require (
github.com/go-openapi/swag v0.19.9 // indirect
github.com/go-openapi/validate v0.19.8 // indirect
github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.4.0 // indirect
github.com/golang/snappy v0.0.1
github.com/google/pprof v0.0.0-20200417002340-c6e0a841f49a
github.com/googleapis/gnostic v0.4.0 // indirect
@ -52,10 +51,9 @@ require (
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
github.com/prometheus/alertmanager v0.20.0
github.com/prometheus/client_golang v1.5.1
github.com/prometheus/client_golang v1.6.0
github.com/prometheus/client_model v0.2.0
github.com/prometheus/common v0.9.1
github.com/prometheus/procfs v0.0.11 // indirect
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd

4
go.sum
View File

@ -653,8 +653,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
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/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=

View File

@ -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,

View File

@ -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),

View File

@ -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 uint64
WorkingSetSize uint64
QuotaPeakPagedPoolUsage uint64
QuotaPagedPoolUsage uint64
QuotaPeakNonPagedPoolUsage uint64
QuotaNonPagedPoolUsage uint64
PagefileUsage uint64
PeakPagefileUsage uint64
PrivateUsage uint64
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) {

View File

@ -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 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 {
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()
}

View File

@ -0,0 +1,386 @@
// 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 promlint provides a linter for Prometheus metrics.
package promlint
import (
"fmt"
"io"
"regexp"
"sort"
"strings"
"github.com/prometheus/common/expfmt"
dto "github.com/prometheus/client_model/go"
)
// 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
}
// 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
}
// 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 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
// and issue description.
func (l *Linter) Lint() ([]Problem, error) {
var problems []Problem
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
}
problems = append(problems, lint(mf)...)
}
}
for _, mf := range l.mfs {
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 []Problem
// Expect all metrics to have help text available.
if mf.Help == nil {
problems = append(problems, newProblem(mf, "no help text"))
}
return problems
}
// lintMetricUnits detects issues with metric unit names.
func lintMetricUnits(mf *dto.MetricFamily) []Problem {
var problems []Problem
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 = append(problems, newProblem(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 []Problem
isCounter := mf.GetType() == dto.MetricType_COUNTER
isUntyped := mf.GetType() == dto.MetricType_UNTYPED
hasTotalSuffix := strings.HasSuffix(mf.GetName(), "_total")
switch {
case isCounter && !hasTotalSuffix:
problems = append(problems, newProblem(mf, `counter metrics should have "_total" suffix`))
case !isUntyped && !isCounter && hasTotalSuffix:
problems = append(problems, newProblem(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 []Problem
isHistogram := t == dto.MetricType_HISTOGRAM
isSummary := t == dto.MetricType_SUMMARY
n := mf.GetName()
if !isHistogram && strings.HasSuffix(n, "_bucket") {
problems = append(problems, newProblem(mf, `non-histogram metrics should not have "_bucket" suffix`))
}
if !isHistogram && !isSummary && strings.HasSuffix(n, "_count") {
problems = append(problems, newProblem(mf, `non-histogram and non-summary metrics should not have "_count" suffix`))
}
if !isHistogram && !isSummary && strings.HasSuffix(n, "_sum") {
problems = append(problems, newProblem(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 = append(problems, newProblem(mf, `non-histogram metrics should not have "le" label`))
}
if !isSummary && ln == "quantile" {
problems = append(problems, newProblem(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 []Problem
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 = append(problems, newProblem(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 []Problem
if strings.Contains(mf.GetName(), ":") {
problems = append(problems, newProblem(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 []Problem
if camelCase.FindString(mf.GetName()) != "" {
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 = append(problems, newProblem(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 []Problem
n := strings.ToLower(mf.GetName())
for _, s := range unitAbbreviations {
if strings.Contains(n, "_"+s+"_") || strings.HasSuffix(n, "_"+s) {
problems = append(problems, newProblem(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",
}
)

View File

@ -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 (
@ -136,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 {

3
vendor/modules.txt vendored
View File

@ -275,7 +275,7 @@ github.com/pkg/errors
github.com/pmezard/go-difflib/difflib
# github.com/prometheus/alertmanager v0.20.0
github.com/prometheus/alertmanager/api/v2/models
# github.com/prometheus/client_golang v1.5.1
# github.com/prometheus/client_golang v1.6.0
github.com/prometheus/client_golang/api
github.com/prometheus/client_golang/api/prometheus/v1
github.com/prometheus/client_golang/prometheus
@ -283,6 +283,7 @@ github.com/prometheus/client_golang/prometheus/internal
github.com/prometheus/client_golang/prometheus/promauto
github.com/prometheus/client_golang/prometheus/promhttp
github.com/prometheus/client_golang/prometheus/testutil
github.com/prometheus/client_golang/prometheus/testutil/promlint
# github.com/prometheus/client_model v0.2.0
github.com/prometheus/client_model/go
# github.com/prometheus/common v0.9.1