Update vendoring for client_golang and friends (#1076)
Signed-off-by: beorn7 <beorn@soundcloud.com>pull/1079/head
parent
b46cd80200
commit
1c9ea46cca
@ -0,0 +1,85 @@ |
||||
// Copyright 2018 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 internal |
||||
|
||||
import ( |
||||
"sort" |
||||
|
||||
dto "github.com/prometheus/client_model/go" |
||||
) |
||||
|
||||
// metricSorter is a sortable slice of *dto.Metric.
|
||||
type metricSorter []*dto.Metric |
||||
|
||||
func (s metricSorter) Len() int { |
||||
return len(s) |
||||
} |
||||
|
||||
func (s metricSorter) Swap(i, j int) { |
||||
s[i], s[j] = s[j], s[i] |
||||
} |
||||
|
||||
func (s metricSorter) Less(i, j int) bool { |
||||
if len(s[i].Label) != len(s[j].Label) { |
||||
// This should not happen. The metrics are
|
||||
// inconsistent. However, we have to deal with the fact, as
|
||||
// people might use custom collectors or metric family injection
|
||||
// to create inconsistent metrics. So let's simply compare the
|
||||
// number of labels in this case. That will still yield
|
||||
// reproducible sorting.
|
||||
return len(s[i].Label) < len(s[j].Label) |
||||
} |
||||
for n, lp := range s[i].Label { |
||||
vi := lp.GetValue() |
||||
vj := s[j].Label[n].GetValue() |
||||
if vi != vj { |
||||
return vi < vj |
||||
} |
||||
} |
||||
|
||||
// We should never arrive here. Multiple metrics with the same
|
||||
// label set in the same scrape will lead to undefined ingestion
|
||||
// behavior. However, as above, we have to provide stable sorting
|
||||
// here, even for inconsistent metrics. So sort equal metrics
|
||||
// by their timestamp, with missing timestamps (implying "now")
|
||||
// coming last.
|
||||
if s[i].TimestampMs == nil { |
||||
return false |
||||
} |
||||
if s[j].TimestampMs == nil { |
||||
return true |
||||
} |
||||
return s[i].GetTimestampMs() < s[j].GetTimestampMs() |
||||
} |
||||
|
||||
// NormalizeMetricFamilies returns a MetricFamily slice with empty
|
||||
// MetricFamilies pruned and the remaining MetricFamilies sorted by name within
|
||||
// the slice, with the contained Metrics sorted within each MetricFamily.
|
||||
func NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily { |
||||
for _, mf := range metricFamiliesByName { |
||||
sort.Sort(metricSorter(mf.Metric)) |
||||
} |
||||
names := make([]string, 0, len(metricFamiliesByName)) |
||||
for name, mf := range metricFamiliesByName { |
||||
if len(mf.Metric) > 0 { |
||||
names = append(names, name) |
||||
} |
||||
} |
||||
sort.Strings(names) |
||||
result := make([]*dto.MetricFamily, 0, len(names)) |
||||
for _, name := range names { |
||||
result = append(result, metricFamiliesByName[name]) |
||||
} |
||||
return result |
||||
} |
||||
34
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
generated
vendored
34
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
generated
vendored
@ -0,0 +1,179 @@ |
||||
// Copyright 2018 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 |
||||
|
||||
import ( |
||||
"fmt" |
||||
"sort" |
||||
|
||||
"github.com/golang/protobuf/proto" |
||||
|
||||
dto "github.com/prometheus/client_model/go" |
||||
) |
||||
|
||||
// WrapRegistererWith returns a Registerer wrapping the provided
|
||||
// Registerer. Collectors registered with the returned Registerer will be
|
||||
// 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.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// The Collector example demonstrates a use of WrapRegistererWith.
|
||||
func WrapRegistererWith(labels Labels, reg Registerer) Registerer { |
||||
return &wrappingRegisterer{ |
||||
wrappedRegisterer: reg, |
||||
labels: labels, |
||||
} |
||||
} |
||||
|
||||
// WrapRegistererWithPrefix returns a Registerer wrapping the provided
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// wrapping Registerer returned by WrapRegistererWithPrefix. It is rarely useful
|
||||
// to use the same prefix for all metrics exposed. In particular, do not prefix
|
||||
// metric names that are standardized across applications, as that would break
|
||||
// horizontal monitoring, for example the metrics provided by the Go collector
|
||||
// (see NewGoCollector) and the process collector (see NewProcessCollector). (In
|
||||
// fact, those metrics are already prefixed with “go_” or “process_”,
|
||||
// respectively.)
|
||||
func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer { |
||||
return &wrappingRegisterer{ |
||||
wrappedRegisterer: reg, |
||||
prefix: prefix, |
||||
} |
||||
} |
||||
|
||||
type wrappingRegisterer struct { |
||||
wrappedRegisterer Registerer |
||||
prefix string |
||||
labels Labels |
||||
} |
||||
|
||||
func (r *wrappingRegisterer) Register(c Collector) error { |
||||
return r.wrappedRegisterer.Register(&wrappingCollector{ |
||||
wrappedCollector: c, |
||||
prefix: r.prefix, |
||||
labels: r.labels, |
||||
}) |
||||
} |
||||
|
||||
func (r *wrappingRegisterer) MustRegister(cs ...Collector) { |
||||
for _, c := range cs { |
||||
if err := r.Register(c); err != nil { |
||||
panic(err) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func (r *wrappingRegisterer) Unregister(c Collector) bool { |
||||
return r.wrappedRegisterer.Unregister(&wrappingCollector{ |
||||
wrappedCollector: c, |
||||
prefix: r.prefix, |
||||
labels: r.labels, |
||||
}) |
||||
} |
||||
|
||||
type wrappingCollector struct { |
||||
wrappedCollector Collector |
||||
prefix string |
||||
labels Labels |
||||
} |
||||
|
||||
func (c *wrappingCollector) Collect(ch chan<- Metric) { |
||||
wrappedCh := make(chan Metric) |
||||
go func() { |
||||
c.wrappedCollector.Collect(wrappedCh) |
||||
close(wrappedCh) |
||||
}() |
||||
for m := range wrappedCh { |
||||
ch <- &wrappingMetric{ |
||||
wrappedMetric: m, |
||||
prefix: c.prefix, |
||||
labels: c.labels, |
||||
} |
||||
} |
||||
} |
||||
|
||||
func (c *wrappingCollector) Describe(ch chan<- *Desc) { |
||||
wrappedCh := make(chan *Desc) |
||||
go func() { |
||||
c.wrappedCollector.Describe(wrappedCh) |
||||
close(wrappedCh) |
||||
}() |
||||
for desc := range wrappedCh { |
||||
ch <- wrapDesc(desc, c.prefix, c.labels) |
||||
} |
||||
} |
||||
|
||||
type wrappingMetric struct { |
||||
wrappedMetric Metric |
||||
prefix string |
||||
labels Labels |
||||
} |
||||
|
||||
func (m *wrappingMetric) Desc() *Desc { |
||||
return wrapDesc(m.wrappedMetric.Desc(), m.prefix, m.labels) |
||||
} |
||||
|
||||
func (m *wrappingMetric) Write(out *dto.Metric) error { |
||||
if err := m.wrappedMetric.Write(out); err != nil { |
||||
return err |
||||
} |
||||
if len(m.labels) == 0 { |
||||
// No wrapping labels.
|
||||
return nil |
||||
} |
||||
for ln, lv := range m.labels { |
||||
out.Label = append(out.Label, &dto.LabelPair{ |
||||
Name: proto.String(ln), |
||||
Value: proto.String(lv), |
||||
}) |
||||
} |
||||
sort.Sort(labelPairSorter(out.Label)) |
||||
return nil |
||||
} |
||||
|
||||
func wrapDesc(desc *Desc, prefix string, labels Labels) *Desc { |
||||
constLabels := Labels{} |
||||
for _, lp := range desc.constLabelPairs { |
||||
constLabels[*lp.Name] = *lp.Value |
||||
} |
||||
for ln, lv := range labels { |
||||
if _, alreadyUsed := constLabels[ln]; alreadyUsed { |
||||
return &Desc{ |
||||
fqName: desc.fqName, |
||||
help: desc.help, |
||||
variableLabels: desc.variableLabels, |
||||
constLabelPairs: desc.constLabelPairs, |
||||
err: fmt.Errorf("attempted wrapping with already existing label name %q", ln), |
||||
} |
||||
} |
||||
constLabels[ln] = lv |
||||
} |
||||
// NewDesc will do remaining validations.
|
||||
newDesc := NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels) |
||||
// Propagate errors if there was any. This will override any errer
|
||||
// created by NewDesc above, i.e. earlier errors get precedence.
|
||||
if desc.err != nil { |
||||
newDesc.err = desc.err |
||||
} |
||||
return newDesc |
||||
} |
||||
Loading…
Reference in new issue