forked from mirrors/statsd_exporter
Remove dead code
This removes all the code that the new registry code replaces. Signed-off-by: Clayton O'Neill <claytono@github.com>
This commit is contained in:
parent
7c30120dbc
commit
f6c0dd965b
2 changed files with 11 additions and 346 deletions
338
exporter.go
338
exporter.go
|
@ -15,12 +15,9 @@ package main
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
"net"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -28,7 +25,6 @@ import (
|
|||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/common/log"
|
||||
"github.com/prometheus/common/model"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mapper"
|
||||
|
@ -39,12 +35,6 @@ const (
|
|||
regErrF = "Failed to update metric %q. Error: %s"
|
||||
)
|
||||
|
||||
var (
|
||||
fnvHash = fnv.New64a()
|
||||
strBuf bytes.Buffer // Used for hashing.
|
||||
intBuf = make([]byte, 8)
|
||||
)
|
||||
|
||||
// uncheckedCollector wraps a Collector but its Describe method yields no Desc.
|
||||
// This allows incoming metrics to have inconsistent label sets
|
||||
type uncheckedCollector struct {
|
||||
|
@ -56,241 +46,6 @@ func (u uncheckedCollector) Collect(c chan<- prometheus.Metric) {
|
|||
u.c.Collect(c)
|
||||
}
|
||||
|
||||
type metricChecker interface {
|
||||
metricConflicts(string, metricType) bool
|
||||
}
|
||||
|
||||
func getSortedLabelNames(labels prometheus.Labels) []string {
|
||||
names := make([]string, 0, len(labels))
|
||||
for labelName := range labels {
|
||||
names = append(names, labelName)
|
||||
}
|
||||
sort.Strings(names)
|
||||
return names
|
||||
}
|
||||
|
||||
func getContainerMapKey(metricName string, labelNames []string) string {
|
||||
return metricName + "," + strings.Join(labelNames, ",")
|
||||
}
|
||||
|
||||
// hashNameAndLabels returns a hash value of the provided name string and all
|
||||
// the label names and values in the provided labels map.
|
||||
//
|
||||
// Not safe for concurrent use! (Uses a shared buffer and hasher to save on
|
||||
// allocations.)
|
||||
func hashNameAndLabels(name string, labelNames []string, labels prometheus.Labels) uint64 {
|
||||
fnvHash.Reset()
|
||||
strBuf.Reset()
|
||||
strBuf.WriteString(name)
|
||||
strBuf.WriteByte(model.SeparatorByte)
|
||||
|
||||
for _, labelName := range labelNames {
|
||||
strBuf.WriteString(labelName)
|
||||
strBuf.WriteByte(model.SeparatorByte)
|
||||
strBuf.WriteString(labels[labelName])
|
||||
strBuf.WriteByte(model.SeparatorByte)
|
||||
}
|
||||
|
||||
fnvHash.Write(strBuf.Bytes())
|
||||
return fnvHash.Sum64()
|
||||
}
|
||||
|
||||
type CounterContainer struct {
|
||||
// metric name
|
||||
Elements map[string]*prometheus.CounterVec
|
||||
}
|
||||
|
||||
func NewCounterContainer() *CounterContainer {
|
||||
return &CounterContainer{
|
||||
Elements: make(map[string]*prometheus.CounterVec),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CounterContainer) Get(metricName string, labelNames []string, labels prometheus.Labels, mc metricChecker, help string) (prometheus.Counter, error) {
|
||||
mapKey := getContainerMapKey(metricName, labelNames)
|
||||
|
||||
counterVec, ok := c.Elements[mapKey]
|
||||
if !ok {
|
||||
if mc.metricConflicts(metricName, CounterMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
metricsCount.WithLabelValues("counter").Inc()
|
||||
counterVec = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: metricName,
|
||||
Help: help,
|
||||
}, labelNames)
|
||||
if err := prometheus.Register(uncheckedCollector{counterVec}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Elements[mapKey] = counterVec
|
||||
}
|
||||
return counterVec.GetMetricWith(labels)
|
||||
}
|
||||
|
||||
func (c *CounterContainer) Delete(metricName string, labelNames []string, labels prometheus.Labels) {
|
||||
mapKey := getContainerMapKey(metricName, labelNames)
|
||||
if _, ok := c.Elements[mapKey]; ok {
|
||||
c.Elements[mapKey].Delete(labels)
|
||||
metricsCount.WithLabelValues("counter").Dec()
|
||||
}
|
||||
}
|
||||
|
||||
type GaugeContainer struct {
|
||||
Elements map[string]*prometheus.GaugeVec
|
||||
}
|
||||
|
||||
func NewGaugeContainer() *GaugeContainer {
|
||||
return &GaugeContainer{
|
||||
Elements: make(map[string]*prometheus.GaugeVec),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *GaugeContainer) Get(metricName string, labelNames []string, labels prometheus.Labels, mc metricChecker, help string) (prometheus.Gauge, error) {
|
||||
mapKey := getContainerMapKey(metricName, labelNames)
|
||||
|
||||
gaugeVec, ok := c.Elements[mapKey]
|
||||
if !ok {
|
||||
if mc.metricConflicts(metricName, GaugeMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
metricsCount.WithLabelValues("gauge").Inc()
|
||||
gaugeVec = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: metricName,
|
||||
Help: help,
|
||||
}, labelNames)
|
||||
if err := prometheus.Register(uncheckedCollector{gaugeVec}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Elements[mapKey] = gaugeVec
|
||||
}
|
||||
return gaugeVec.GetMetricWith(labels)
|
||||
}
|
||||
|
||||
func (c *GaugeContainer) Delete(metricName string, labelNames []string, labels prometheus.Labels) {
|
||||
mapKey := getContainerMapKey(metricName, labelNames)
|
||||
if _, ok := c.Elements[mapKey]; ok {
|
||||
c.Elements[mapKey].Delete(labels)
|
||||
metricsCount.WithLabelValues("gauge").Dec()
|
||||
}
|
||||
}
|
||||
|
||||
type SummaryContainer struct {
|
||||
Elements map[string]*prometheus.SummaryVec
|
||||
mapper *mapper.MetricMapper
|
||||
}
|
||||
|
||||
func NewSummaryContainer(mapper *mapper.MetricMapper) *SummaryContainer {
|
||||
return &SummaryContainer{
|
||||
Elements: make(map[string]*prometheus.SummaryVec),
|
||||
mapper: mapper,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *SummaryContainer) Get(metricName string, labelNames []string, labels prometheus.Labels, mc metricChecker, help string, mapping *mapper.MetricMapping) (prometheus.Observer, error) {
|
||||
mapKey := getContainerMapKey(metricName, labelNames)
|
||||
|
||||
summaryVec, ok := c.Elements[mapKey]
|
||||
if !ok {
|
||||
if mc.metricConflicts(metricName, SummaryMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
if mc.metricConflicts(metricName+"_sum", SummaryMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
if mc.metricConflicts(metricName+"_count", SummaryMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
metricsCount.WithLabelValues("summary").Inc()
|
||||
quantiles := c.mapper.Defaults.Quantiles
|
||||
if mapping != nil && mapping.Quantiles != nil && len(mapping.Quantiles) > 0 {
|
||||
quantiles = mapping.Quantiles
|
||||
}
|
||||
objectives := make(map[float64]float64)
|
||||
for _, q := range quantiles {
|
||||
objectives[q.Quantile] = q.Error
|
||||
}
|
||||
// In the case of no mapping file, explicitly define the default quantiles
|
||||
if len(objectives) == 0 {
|
||||
objectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
|
||||
}
|
||||
summaryVec = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Name: metricName,
|
||||
Help: help,
|
||||
Objectives: objectives,
|
||||
}, labelNames)
|
||||
if err := prometheus.Register(uncheckedCollector{summaryVec}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Elements[mapKey] = summaryVec
|
||||
}
|
||||
return summaryVec.GetMetricWith(labels)
|
||||
}
|
||||
|
||||
func (c *SummaryContainer) Delete(metricName string, labelNames []string, labels prometheus.Labels) {
|
||||
mapKey := getContainerMapKey(metricName, labelNames)
|
||||
if _, ok := c.Elements[mapKey]; ok {
|
||||
c.Elements[mapKey].Delete(labels)
|
||||
metricsCount.WithLabelValues("summary").Dec()
|
||||
}
|
||||
}
|
||||
|
||||
type HistogramContainer struct {
|
||||
Elements map[string]*prometheus.HistogramVec
|
||||
mapper *mapper.MetricMapper
|
||||
}
|
||||
|
||||
func NewHistogramContainer(mapper *mapper.MetricMapper) *HistogramContainer {
|
||||
return &HistogramContainer{
|
||||
Elements: make(map[string]*prometheus.HistogramVec),
|
||||
mapper: mapper,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *HistogramContainer) Get(metricName string, labelNames []string, labels prometheus.Labels, mc metricChecker, help string, mapping *mapper.MetricMapping) (prometheus.Observer, error) {
|
||||
mapKey := getContainerMapKey(metricName, labelNames)
|
||||
|
||||
histogramVec, ok := c.Elements[mapKey]
|
||||
if !ok {
|
||||
if mc.metricConflicts(metricName, HistogramMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
if mc.metricConflicts(metricName+"_sum", HistogramMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
if mc.metricConflicts(metricName+"_count", HistogramMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
if mc.metricConflicts(metricName+"_bucket", HistogramMetricType) {
|
||||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
metricsCount.WithLabelValues("histogram").Inc()
|
||||
buckets := c.mapper.Defaults.Buckets
|
||||
if mapping != nil && mapping.Buckets != nil && len(mapping.Buckets) > 0 {
|
||||
buckets = mapping.Buckets
|
||||
}
|
||||
histogramVec = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: metricName,
|
||||
Help: help,
|
||||
Buckets: buckets,
|
||||
}, labelNames)
|
||||
if err := prometheus.Register(uncheckedCollector{histogramVec}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Elements[mapKey] = histogramVec
|
||||
}
|
||||
return histogramVec.GetMetricWith(labels)
|
||||
}
|
||||
|
||||
func (c *HistogramContainer) Delete(metricName string, labelNames []string, labels prometheus.Labels) {
|
||||
mapKey := getContainerMapKey(metricName, labelNames)
|
||||
if _, ok := c.Elements[mapKey]; ok {
|
||||
c.Elements[mapKey].Delete(labels)
|
||||
metricsCount.WithLabelValues("histogram").Dec()
|
||||
}
|
||||
}
|
||||
|
||||
type Event interface {
|
||||
MetricName() string
|
||||
Value() float64
|
||||
|
@ -334,21 +89,9 @@ func (c *TimerEvent) MetricType() mapper.MetricType { return mapper.MetricTypeTi
|
|||
|
||||
type Events []Event
|
||||
|
||||
type LabelValues struct {
|
||||
lastRegisteredAt time.Time
|
||||
labels prometheus.Labels
|
||||
ttl time.Duration
|
||||
metricType metricType
|
||||
}
|
||||
|
||||
type Exporter struct {
|
||||
Counters *CounterContainer
|
||||
Gauges *GaugeContainer
|
||||
Summaries *SummaryContainer
|
||||
Histograms *HistogramContainer
|
||||
mapper *mapper.MetricMapper
|
||||
registry *registry
|
||||
labelValues map[string]map[uint64]*LabelValues
|
||||
mapper *mapper.MetricMapper
|
||||
registry *registry
|
||||
}
|
||||
|
||||
// Replace invalid characters in the metric name with "_"
|
||||
|
@ -414,7 +157,6 @@ func (b *Exporter) Listen(e <-chan Events) {
|
|||
for {
|
||||
select {
|
||||
case <-removeStaleMetricsTicker.C:
|
||||
b.removeStaleMetrics()
|
||||
b.registry.removeStaleMetrics()
|
||||
case events, ok := <-e:
|
||||
if !ok {
|
||||
|
@ -541,82 +283,10 @@ func (b *Exporter) handleEvent(event Event) {
|
|||
}
|
||||
}
|
||||
|
||||
// removeStaleMetrics removes label values set from metric with stale values
|
||||
func (b *Exporter) removeStaleMetrics() {
|
||||
now := clock.Now()
|
||||
// delete timeseries with expired ttl
|
||||
for metricName := range b.labelValues {
|
||||
for hash, lvs := range b.labelValues[metricName] {
|
||||
if lvs.ttl == 0 {
|
||||
continue
|
||||
}
|
||||
if lvs.lastRegisteredAt.Add(lvs.ttl).Before(now) {
|
||||
sortedLabelNames := getSortedLabelNames(lvs.labels)
|
||||
b.Counters.Delete(metricName, sortedLabelNames, lvs.labels)
|
||||
b.Gauges.Delete(metricName, sortedLabelNames, lvs.labels)
|
||||
b.Summaries.Delete(metricName, sortedLabelNames, lvs.labels)
|
||||
b.Histograms.Delete(metricName, sortedLabelNames, lvs.labels)
|
||||
delete(b.labelValues[metricName], hash)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// saveLabelValues stores label values set to labelValues and update lastRegisteredAt time and ttl value
|
||||
func (b *Exporter) saveLabelValues(metricName string, metricType metricType, labelNames []string, labels prometheus.Labels, ttl time.Duration) {
|
||||
metric, hasMetric := b.labelValues[metricName]
|
||||
if !hasMetric {
|
||||
metric = make(map[uint64]*LabelValues)
|
||||
b.labelValues[metricName] = metric
|
||||
}
|
||||
hash := hashNameAndLabels(metricName, labelNames, labels)
|
||||
metricLabelValues, ok := metric[hash]
|
||||
if !ok {
|
||||
metricLabelValues = &LabelValues{
|
||||
labels: labels,
|
||||
ttl: ttl,
|
||||
metricType: metricType,
|
||||
}
|
||||
b.labelValues[metricName][hash] = metricLabelValues
|
||||
}
|
||||
now := clock.Now()
|
||||
metricLabelValues.lastRegisteredAt = now
|
||||
// Update ttl from mapping
|
||||
metricLabelValues.ttl = ttl
|
||||
}
|
||||
|
||||
func (b *Exporter) metricConflicts(metricName string, metricType metricType) bool {
|
||||
metric, hasMetric := b.labelValues[metricName]
|
||||
if !hasMetric {
|
||||
// No metric with this name exists
|
||||
return false
|
||||
}
|
||||
|
||||
// The metric does exist. All metrics in the hash should be of the same
|
||||
// type, so we pick check the first one we find in the hash to check the
|
||||
// type.
|
||||
for _, lvs := range metric {
|
||||
if lvs.metricType == metricType {
|
||||
// We've found a copy of this metric with this type, but different
|
||||
// labels, so it's safe to create a new one.
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// The metric exists, but it's of a different type than we're trying to
|
||||
// create.
|
||||
return true
|
||||
}
|
||||
|
||||
func NewExporter(mapper *mapper.MetricMapper) *Exporter {
|
||||
return &Exporter{
|
||||
Counters: NewCounterContainer(),
|
||||
Gauges: NewGaugeContainer(),
|
||||
Summaries: NewSummaryContainer(mapper),
|
||||
Histograms: NewHistogramContainer(mapper),
|
||||
mapper: mapper,
|
||||
registry: newRegistry(mapper),
|
||||
labelValues: make(map[string]map[uint64]*LabelValues),
|
||||
mapper: mapper,
|
||||
registry: newRegistry(mapper),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -779,13 +779,11 @@ func getFloat64(metrics []*dto.MetricFamily, name string, labels prometheus.Labe
|
|||
}
|
||||
|
||||
var metric *dto.Metric
|
||||
sortedLabelNames := getSortedLabelNames(labels)
|
||||
labelsHash := hashNameAndLabels(name, sortedLabelNames, labels)
|
||||
labelStr := fmt.Sprintf("%v", labels)
|
||||
for _, m := range metricFamily.Metric {
|
||||
l := labelPairsAsLabels(m.GetLabel())
|
||||
sln := getSortedLabelNames(l)
|
||||
h := hashNameAndLabels(name, sln, l)
|
||||
if h == labelsHash {
|
||||
ls := fmt.Sprintf("%v", l)
|
||||
if labelStr == ls {
|
||||
metric = m
|
||||
break
|
||||
}
|
||||
|
@ -889,17 +887,14 @@ func BenchmarkHashNameAndLabels(b *testing.B) {
|
|||
}{
|
||||
{
|
||||
name: "no labels",
|
||||
metric: "counter",
|
||||
labels: map[string]string{},
|
||||
}, {
|
||||
name: "one label",
|
||||
metric: "counter",
|
||||
name: "one label",
|
||||
labels: map[string]string{
|
||||
"label": "value",
|
||||
},
|
||||
}, {
|
||||
name: "many labels",
|
||||
metric: "counter",
|
||||
name: "many labels",
|
||||
labels: map[string]string{
|
||||
"label0": "value",
|
||||
"label1": "value",
|
||||
|
@ -915,11 +910,11 @@ func BenchmarkHashNameAndLabels(b *testing.B) {
|
|||
},
|
||||
}
|
||||
|
||||
r := newRegistry(nil)
|
||||
for _, s := range scenarios {
|
||||
sortedLabelNames := getSortedLabelNames(s.labels)
|
||||
b.Run(s.name, func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
hashNameAndLabels(s.metric, sortedLabelNames, s.labels)
|
||||
r.hashLabels(s.labels)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue