Merge pull request #74248 from danielqsj/pdep

Update vendor prometheus/common/... to latest release
pull/564/head
Kubernetes Prow Robot 2019-02-25 11:33:43 -08:00 committed by GitHub
commit 1eb2acca99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 413 additions and 191 deletions

25
Godeps/Godeps.json generated
View File

@ -3115,23 +3115,23 @@
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus", "ImportPath": "github.com/prometheus/client_golang/prometheus",
"Comment": "v0.9.1", "Comment": "v0.9.2",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/internal", "ImportPath": "github.com/prometheus/client_golang/prometheus/internal",
"Comment": "v0.9.1", "Comment": "v0.9.2",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/promhttp", "ImportPath": "github.com/prometheus/client_golang/prometheus/promhttp",
"Comment": "v0.9.1", "Comment": "v0.9.2",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/testutil", "ImportPath": "github.com/prometheus/client_golang/prometheus/testutil",
"Comment": "v0.9.1", "Comment": "v0.9.2",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_model/go", "ImportPath": "github.com/prometheus/client_model/go",
@ -3140,15 +3140,18 @@
}, },
{ {
"ImportPath": "github.com/prometheus/common/expfmt", "ImportPath": "github.com/prometheus/common/expfmt",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", "ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/model", "ImportPath": "github.com/prometheus/common/model",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/procfs", "ImportPath": "github.com/prometheus/procfs",

View File

@ -572,15 +572,18 @@
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus", "ImportPath": "github.com/prometheus/client_golang/prometheus",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/internal", "ImportPath": "github.com/prometheus/client_golang/prometheus/internal",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/promhttp", "ImportPath": "github.com/prometheus/client_golang/prometheus/promhttp",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_model/go", "ImportPath": "github.com/prometheus/client_model/go",
@ -588,15 +591,18 @@
}, },
{ {
"ImportPath": "github.com/prometheus/common/expfmt", "ImportPath": "github.com/prometheus/common/expfmt",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", "ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/model", "ImportPath": "github.com/prometheus/common/model",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/procfs", "ImportPath": "github.com/prometheus/procfs",

View File

@ -552,15 +552,18 @@
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus", "ImportPath": "github.com/prometheus/client_golang/prometheus",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/internal", "ImportPath": "github.com/prometheus/client_golang/prometheus/internal",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/promhttp", "ImportPath": "github.com/prometheus/client_golang/prometheus/promhttp",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_model/go", "ImportPath": "github.com/prometheus/client_model/go",
@ -568,15 +571,18 @@
}, },
{ {
"ImportPath": "github.com/prometheus/common/expfmt", "ImportPath": "github.com/prometheus/common/expfmt",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", "ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/model", "ImportPath": "github.com/prometheus/common/model",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/procfs", "ImportPath": "github.com/prometheus/procfs",

View File

@ -220,11 +220,13 @@
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus", "ImportPath": "github.com/prometheus/client_golang/prometheus",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/internal", "ImportPath": "github.com/prometheus/client_golang/prometheus/internal",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_model/go", "ImportPath": "github.com/prometheus/client_model/go",
@ -232,15 +234,18 @@
}, },
{ {
"ImportPath": "github.com/prometheus/common/expfmt", "ImportPath": "github.com/prometheus/common/expfmt",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", "ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/model", "ImportPath": "github.com/prometheus/common/model",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/procfs", "ImportPath": "github.com/prometheus/procfs",

View File

@ -204,11 +204,13 @@
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus", "ImportPath": "github.com/prometheus/client_golang/prometheus",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus/internal", "ImportPath": "github.com/prometheus/client_golang/prometheus/internal",
"Rev": "abad2d1bd44235a26707c172eab6bca5bf2dbad3" "Comment": "v0.9.2",
"Rev": "505eaef017263e299324067d40ca2c48f6a2cf50"
}, },
{ {
"ImportPath": "github.com/prometheus/client_model/go", "ImportPath": "github.com/prometheus/client_model/go",
@ -216,15 +218,18 @@
}, },
{ {
"ImportPath": "github.com/prometheus/common/expfmt", "ImportPath": "github.com/prometheus/common/expfmt",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", "ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/common/model", "ImportPath": "github.com/prometheus/common/model",
"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207" "Comment": "v0.2.0",
"Rev": "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
}, },
{ {
"ImportPath": "github.com/prometheus/procfs", "ImportPath": "github.com/prometheus/procfs",

View File

@ -93,7 +93,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
// First add only the const label names and sort them... // First add only the const label names and sort them...
for labelName := range constLabels { for labelName := range constLabels {
if !checkLabelName(labelName) { if !checkLabelName(labelName) {
d.err = fmt.Errorf("%q is not a valid label name", labelName) d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
return d return d
} }
labelNames = append(labelNames, labelName) labelNames = append(labelNames, labelName)
@ -115,7 +115,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
// dimension with a different mix between preset and variable labels. // dimension with a different mix between preset and variable labels.
for _, labelName := range variableLabels { for _, labelName := range variableLabels {
if !checkLabelName(labelName) { if !checkLabelName(labelName) {
d.err = fmt.Errorf("%q is not a valid label name", labelName) d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
return d return d
} }
labelNames = append(labelNames, "$"+labelName) labelNames = append(labelNames, "$"+labelName)

View File

@ -872,7 +872,13 @@ func checkMetricConsistency(
h = hashAddByte(h, separatorByte) h = hashAddByte(h, separatorByte)
// Make sure label pairs are sorted. We depend on it for the consistency // Make sure label pairs are sorted. We depend on it for the consistency
// check. // check.
sort.Sort(labelPairSorter(dtoMetric.Label)) if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) {
// We cannot sort dtoMetric.Label in place as it is immutable by contract.
copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label))
copy(copiedLabels, dtoMetric.Label)
sort.Sort(labelPairSorter(copiedLabels))
dtoMetric.Label = copiedLabels
}
for _, lp := range dtoMetric.Label { for _, lp := range dtoMetric.Label {
h = hashAdd(h, lp.GetName()) h = hashAdd(h, lp.GetName())
h = hashAddByte(h, separatorByte) h = hashAddByte(h, separatorByte)
@ -903,8 +909,8 @@ func checkDescConsistency(
} }
// Is the desc consistent with the content of the metric? // Is the desc consistent with the content of the metric?
lpsFromDesc := make([]*dto.LabelPair, 0, len(dtoMetric.Label)) lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label))
lpsFromDesc = append(lpsFromDesc, desc.constLabelPairs...) copy(lpsFromDesc, desc.constLabelPairs)
for _, l := range desc.variableLabels { for _, l := range desc.variableLabels {
lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{ lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{
Name: proto.String(l), Name: proto.String(l),

View File

@ -37,7 +37,6 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"reflect"
"github.com/prometheus/common/expfmt" "github.com/prometheus/common/expfmt"
@ -125,38 +124,43 @@ func CollectAndCompare(c prometheus.Collector, expected io.Reader, metricNames .
// exposition format. If any metricNames are provided, only metrics with those // exposition format. If any metricNames are provided, only metrics with those
// names are compared. // names are compared.
func GatherAndCompare(g prometheus.Gatherer, expected io.Reader, metricNames ...string) error { func GatherAndCompare(g prometheus.Gatherer, expected io.Reader, metricNames ...string) error {
metrics, err := g.Gather() got, err := g.Gather()
if err != nil { if err != nil {
return fmt.Errorf("gathering metrics failed: %s", err) return fmt.Errorf("gathering metrics failed: %s", err)
} }
if metricNames != nil { if metricNames != nil {
metrics = filterMetrics(metrics, metricNames) got = filterMetrics(got, metricNames)
} }
var tp expfmt.TextParser var tp expfmt.TextParser
expectedMetrics, err := tp.TextToMetricFamilies(expected) wantRaw, err := tp.TextToMetricFamilies(expected)
if err != nil { if err != nil {
return fmt.Errorf("parsing expected metrics failed: %s", err) return fmt.Errorf("parsing expected metrics failed: %s", err)
} }
want := internal.NormalizeMetricFamilies(wantRaw)
if !reflect.DeepEqual(metrics, internal.NormalizeMetricFamilies(expectedMetrics)) { return compare(got, want)
// Encode the gathered output to the readable text format for comparison. }
var buf1 bytes.Buffer
enc := expfmt.NewEncoder(&buf1, expfmt.FmtText) // compare encodes both provided slices of metric families into the text format,
for _, mf := range metrics { // compares their string message, and returns an error if they do not match.
// The error contains the encoded text of both the desired and the actual
// result.
func compare(got, want []*dto.MetricFamily) error {
var gotBuf, wantBuf bytes.Buffer
enc := expfmt.NewEncoder(&gotBuf, expfmt.FmtText)
for _, mf := range got {
if err := enc.Encode(mf); err != nil { if err := enc.Encode(mf); err != nil {
return fmt.Errorf("encoding result failed: %s", err) return fmt.Errorf("encoding gathered metrics failed: %s", err)
} }
} }
// Encode normalized expected metrics again to generate them in the same ordering enc = expfmt.NewEncoder(&wantBuf, expfmt.FmtText)
// the registry does to spot differences more easily. for _, mf := range want {
var buf2 bytes.Buffer
enc = expfmt.NewEncoder(&buf2, expfmt.FmtText)
for _, mf := range internal.NormalizeMetricFamilies(expectedMetrics) {
if err := enc.Encode(mf); err != nil { if err := enc.Encode(mf); err != nil {
return fmt.Errorf("encoding result failed: %s", err) return fmt.Errorf("encoding expected metrics failed: %s", err)
} }
} }
if wantBuf.String() != gotBuf.String() {
return fmt.Errorf(` return fmt.Errorf(`
metric output does not match expectation; want: metric output does not match expectation; want:
@ -165,7 +169,8 @@ metric output does not match expectation; want:
got: got:
%s %s
`, buf2.String(), buf1.String()) `, wantBuf.String(), gotBuf.String())
} }
return nil return nil
} }

View File

@ -39,13 +39,16 @@ func NewTimer(o Observer) *Timer {
// ObserveDuration records the duration passed since the Timer was created with // ObserveDuration records the duration passed since the Timer was created with
// NewTimer. It calls the Observe method of the Observer provided during // NewTimer. It calls the Observe method of the Observer provided during
// construction with the duration in seconds as an argument. ObserveDuration is // construction with the duration in seconds as an argument. The observed
// usually called with a defer statement. // duration is also returned. ObserveDuration is usually called with a defer
// statement.
// //
// Note that this method is only guaranteed to never observe negative durations // Note that this method is only guaranteed to never observe negative durations
// if used with Go1.9+. // if used with Go1.9+.
func (t *Timer) ObserveDuration() { func (t *Timer) ObserveDuration() time.Duration {
d := time.Since(t.begin)
if t.observer != nil { if t.observer != nil {
t.observer.Observe(time.Since(t.begin).Seconds()) t.observer.Observe(d.Seconds())
} }
return d
} }

View File

@ -164,9 +164,9 @@ func (sd *SampleDecoder) Decode(s *model.Vector) error {
} }
// ExtractSamples builds a slice of samples from the provided metric // ExtractSamples builds a slice of samples from the provided metric
// families. If an error occurs during sample extraction, it continues to // families. If an error occurrs during sample extraction, it continues to
// extract from the remaining metric families. The returned error is the last // extract from the remaining metric families. The returned error is the last
// error that has occured. // error that has occurred.
func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) { func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {
var ( var (
all model.Vector all model.Vector

View File

@ -26,7 +26,7 @@ const (
// The Content-Type values for the different wire protocols. // The Content-Type values for the different wire protocols.
FmtUnknown Format = `<unknown>` FmtUnknown Format = `<unknown>`
FmtText Format = `text/plain; version=` + TextVersion FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8`
FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` FmtProtoDelim Format = ProtoFmt + ` encoding=delimited`
FmtProtoText Format = ProtoFmt + ` encoding=text` FmtProtoText Format = ProtoFmt + ` encoding=text`
FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`

View File

@ -14,13 +14,45 @@
package expfmt package expfmt
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"math" "math"
"strconv"
"strings" "strings"
"sync"
"github.com/prometheus/common/model"
dto "github.com/prometheus/client_model/go" dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/model" )
// enhancedWriter has all the enhanced write functions needed here. bytes.Buffer
// implements it.
type enhancedWriter interface {
io.Writer
WriteRune(r rune) (n int, err error)
WriteString(s string) (n int, err error)
WriteByte(c byte) error
}
const (
initialBufSize = 512
initialNumBufSize = 24
)
var (
bufPool = sync.Pool{
New: func() interface{} {
return bytes.NewBuffer(make([]byte, 0, initialBufSize))
},
}
numBufPool = sync.Pool{
New: func() interface{} {
b := make([]byte, 0, initialNumBufSize)
return &b
},
}
) )
// MetricFamilyToText converts a MetricFamily proto message into text format and // MetricFamilyToText converts a MetricFamily proto message into text format and
@ -32,37 +64,92 @@ import (
// will result in invalid text format output. // will result in invalid text format output.
// //
// This method fulfills the type 'prometheus.encoder'. // This method fulfills the type 'prometheus.encoder'.
func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) { func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) {
var written int
// Fail-fast checks. // Fail-fast checks.
if len(in.Metric) == 0 { if len(in.Metric) == 0 {
return written, fmt.Errorf("MetricFamily has no metrics: %s", in) return 0, fmt.Errorf("MetricFamily has no metrics: %s", in)
} }
name := in.GetName() name := in.GetName()
if name == "" { if name == "" {
return written, fmt.Errorf("MetricFamily has no name: %s", in) return 0, fmt.Errorf("MetricFamily has no name: %s", in)
} }
// Try the interface upgrade. If it doesn't work, we'll use a
// bytes.Buffer from the sync.Pool and write out its content to out in a
// single go in the end.
w, ok := out.(enhancedWriter)
if !ok {
b := bufPool.Get().(*bytes.Buffer)
b.Reset()
w = b
defer func() {
bWritten, bErr := out.Write(b.Bytes())
written = bWritten
if err == nil {
err = bErr
}
bufPool.Put(b)
}()
}
var n int
// Comments, first HELP, then TYPE. // Comments, first HELP, then TYPE.
if in.Help != nil { if in.Help != nil {
n, err := fmt.Fprintf( n, err = w.WriteString("# HELP ")
out, "# HELP %s %s\n",
name, escapeString(*in.Help, false),
)
written += n written += n
if err != nil { if err != nil {
return written, err return
} }
n, err = w.WriteString(name)
written += n
if err != nil {
return
}
err = w.WriteByte(' ')
written++
if err != nil {
return
}
n, err = writeEscapedString(w, *in.Help, false)
written += n
if err != nil {
return
}
err = w.WriteByte('\n')
written++
if err != nil {
return
}
}
n, err = w.WriteString("# TYPE ")
written += n
if err != nil {
return
}
n, err = w.WriteString(name)
written += n
if err != nil {
return
} }
metricType := in.GetType() metricType := in.GetType()
n, err := fmt.Fprintf( switch metricType {
out, "# TYPE %s %s\n", case dto.MetricType_COUNTER:
name, strings.ToLower(metricType.String()), n, err = w.WriteString(" counter\n")
) case dto.MetricType_GAUGE:
n, err = w.WriteString(" gauge\n")
case dto.MetricType_SUMMARY:
n, err = w.WriteString(" summary\n")
case dto.MetricType_UNTYPED:
n, err = w.WriteString(" untyped\n")
case dto.MetricType_HISTOGRAM:
n, err = w.WriteString(" histogram\n")
default:
return written, fmt.Errorf("unknown metric type %s", metricType.String())
}
written += n written += n
if err != nil { if err != nil {
return written, err return
} }
// Finally the samples, one line for each. // Finally the samples, one line for each.
@ -75,9 +162,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
) )
} }
n, err = writeSample( n, err = writeSample(
name, metric, "", "", w, name, "", metric, "", 0,
metric.Counter.GetValue(), metric.Counter.GetValue(),
out,
) )
case dto.MetricType_GAUGE: case dto.MetricType_GAUGE:
if metric.Gauge == nil { if metric.Gauge == nil {
@ -86,9 +172,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
) )
} }
n, err = writeSample( n, err = writeSample(
name, metric, "", "", w, name, "", metric, "", 0,
metric.Gauge.GetValue(), metric.Gauge.GetValue(),
out,
) )
case dto.MetricType_UNTYPED: case dto.MetricType_UNTYPED:
if metric.Untyped == nil { if metric.Untyped == nil {
@ -97,9 +182,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
) )
} }
n, err = writeSample( n, err = writeSample(
name, metric, "", "", w, name, "", metric, "", 0,
metric.Untyped.GetValue(), metric.Untyped.GetValue(),
out,
) )
case dto.MetricType_SUMMARY: case dto.MetricType_SUMMARY:
if metric.Summary == nil { if metric.Summary == nil {
@ -109,29 +193,26 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
} }
for _, q := range metric.Summary.Quantile { for _, q := range metric.Summary.Quantile {
n, err = writeSample( n, err = writeSample(
name, metric, w, name, "", metric,
model.QuantileLabel, fmt.Sprint(q.GetQuantile()), model.QuantileLabel, q.GetQuantile(),
q.GetValue(), q.GetValue(),
out,
) )
written += n written += n
if err != nil { if err != nil {
return written, err return
} }
} }
n, err = writeSample( n, err = writeSample(
name+"_sum", metric, "", "", w, name, "_sum", metric, "", 0,
metric.Summary.GetSampleSum(), metric.Summary.GetSampleSum(),
out,
) )
if err != nil {
return written, err
}
written += n written += n
if err != nil {
return
}
n, err = writeSample( n, err = writeSample(
name+"_count", metric, "", "", w, name, "_count", metric, "", 0,
float64(metric.Summary.GetSampleCount()), float64(metric.Summary.GetSampleCount()),
out,
) )
case dto.MetricType_HISTOGRAM: case dto.MetricType_HISTOGRAM:
if metric.Histogram == nil { if metric.Histogram == nil {
@ -140,46 +221,42 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
) )
} }
infSeen := false infSeen := false
for _, q := range metric.Histogram.Bucket { for _, b := range metric.Histogram.Bucket {
n, err = writeSample( n, err = writeSample(
name+"_bucket", metric, w, name, "_bucket", metric,
model.BucketLabel, fmt.Sprint(q.GetUpperBound()), model.BucketLabel, b.GetUpperBound(),
float64(q.GetCumulativeCount()), float64(b.GetCumulativeCount()),
out,
) )
written += n written += n
if err != nil { if err != nil {
return written, err return
} }
if math.IsInf(q.GetUpperBound(), +1) { if math.IsInf(b.GetUpperBound(), +1) {
infSeen = true infSeen = true
} }
} }
if !infSeen { if !infSeen {
n, err = writeSample( n, err = writeSample(
name+"_bucket", metric, w, name, "_bucket", metric,
model.BucketLabel, "+Inf", model.BucketLabel, math.Inf(+1),
float64(metric.Histogram.GetSampleCount()), float64(metric.Histogram.GetSampleCount()),
out,
) )
if err != nil {
return written, err
}
written += n written += n
if err != nil {
return
}
} }
n, err = writeSample( n, err = writeSample(
name+"_sum", metric, "", "", w, name, "_sum", metric, "", 0,
metric.Histogram.GetSampleSum(), metric.Histogram.GetSampleSum(),
out,
) )
if err != nil {
return written, err
}
written += n written += n
if err != nil {
return
}
n, err = writeSample( n, err = writeSample(
name+"_count", metric, "", "", w, name, "_count", metric, "", 0,
float64(metric.Histogram.GetSampleCount()), float64(metric.Histogram.GetSampleCount()),
out,
) )
default: default:
return written, fmt.Errorf( return written, fmt.Errorf(
@ -188,116 +265,204 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
} }
written += n written += n
if err != nil { if err != nil {
return written, err return
} }
} }
return written, nil return
} }
// writeSample writes a single sample in text format to out, given the metric // writeSample writes a single sample in text format to w, given the metric
// name, the metric proto message itself, optionally an additional label name // name, the metric proto message itself, optionally an additional label name
// and value (use empty strings if not required), and the value. The function // with a float64 value (use empty string as label name if not required), and
// returns the number of bytes written and any error encountered. // the value. The function returns the number of bytes written and any error
// encountered.
func writeSample( func writeSample(
name string, w enhancedWriter,
name, suffix string,
metric *dto.Metric, metric *dto.Metric,
additionalLabelName, additionalLabelValue string, additionalLabelName string, additionalLabelValue float64,
value float64, value float64,
out io.Writer,
) (int, error) { ) (int, error) {
var written int var written int
n, err := fmt.Fprint(out, name) n, err := w.WriteString(name)
written += n written += n
if err != nil { if err != nil {
return written, err return written, err
} }
n, err = labelPairsToText( if suffix != "" {
metric.Label, n, err = w.WriteString(suffix)
additionalLabelName, additionalLabelValue, written += n
out, if err != nil {
return written, err
}
}
n, err = writeLabelPairs(
w, metric.Label, additionalLabelName, additionalLabelValue,
) )
written += n written += n
if err != nil { if err != nil {
return written, err return written, err
} }
n, err = fmt.Fprintf(out, " %v", value) err = w.WriteByte(' ')
written++
if err != nil {
return written, err
}
n, err = writeFloat(w, value)
written += n written += n
if err != nil { if err != nil {
return written, err return written, err
} }
if metric.TimestampMs != nil { if metric.TimestampMs != nil {
n, err = fmt.Fprintf(out, " %v", *metric.TimestampMs) err = w.WriteByte(' ')
written++
if err != nil {
return written, err
}
n, err = writeInt(w, *metric.TimestampMs)
written += n written += n
if err != nil { if err != nil {
return written, err return written, err
} }
} }
n, err = out.Write([]byte{'\n'}) err = w.WriteByte('\n')
written += n written++
if err != nil { if err != nil {
return written, err return written, err
} }
return written, nil return written, nil
} }
// labelPairsToText converts a slice of LabelPair proto messages plus the // writeLabelPairs converts a slice of LabelPair proto messages plus the
// explicitly given additional label pair into text formatted as required by the // explicitly given additional label pair into text formatted as required by the
// text format and writes it to 'out'. An empty slice in combination with an // text format and writes it to 'w'. An empty slice in combination with an empty
// empty string 'additionalLabelName' results in nothing being // string 'additionalLabelName' results in nothing being written. Otherwise, the
// written. Otherwise, the label pairs are written, escaped as required by the // label pairs are written, escaped as required by the text format, and enclosed
// text format, and enclosed in '{...}'. The function returns the number of // in '{...}'. The function returns the number of bytes written and any error
// bytes written and any error encountered. // encountered.
func labelPairsToText( func writeLabelPairs(
w enhancedWriter,
in []*dto.LabelPair, in []*dto.LabelPair,
additionalLabelName, additionalLabelValue string, additionalLabelName string, additionalLabelValue float64,
out io.Writer,
) (int, error) { ) (int, error) {
if len(in) == 0 && additionalLabelName == "" { if len(in) == 0 && additionalLabelName == "" {
return 0, nil return 0, nil
} }
var written int var (
separator := '{' written int
for _, lp := range in { separator byte = '{'
n, err := fmt.Fprintf(
out, `%c%s="%s"`,
separator, lp.GetName(), escapeString(lp.GetValue(), true),
) )
for _, lp := range in {
err := w.WriteByte(separator)
written++
if err != nil {
return written, err
}
n, err := w.WriteString(lp.GetName())
written += n written += n
if err != nil { if err != nil {
return written, err return written, err
} }
n, err = w.WriteString(`="`)
written += n
if err != nil {
return written, err
}
n, err = writeEscapedString(w, lp.GetValue(), true)
written += n
if err != nil {
return written, err
}
err = w.WriteByte('"')
written++
if err != nil {
return written, err
}
separator = ',' separator = ','
} }
if additionalLabelName != "" { if additionalLabelName != "" {
n, err := fmt.Fprintf( err := w.WriteByte(separator)
out, `%c%s="%s"`, written++
separator, additionalLabelName, if err != nil {
escapeString(additionalLabelValue, true), return written, err
) }
n, err := w.WriteString(additionalLabelName)
written += n written += n
if err != nil { if err != nil {
return written, err return written, err
} }
} n, err = w.WriteString(`="`)
n, err := out.Write([]byte{'}'})
written += n written += n
if err != nil { if err != nil {
return written, err return written, err
} }
n, err = writeFloat(w, additionalLabelValue)
written += n
if err != nil {
return written, err
}
err = w.WriteByte('"')
written++
if err != nil {
return written, err
}
}
err := w.WriteByte('}')
written++
if err != nil {
return written, err
}
return written, nil return written, nil
} }
// writeEscapedString replaces '\' by '\\', new line character by '\n', and - if
// includeDoubleQuote is true - '"' by '\"'.
var ( var (
escape = strings.NewReplacer("\\", `\\`, "\n", `\n`) escaper = strings.NewReplacer("\\", `\\`, "\n", `\n`)
escapeWithDoubleQuote = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`) quotedEscaper = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
) )
// escapeString replaces '\' by '\\', new line character by '\n', and - if func writeEscapedString(w enhancedWriter, v string, includeDoubleQuote bool) (int, error) {
// includeDoubleQuote is true - '"' by '\"'.
func escapeString(v string, includeDoubleQuote bool) string {
if includeDoubleQuote { if includeDoubleQuote {
return escapeWithDoubleQuote.Replace(v) return quotedEscaper.WriteString(w, v)
} else {
return escaper.WriteString(w, v)
} }
}
return escape.Replace(v)
// writeFloat is equivalent to fmt.Fprint with a float64 argument but hardcodes
// a few common cases for increased efficiency. For non-hardcoded cases, it uses
// strconv.AppendFloat to avoid allocations, similar to writeInt.
func writeFloat(w enhancedWriter, f float64) (int, error) {
switch {
case f == 1:
return 1, w.WriteByte('1')
case f == 0:
return 1, w.WriteByte('0')
case f == -1:
return w.WriteString("-1")
case math.IsNaN(f):
return w.WriteString("NaN")
case math.IsInf(f, +1):
return w.WriteString("+Inf")
case math.IsInf(f, -1):
return w.WriteString("-Inf")
default:
bp := numBufPool.Get().(*[]byte)
*bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64)
written, err := w.Write(*bp)
numBufPool.Put(bp)
return written, err
}
}
// writeInt is equivalent to fmt.Fprint with an int64 argument but uses
// strconv.AppendInt with a byte slice taken from a sync.Pool to avoid
// allocations.
func writeInt(w enhancedWriter, i int64) (int, error) {
bp := numBufPool.Get().(*[]byte)
*bp = strconv.AppendInt((*bp)[:0], i, 10)
written, err := w.Write(*bp)
numBufPool.Put(bp)
return written, err
} }

View File

@ -315,6 +315,10 @@ func (p *TextParser) startLabelValue() stateFn {
if p.readTokenAsLabelValue(); p.err != nil { if p.readTokenAsLabelValue(); p.err != nil {
return nil return nil
} }
if !model.LabelValue(p.currentToken.String()).IsValid() {
p.parseError(fmt.Sprintf("invalid label value %q", p.currentToken.String()))
return nil
}
p.currentLabelPair.Value = proto.String(p.currentToken.String()) p.currentLabelPair.Value = proto.String(p.currentToken.String())
// Special treatment of summaries: // Special treatment of summaries:
// - Quantile labels are special, will result in dto.Quantile later. // - Quantile labels are special, will result in dto.Quantile later.
@ -355,7 +359,7 @@ func (p *TextParser) startLabelValue() stateFn {
} }
return p.readingValue return p.readingValue
default: default:
p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.Value)) p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.GetValue()))
return nil return nil
} }
} }
@ -552,8 +556,8 @@ func (p *TextParser) readTokenUntilWhitespace() {
// byte considered is the byte already read (now in p.currentByte). The first // byte considered is the byte already read (now in p.currentByte). The first
// newline byte encountered is still copied into p.currentByte, but not into // newline byte encountered is still copied into p.currentByte, but not into
// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are // p.currentToken. If recognizeEscapeSequence is true, two escape sequences are
// recognized: '\\' tranlates into '\', and '\n' into a line-feed character. All // recognized: '\\' translates into '\', and '\n' into a line-feed character.
// other escape sequences are invalid and cause an error. // All other escape sequences are invalid and cause an error.
func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) { func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) {
p.currentToken.Reset() p.currentToken.Reset()
escaped := false escaped := false

View File

@ -1,12 +1,12 @@
/* /*
Copyright (c) 2011, Open Knowledge Foundation Ltd.
All rights reserved.
HTTP Content-Type Autonegotiation. HTTP Content-Type Autonegotiation.
The functions in this package implement the behaviour specified in The functions in this package implement the behaviour specified in
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Copyright (c) 2011, Open Knowledge Foundation Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:

View File

@ -21,7 +21,6 @@ import (
) )
var ( var (
separator = []byte{0}
// MetricNameRE is a regular expression matching valid metric // MetricNameRE is a regular expression matching valid metric
// names. Note that the IsValidMetricName function performs the same // names. Note that the IsValidMetricName function performs the same
// check but faster than a match with this regular expression. // check but faster than a match with this regular expression.

View File

@ -59,8 +59,8 @@ func (m *Matcher) Validate() error {
return nil return nil
} }
// Silence defines the representation of a silence definiton // Silence defines the representation of a silence definition in the Prometheus
// in the Prometheus eco-system. // eco-system.
type Silence struct { type Silence struct {
ID uint64 `json:"id,omitempty"` ID uint64 `json:"id,omitempty"`

View File

@ -43,7 +43,7 @@ const (
// (1970-01-01 00:00 UTC) excluding leap seconds. // (1970-01-01 00:00 UTC) excluding leap seconds.
type Time int64 type Time int64
// Interval describes and interval between two timestamps. // Interval describes an interval between two timestamps.
type Interval struct { type Interval struct {
Start, End Time Start, End Time
} }
@ -163,9 +163,21 @@ func (t *Time) UnmarshalJSON(b []byte) error {
// This type should not propagate beyond the scope of input/output processing. // This type should not propagate beyond the scope of input/output processing.
type Duration time.Duration type Duration time.Duration
// Set implements pflag/flag.Value
func (d *Duration) Set(s string) error {
var err error
*d, err = ParseDuration(s)
return err
}
// Type implements pflag.Value
func (d *Duration) Type() string {
return "duration"
}
var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$") var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
// StringToDuration parses a string into a time.Duration, assuming that a year // ParseDuration parses a string into a time.Duration, assuming that a year
// always has 365d, a week always has 7d, and a day always has 24h. // always has 365d, a week always has 7d, and a day always has 24h.
func ParseDuration(durationStr string) (Duration, error) { func ParseDuration(durationStr string) (Duration, error) {
matches := durationRE.FindStringSubmatch(durationStr) matches := durationRE.FindStringSubmatch(durationStr)
@ -202,6 +214,9 @@ func (d Duration) String() string {
ms = int64(time.Duration(d) / time.Millisecond) ms = int64(time.Duration(d) / time.Millisecond)
unit = "ms" unit = "ms"
) )
if ms == 0 {
return "0s"
}
factors := map[string]int64{ factors := map[string]int64{
"y": 1000 * 60 * 60 * 24 * 365, "y": 1000 * 60 * 60 * 24 * 365,
"w": 1000 * 60 * 60 * 24 * 7, "w": 1000 * 60 * 60 * 24 * 7,

View File

@ -100,7 +100,7 @@ func (s *SamplePair) UnmarshalJSON(b []byte) error {
} }
// Equal returns true if this SamplePair and o have equal Values and equal // Equal returns true if this SamplePair and o have equal Values and equal
// Timestamps. The sematics of Value equality is defined by SampleValue.Equal. // Timestamps. The semantics of Value equality is defined by SampleValue.Equal.
func (s *SamplePair) Equal(o *SamplePair) bool { func (s *SamplePair) Equal(o *SamplePair) bool {
return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp)) return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
} }
@ -117,7 +117,7 @@ type Sample struct {
} }
// Equal compares first the metrics, then the timestamp, then the value. The // Equal compares first the metrics, then the timestamp, then the value. The
// sematics of value equality is defined by SampleValue.Equal. // semantics of value equality is defined by SampleValue.Equal.
func (s *Sample) Equal(o *Sample) bool { func (s *Sample) Equal(o *Sample) bool {
if s == o { if s == o {
return true return true

0
vendor/k8s.io/kube-openapi/pkg/generators/rules/OWNERS generated vendored Normal file → Executable file
View File