summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/armon/go-metrics/prometheus/prometheus.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/armon/go-metrics/prometheus/prometheus.go')
-rw-r--r--vendor/github.com/armon/go-metrics/prometheus/prometheus.go96
1 files changed, 84 insertions, 12 deletions
diff --git a/vendor/github.com/armon/go-metrics/prometheus/prometheus.go b/vendor/github.com/armon/go-metrics/prometheus/prometheus.go
index a647e5965..a5b27d6d3 100644
--- a/vendor/github.com/armon/go-metrics/prometheus/prometheus.go
+++ b/vendor/github.com/armon/go-metrics/prometheus/prometheus.go
@@ -13,19 +13,91 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
+var (
+ // DefaultPrometheusOpts is the default set of options used when creating a
+ // PrometheusSink.
+ DefaultPrometheusOpts = PrometheusOpts{
+ Expiration: 60 * time.Second,
+ }
+)
+
+// PrometheusOpts is used to configure the Prometheus Sink
+type PrometheusOpts struct {
+ // Expiration is the duration a metric is valid for, after which it will be
+ // untracked. If the value is zero, a metric is never expired.
+ Expiration time.Duration
+}
+
type PrometheusSink struct {
- mu sync.Mutex
- gauges map[string]prometheus.Gauge
- summaries map[string]prometheus.Summary
- counters map[string]prometheus.Counter
+ mu sync.Mutex
+ gauges map[string]prometheus.Gauge
+ summaries map[string]prometheus.Summary
+ counters map[string]prometheus.Counter
+ updates map[string]time.Time
+ expiration time.Duration
}
+// NewPrometheusSink creates a new PrometheusSink using the default options.
func NewPrometheusSink() (*PrometheusSink, error) {
- return &PrometheusSink{
- gauges: make(map[string]prometheus.Gauge),
- summaries: make(map[string]prometheus.Summary),
- counters: make(map[string]prometheus.Counter),
- }, nil
+ return NewPrometheusSinkFrom(DefaultPrometheusOpts)
+}
+
+// NewPrometheusSinkFrom creates a new PrometheusSink using the passed options.
+func NewPrometheusSinkFrom(opts PrometheusOpts) (*PrometheusSink, error) {
+ sink := &PrometheusSink{
+ gauges: make(map[string]prometheus.Gauge),
+ summaries: make(map[string]prometheus.Summary),
+ counters: make(map[string]prometheus.Counter),
+ updates: make(map[string]time.Time),
+ expiration: opts.Expiration,
+ }
+
+ return sink, prometheus.Register(sink)
+}
+
+// Describe is needed to meet the Collector interface.
+func (p *PrometheusSink) Describe(c chan<- *prometheus.Desc) {
+ // We must emit some description otherwise an error is returned. This
+ // description isn't shown to the user!
+ prometheus.NewGauge(prometheus.GaugeOpts{Name: "Dummy", Help: "Dummy"}).Describe(c)
+}
+
+// Collect meets the collection interface and allows us to enforce our expiration
+// logic to clean up ephemeral metrics if their value haven't been set for a
+// duration exceeding our allowed expiration time.
+func (p *PrometheusSink) Collect(c chan<- prometheus.Metric) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+
+ expire := p.expiration != 0
+ now := time.Now()
+ for k, v := range p.gauges {
+ last := p.updates[k]
+ if expire && last.Add(p.expiration).Before(now) {
+ delete(p.updates, k)
+ delete(p.gauges, k)
+ } else {
+ v.Collect(c)
+ }
+ }
+ for k, v := range p.summaries {
+ last := p.updates[k]
+ if expire && last.Add(p.expiration).Before(now) {
+ delete(p.updates, k)
+ delete(p.summaries, k)
+ } else {
+ v.Collect(c)
+ }
+ }
+ for k, v := range p.counters {
+ last := p.updates[k]
+ if expire && last.Add(p.expiration).Before(now) {
+ delete(p.updates, k)
+ delete(p.counters, k)
+ } else {
+ v.Collect(c)
+ }
+ }
}
var forbiddenChars = regexp.MustCompile("[ .=\\-]")
@@ -65,10 +137,10 @@ func (p *PrometheusSink) SetGaugeWithLabels(parts []string, val float32, labels
Help: key,
ConstLabels: prometheusLabels(labels),
})
- prometheus.MustRegister(g)
p.gauges[hash] = g
}
g.Set(float64(val))
+ p.updates[hash] = time.Now()
}
func (p *PrometheusSink) AddSample(parts []string, val float32) {
@@ -87,10 +159,10 @@ func (p *PrometheusSink) AddSampleWithLabels(parts []string, val float32, labels
MaxAge: 10 * time.Second,
ConstLabels: prometheusLabels(labels),
})
- prometheus.MustRegister(g)
p.summaries[hash] = g
}
g.Observe(float64(val))
+ p.updates[hash] = time.Now()
}
// EmitKey is not implemented. Prometheus doesn’t offer a type for which an
@@ -114,8 +186,8 @@ func (p *PrometheusSink) IncrCounterWithLabels(parts []string, val float32, labe
Help: key,
ConstLabels: prometheusLabels(labels),
})
- prometheus.MustRegister(g)
p.counters[hash] = g
}
g.Add(float64(val))
+ p.updates[hash] = time.Now()
}