Files
docker-cli/components/cli/vendor/github.com/docker/go-metrics/namespace.go
Mathieu Champlon 802dab1037 Bump moby to d37f5c6bdf788a6cb82c07fb707e31a240eff5f9
Also bringing:
. golang.org/x/net 5561cd9b4330353950f399814f427425c0a26fd2
. github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5
. github.com/docker/swarmkit bd69f6e8e301645afd344913fa1ede53a0a111fb
. github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
. github.com/prometheus/client_golang 52437c81da6b127a9925d17eb3a382a2e5fd395e
. github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
. github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
. github.com/prometheus/common ebdfc6da46522d58825777cf1f90490a5b1ef1d8
. github.com/prometheus/procfs abf152e5f3e97f2fafac028d2cc06c1feb87ffa5
. github.com/matttproud/golang_protobuf_extensions v1.0.0

Signed-off-by: Mathieu Champlon <mathieu.champlon@docker.com>
Upstream-commit: 5d54584f03
Component: cli
2018-05-18 11:44:14 +02:00

182 lines
4.4 KiB
Go

package metrics
import (
"fmt"
"sync"
"github.com/prometheus/client_golang/prometheus"
)
type Labels map[string]string
// NewNamespace returns a namespaces that is responsible for managing a collection of
// metrics for a particual namespace and subsystem
//
// labels allows const labels to be added to all metrics created in this namespace
// and are commonly used for data like application version and git commit
func NewNamespace(name, subsystem string, labels Labels) *Namespace {
if labels == nil {
labels = make(map[string]string)
}
return &Namespace{
name: name,
subsystem: subsystem,
labels: labels,
}
}
// Namespace describes a set of metrics that share a namespace and subsystem.
type Namespace struct {
name string
subsystem string
labels Labels
mu sync.Mutex
metrics []prometheus.Collector
}
// WithConstLabels returns a namespace with the provided set of labels merged
// with the existing constant labels on the namespace.
//
// Only metrics created with the returned namespace will get the new constant
// labels. The returned namespace must be registered separately.
func (n *Namespace) WithConstLabels(labels Labels) *Namespace {
n.mu.Lock()
ns := &Namespace{
name: n.name,
subsystem: n.subsystem,
labels: mergeLabels(n.labels, labels),
}
n.mu.Unlock()
return ns
}
func (n *Namespace) NewCounter(name, help string) Counter {
c := &counter{pc: prometheus.NewCounter(n.newCounterOpts(name, help))}
n.Add(c)
return c
}
func (n *Namespace) NewLabeledCounter(name, help string, labels ...string) LabeledCounter {
c := &labeledCounter{pc: prometheus.NewCounterVec(n.newCounterOpts(name, help), labels)}
n.Add(c)
return c
}
func (n *Namespace) newCounterOpts(name, help string) prometheus.CounterOpts {
return prometheus.CounterOpts{
Namespace: n.name,
Subsystem: n.subsystem,
Name: makeName(name, Total),
Help: help,
ConstLabels: prometheus.Labels(n.labels),
}
}
func (n *Namespace) NewTimer(name, help string) Timer {
t := &timer{
m: prometheus.NewHistogram(n.newTimerOpts(name, help)),
}
n.Add(t)
return t
}
func (n *Namespace) NewLabeledTimer(name, help string, labels ...string) LabeledTimer {
t := &labeledTimer{
m: prometheus.NewHistogramVec(n.newTimerOpts(name, help), labels),
}
n.Add(t)
return t
}
func (n *Namespace) newTimerOpts(name, help string) prometheus.HistogramOpts {
return prometheus.HistogramOpts{
Namespace: n.name,
Subsystem: n.subsystem,
Name: makeName(name, Seconds),
Help: help,
ConstLabels: prometheus.Labels(n.labels),
}
}
func (n *Namespace) NewGauge(name, help string, unit Unit) Gauge {
g := &gauge{
pg: prometheus.NewGauge(n.newGaugeOpts(name, help, unit)),
}
n.Add(g)
return g
}
func (n *Namespace) NewLabeledGauge(name, help string, unit Unit, labels ...string) LabeledGauge {
g := &labeledGauge{
pg: prometheus.NewGaugeVec(n.newGaugeOpts(name, help, unit), labels),
}
n.Add(g)
return g
}
func (n *Namespace) newGaugeOpts(name, help string, unit Unit) prometheus.GaugeOpts {
return prometheus.GaugeOpts{
Namespace: n.name,
Subsystem: n.subsystem,
Name: makeName(name, unit),
Help: help,
ConstLabels: prometheus.Labels(n.labels),
}
}
func (n *Namespace) Describe(ch chan<- *prometheus.Desc) {
n.mu.Lock()
defer n.mu.Unlock()
for _, metric := range n.metrics {
metric.Describe(ch)
}
}
func (n *Namespace) Collect(ch chan<- prometheus.Metric) {
n.mu.Lock()
defer n.mu.Unlock()
for _, metric := range n.metrics {
metric.Collect(ch)
}
}
func (n *Namespace) Add(collector prometheus.Collector) {
n.mu.Lock()
n.metrics = append(n.metrics, collector)
n.mu.Unlock()
}
func (n *Namespace) NewDesc(name, help string, unit Unit, labels ...string) *prometheus.Desc {
name = makeName(name, unit)
namespace := n.name
if n.subsystem != "" {
namespace = fmt.Sprintf("%s_%s", namespace, n.subsystem)
}
name = fmt.Sprintf("%s_%s", namespace, name)
return prometheus.NewDesc(name, help, labels, prometheus.Labels(n.labels))
}
// mergeLabels merges two or more labels objects into a single map, favoring
// the later labels.
func mergeLabels(lbs ...Labels) Labels {
merged := make(Labels)
for _, target := range lbs {
for k, v := range target {
merged[k] = v
}
}
return merged
}
func makeName(name string, unit Unit) string {
if unit == "" {
return name
}
return fmt.Sprintf("%s_%s", name, unit)
}