summaryrefslogtreecommitdiff
path: root/vendor/github.com/docker/go-metrics/namespace.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/docker/go-metrics/namespace.go')
-rw-r--r--vendor/github.com/docker/go-metrics/namespace.go315
1 files changed, 315 insertions, 0 deletions
diff --git a/vendor/github.com/docker/go-metrics/namespace.go b/vendor/github.com/docker/go-metrics/namespace.go
new file mode 100644
index 000000000..798315451
--- /dev/null
+++ b/vendor/github.com/docker/go-metrics/namespace.go
@@ -0,0 +1,315 @@
+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)
+}
+
+func (n *Namespace) NewDefaultHttpMetrics(handlerName string) []*HTTPMetric {
+ return n.NewHttpMetricsWithOpts(handlerName, HTTPHandlerOpts{
+ DurationBuckets: defaultDurationBuckets,
+ RequestSizeBuckets: defaultResponseSizeBuckets,
+ ResponseSizeBuckets: defaultResponseSizeBuckets,
+ })
+}
+
+func (n *Namespace) NewHttpMetrics(handlerName string, durationBuckets, requestSizeBuckets, responseSizeBuckets []float64) []*HTTPMetric {
+ return n.NewHttpMetricsWithOpts(handlerName, HTTPHandlerOpts{
+ DurationBuckets: durationBuckets,
+ RequestSizeBuckets: requestSizeBuckets,
+ ResponseSizeBuckets: responseSizeBuckets,
+ })
+}
+
+func (n *Namespace) NewHttpMetricsWithOpts(handlerName string, opts HTTPHandlerOpts) []*HTTPMetric {
+ var httpMetrics []*HTTPMetric
+ inFlightMetric := n.NewInFlightGaugeMetric(handlerName)
+ requestTotalMetric := n.NewRequestTotalMetric(handlerName)
+ requestDurationMetric := n.NewRequestDurationMetric(handlerName, opts.DurationBuckets)
+ requestSizeMetric := n.NewRequestSizeMetric(handlerName, opts.RequestSizeBuckets)
+ responseSizeMetric := n.NewResponseSizeMetric(handlerName, opts.ResponseSizeBuckets)
+ httpMetrics = append(httpMetrics, inFlightMetric, requestDurationMetric, requestTotalMetric, requestSizeMetric, responseSizeMetric)
+ return httpMetrics
+}
+
+func (n *Namespace) NewInFlightGaugeMetric(handlerName string) *HTTPMetric {
+ labels := prometheus.Labels(n.labels)
+ labels["handler"] = handlerName
+ metric := prometheus.NewGauge(prometheus.GaugeOpts{
+ Namespace: n.name,
+ Subsystem: n.subsystem,
+ Name: "in_flight_requests",
+ Help: "The in-flight HTTP requests",
+ ConstLabels: prometheus.Labels(labels),
+ })
+ httpMetric := &HTTPMetric{
+ Collector: metric,
+ handlerType: InstrumentHandlerInFlight,
+ }
+ n.Add(httpMetric)
+ return httpMetric
+}
+
+func (n *Namespace) NewRequestTotalMetric(handlerName string) *HTTPMetric {
+ labels := prometheus.Labels(n.labels)
+ labels["handler"] = handlerName
+ metric := prometheus.NewCounterVec(
+ prometheus.CounterOpts{
+ Namespace: n.name,
+ Subsystem: n.subsystem,
+ Name: "requests_total",
+ Help: "Total number of HTTP requests made.",
+ ConstLabels: prometheus.Labels(labels),
+ },
+ []string{"code", "method"},
+ )
+ httpMetric := &HTTPMetric{
+ Collector: metric,
+ handlerType: InstrumentHandlerCounter,
+ }
+ n.Add(httpMetric)
+ return httpMetric
+}
+func (n *Namespace) NewRequestDurationMetric(handlerName string, buckets []float64) *HTTPMetric {
+ if len(buckets) == 0 {
+ panic("DurationBuckets must be provided")
+ }
+ labels := prometheus.Labels(n.labels)
+ labels["handler"] = handlerName
+ opts := prometheus.HistogramOpts{
+ Namespace: n.name,
+ Subsystem: n.subsystem,
+ Name: "request_duration_seconds",
+ Help: "The HTTP request latencies in seconds.",
+ Buckets: buckets,
+ ConstLabels: prometheus.Labels(labels),
+ }
+ metric := prometheus.NewHistogramVec(opts, []string{"method"})
+ httpMetric := &HTTPMetric{
+ Collector: metric,
+ handlerType: InstrumentHandlerDuration,
+ }
+ n.Add(httpMetric)
+ return httpMetric
+}
+
+func (n *Namespace) NewRequestSizeMetric(handlerName string, buckets []float64) *HTTPMetric {
+ if len(buckets) == 0 {
+ panic("RequestSizeBuckets must be provided")
+ }
+ labels := prometheus.Labels(n.labels)
+ labels["handler"] = handlerName
+ opts := prometheus.HistogramOpts{
+ Namespace: n.name,
+ Subsystem: n.subsystem,
+ Name: "request_size_bytes",
+ Help: "The HTTP request sizes in bytes.",
+ Buckets: buckets,
+ ConstLabels: prometheus.Labels(labels),
+ }
+ metric := prometheus.NewHistogramVec(opts, []string{})
+ httpMetric := &HTTPMetric{
+ Collector: metric,
+ handlerType: InstrumentHandlerRequestSize,
+ }
+ n.Add(httpMetric)
+ return httpMetric
+}
+
+func (n *Namespace) NewResponseSizeMetric(handlerName string, buckets []float64) *HTTPMetric {
+ if len(buckets) == 0 {
+ panic("ResponseSizeBuckets must be provided")
+ }
+ labels := prometheus.Labels(n.labels)
+ labels["handler"] = handlerName
+ opts := prometheus.HistogramOpts{
+ Namespace: n.name,
+ Subsystem: n.subsystem,
+ Name: "response_size_bytes",
+ Help: "The HTTP response sizes in bytes.",
+ Buckets: buckets,
+ ConstLabels: prometheus.Labels(labels),
+ }
+ metrics := prometheus.NewHistogramVec(opts, []string{})
+ httpMetric := &HTTPMetric{
+ Collector: metrics,
+ handlerType: InstrumentHandlerResponseSize,
+ }
+ n.Add(httpMetric)
+ return httpMetric
+}