From f66cdf0736e89ebb8fd37057cd0f7da2cd8386d4 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Wed, 28 Jun 2017 17:55:59 +0200 Subject: [PATCH] Un-export MetricVec This is in preparation for "curried" metric vecs, as discussed. And it's a good thing anyway. The exported MetricVec was from a time when I thought people would define own Metric types and then create Vecs of it. That has never happened. --- prometheus/counter.go | 56 ++++++++++++----- prometheus/gauge.go | 56 ++++++++++++----- prometheus/histogram.go | 57 +++++++++++++----- prometheus/summary.go | 57 +++++++++++++----- prometheus/untyped.go | 53 ++++++++++++---- prometheus/vec.go | 130 ++++++++++++++-------------------------- 6 files changed, 255 insertions(+), 154 deletions(-) diff --git a/prometheus/counter.go b/prometheus/counter.go index 72d5256..44b48c5 100644 --- a/prometheus/counter.go +++ b/prometheus/counter.go @@ -74,12 +74,11 @@ func (c *counter) Add(v float64) { // CounterVec embeds MetricVec. See there for a full list of methods with // detailed documentation. type CounterVec struct { - *MetricVec + *metricVec } // NewCounterVec creates a new CounterVec based on the provided CounterOpts and -// partitioned by the given label names. At least one label name must be -// provided. +// partitioned by the given label names. func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { desc := NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), @@ -88,7 +87,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { opts.ConstLabels, ) return &CounterVec{ - MetricVec: newMetricVec(desc, func(lvs ...string) Metric { + metricVec: newMetricVec(desc, func(lvs ...string) Metric { result := &counter{value: value{ desc: desc, valType: CounterValue, @@ -100,22 +99,51 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { } } -// GetMetricWithLabelValues replaces the method of the same name in -// MetricVec. The difference is that this method returns a Counter and not a -// Metric so that no type conversion is required. +// GetMetricWithLabelValues returns the Counter for the given slice of label +// values (same order as the VariableLabels in Desc). If that combination of +// label values is accessed for the first time, a new Counter is created. +// +// It is possible to call this method without using the returned Counter to only +// create the new Counter but leave it at its starting value 0. See also the +// SummaryVec example. +// +// Keeping the Counter for later use is possible (and should be considered if +// performance is critical), but keep in mind that Reset, DeleteLabelValues and +// Delete can be used to delete the Counter from the CounterVec. In that case, +// the Counter will still exist, but it will not be exported anymore, even if a +// Counter with the same label values is created later. +// +// An error is returned if the number of label values is not the same as the +// number of VariableLabels in Desc. +// +// Note that for more than one label value, this method is prone to mistakes +// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as +// an alternative to avoid that type of mistake. For higher label numbers, the +// latter has a much more readable (albeit more verbose) syntax, but it comes +// with a performance overhead (for creating and processing the Labels map). +// See also the GaugeVec example. func (m *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) { - metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) + metric, err := m.metricVec.getMetricWithLabelValues(lvs...) if metric != nil { return metric.(Counter), err } return nil, err } -// GetMetricWith replaces the method of the same name in MetricVec. The -// difference is that this method returns a Counter and not a Metric so that no -// type conversion is required. +// GetMetricWith returns the Counter for the given Labels map (the label names +// must match those of the VariableLabels in Desc). If that label map is +// accessed for the first time, a new Counter is created. Implications of +// creating a Counter without using it and keeping the Counter for later use are +// the same as for GetMetricWithLabelValues. +// +// An error is returned if the number and names of the Labels are inconsistent +// with those of the VariableLabels in Desc. +// +// This method is used for the same purpose as +// GetMetricWithLabelValues(...string). See there for pros and cons of the two +// methods. func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) { - metric, err := m.MetricVec.GetMetricWith(labels) + metric, err := m.metricVec.getMetricWith(labels) if metric != nil { return metric.(Counter), err } @@ -127,14 +155,14 @@ func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) { // error, WithLabelValues allows shortcuts like // myVec.WithLabelValues("404", "GET").Add(42) func (m *CounterVec) WithLabelValues(lvs ...string) Counter { - return m.MetricVec.WithLabelValues(lvs...).(Counter) + return m.metricVec.withLabelValues(lvs...).(Counter) } // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. By not returning an error, With allows shortcuts like // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) func (m *CounterVec) With(labels Labels) Counter { - return m.MetricVec.With(labels).(Counter) + return m.metricVec.with(labels).(Counter) } // CounterFunc is a Counter whose value is determined at collect time by calling a diff --git a/prometheus/gauge.go b/prometheus/gauge.go index 9ab5a3d..13064da 100644 --- a/prometheus/gauge.go +++ b/prometheus/gauge.go @@ -63,12 +63,11 @@ func NewGauge(opts GaugeOpts) Gauge { // (e.g. number of operations queued, partitioned by user and operation // type). Create instances with NewGaugeVec. type GaugeVec struct { - *MetricVec + *metricVec } // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and -// partitioned by the given label names. At least one label name must be -// provided. +// partitioned by the given label names. func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { desc := NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), @@ -77,28 +76,57 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { opts.ConstLabels, ) return &GaugeVec{ - MetricVec: newMetricVec(desc, func(lvs ...string) Metric { + metricVec: newMetricVec(desc, func(lvs ...string) Metric { return newValue(desc, GaugeValue, 0, lvs...) }), } } -// GetMetricWithLabelValues replaces the method of the same name in -// MetricVec. The difference is that this method returns a Gauge and not a -// Metric so that no type conversion is required. +// GetMetricWithLabelValues returns the Gauge for the given slice of label +// values (same order as the VariableLabels in Desc). If that combination of +// label values is accessed for the first time, a new Gauge is created. +// +// It is possible to call this method without using the returned Gauge to only +// create the new Gauge but leave it at its starting value 0. See also the +// SummaryVec example. +// +// Keeping the Gauge for later use is possible (and should be considered if +// performance is critical), but keep in mind that Reset, DeleteLabelValues and +// Delete can be used to delete the Gauge from the GaugeVec. In that case, the +// Gauge will still exist, but it will not be exported anymore, even if a +// Gauge with the same label values is created later. See also the CounterVec +// example. +// +// An error is returned if the number of label values is not the same as the +// number of VariableLabels in Desc. +// +// Note that for more than one label value, this method is prone to mistakes +// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as +// an alternative to avoid that type of mistake. For higher label numbers, the +// latter has a much more readable (albeit more verbose) syntax, but it comes +// with a performance overhead (for creating and processing the Labels map). func (m *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) { - metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) + metric, err := m.metricVec.getMetricWithLabelValues(lvs...) if metric != nil { return metric.(Gauge), err } return nil, err } -// GetMetricWith replaces the method of the same name in MetricVec. The -// difference is that this method returns a Gauge and not a Metric so that no -// type conversion is required. +// GetMetricWith returns the Gauge for the given Labels map (the label names +// must match those of the VariableLabels in Desc). If that label map is +// accessed for the first time, a new Gauge is created. Implications of +// creating a Gauge without using it and keeping the Gauge for later use are +// the same as for GetMetricWithLabelValues. +// +// An error is returned if the number and names of the Labels are inconsistent +// with those of the VariableLabels in Desc. +// +// This method is used for the same purpose as +// GetMetricWithLabelValues(...string). See there for pros and cons of the two +// methods. func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { - metric, err := m.MetricVec.GetMetricWith(labels) + metric, err := m.metricVec.getMetricWith(labels) if metric != nil { return metric.(Gauge), err } @@ -110,14 +138,14 @@ func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { // error, WithLabelValues allows shortcuts like // myVec.WithLabelValues("404", "GET").Add(42) func (m *GaugeVec) WithLabelValues(lvs ...string) Gauge { - return m.MetricVec.WithLabelValues(lvs...).(Gauge) + return m.metricVec.withLabelValues(lvs...).(Gauge) } // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. By not returning an error, With allows shortcuts like // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) func (m *GaugeVec) With(labels Labels) Gauge { - return m.MetricVec.With(labels).(Gauge) + return m.metricVec.with(labels).(Gauge) } // GaugeFunc is a Gauge whose value is determined at collect time by calling a diff --git a/prometheus/histogram.go b/prometheus/histogram.go index f46eff6..4e0a9c8 100644 --- a/prometheus/histogram.go +++ b/prometheus/histogram.go @@ -287,12 +287,11 @@ func (h *histogram) Write(out *dto.Metric) error { // (e.g. HTTP request latencies, partitioned by status code and method). Create // instances with NewHistogramVec. type HistogramVec struct { - *MetricVec + *metricVec } // NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and -// partitioned by the given label names. At least one label name must be -// provided. +// partitioned by the given label names. func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec { desc := NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), @@ -301,28 +300,58 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec { opts.ConstLabels, ) return &HistogramVec{ - MetricVec: newMetricVec(desc, func(lvs ...string) Metric { + metricVec: newMetricVec(desc, func(lvs ...string) Metric { return newHistogram(desc, opts, lvs...) }), } } -// GetMetricWithLabelValues replaces the method of the same name in -// MetricVec. The difference is that this method returns an Observer and not a -// Metric so that no type conversion to an Observer is required. +// GetMetricWithLabelValues returns the Histogram for the given slice of label +// values (same order as the VariableLabels in Desc). If that combination of +// label values is accessed for the first time, a new Histogram is created. +// +// It is possible to call this method without using the returned Histogram to only +// create the new Histogram but leave it at its starting value, a Histogram without +// any observations. +// +// Keeping the Histogram for later use is possible (and should be considered if +// performance is critical), but keep in mind that Reset, DeleteLabelValues and +// Delete can be used to delete the Histogram from the HistogramVec. In that case, the +// Histogram will still exist, but it will not be exported anymore, even if a +// Histogram with the same label values is created later. See also the CounterVec +// example. +// +// An error is returned if the number of label values is not the same as the +// number of VariableLabels in Desc. +// +// Note that for more than one label value, this method is prone to mistakes +// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as +// an alternative to avoid that type of mistake. For higher label numbers, the +// latter has a much more readable (albeit more verbose) syntax, but it comes +// with a performance overhead (for creating and processing the Labels map). +// See also the GaugeVec example. func (m *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { - metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) + metric, err := m.metricVec.getMetricWithLabelValues(lvs...) if metric != nil { return metric.(Observer), err } return nil, err } -// GetMetricWith replaces the method of the same name in MetricVec. The -// difference is that this method returns an Observer and not a Metric so that no -// type conversion to an Observer is required. +// GetMetricWith returns the Histogram for the given Labels map (the label names +// must match those of the VariableLabels in Desc). If that label map is +// accessed for the first time, a new Histogram is created. Implications of +// creating a Histogram without using it and keeping the Histogram for later use +// are the same as for GetMetricWithLabelValues. +// +// An error is returned if the number and names of the Labels are inconsistent +// with those of the VariableLabels in Desc. +// +// This method is used for the same purpose as +// GetMetricWithLabelValues(...string). See there for pros and cons of the two +// methods. func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) { - metric, err := m.MetricVec.GetMetricWith(labels) + metric, err := m.metricVec.getMetricWith(labels) if metric != nil { return metric.(Observer), err } @@ -334,14 +363,14 @@ func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) { // error, WithLabelValues allows shortcuts like // myVec.WithLabelValues("404", "GET").Observe(42.21) func (m *HistogramVec) WithLabelValues(lvs ...string) Observer { - return m.MetricVec.WithLabelValues(lvs...).(Observer) + return m.metricVec.withLabelValues(lvs...).(Observer) } // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. By not returning an error, With allows shortcuts like // myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21) func (m *HistogramVec) With(labels Labels) Observer { - return m.MetricVec.With(labels).(Observer) + return m.metricVec.with(labels).(Observer) } type constHistogram struct { diff --git a/prometheus/summary.go b/prometheus/summary.go index 1c65e25..964d8cb 100644 --- a/prometheus/summary.go +++ b/prometheus/summary.go @@ -399,12 +399,11 @@ func (s quantSort) Less(i, j int) bool { // (e.g. HTTP request latencies, partitioned by status code and method). Create // instances with NewSummaryVec. type SummaryVec struct { - *MetricVec + *metricVec } // NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and -// partitioned by the given label names. At least one label name must be -// provided. +// partitioned by the given label names. func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { desc := NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), @@ -413,28 +412,58 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { opts.ConstLabels, ) return &SummaryVec{ - MetricVec: newMetricVec(desc, func(lvs ...string) Metric { + metricVec: newMetricVec(desc, func(lvs ...string) Metric { return newSummary(desc, opts, lvs...) }), } } -// GetMetricWithLabelValues replaces the method of the same name in MetricVec. -// The difference is that this method returns an Observer and not a Metric so -// that no type conversion to an Observer is required. +// GetMetricWithLabelValues returns the Summary for the given slice of label +// values (same order as the VariableLabels in Desc). If that combination of +// label values is accessed for the first time, a new Summary is created. +// +// It is possible to call this method without using the returned Summary to only +// create the new Summary but leave it at its starting value, a Summary without +// any observations. +// +// Keeping the Summary for later use is possible (and should be considered if +// performance is critical), but keep in mind that Reset, DeleteLabelValues and +// Delete can be used to delete the Summary from the SummaryVec. In that case, the +// Summary will still exist, but it will not be exported anymore, even if a +// Summary with the same label values is created later. See also the CounterVec +// example. +// +// An error is returned if the number of label values is not the same as the +// number of VariableLabels in Desc. +// +// Note that for more than one label value, this method is prone to mistakes +// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as +// an alternative to avoid that type of mistake. For higher label numbers, the +// latter has a much more readable (albeit more verbose) syntax, but it comes +// with a performance overhead (for creating and processing the Labels map). +// See also the GaugeVec example. func (m *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { - metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) + metric, err := m.metricVec.getMetricWithLabelValues(lvs...) if metric != nil { return metric.(Observer), err } return nil, err } -// GetMetricWith replaces the method of the same name in MetricVec. The -// difference is that this method returns an Observer and not a Metric so that -// no type conversion to an Observer is required. +// GetMetricWith returns the Summary for the given Labels map (the label names +// must match those of the VariableLabels in Desc). If that label map is +// accessed for the first time, a new Summary is created. Implications of +// creating a Summary without using it and keeping the Summary for later use are +// the same as for GetMetricWithLabelValues. +// +// An error is returned if the number and names of the Labels are inconsistent +// with those of the VariableLabels in Desc. +// +// This method is used for the same purpose as +// GetMetricWithLabelValues(...string). See there for pros and cons of the two +// methods. func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) { - metric, err := m.MetricVec.GetMetricWith(labels) + metric, err := m.metricVec.getMetricWith(labels) if metric != nil { return metric.(Observer), err } @@ -446,14 +475,14 @@ func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) { // error, WithLabelValues allows shortcuts like // myVec.WithLabelValues("404", "GET").Observe(42.21) func (m *SummaryVec) WithLabelValues(lvs ...string) Observer { - return m.MetricVec.WithLabelValues(lvs...).(Observer) + return m.metricVec.withLabelValues(lvs...).(Observer) } // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. By not returning an error, With allows shortcuts like // myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21) func (m *SummaryVec) With(labels Labels) Observer { - return m.MetricVec.With(labels).(Observer) + return m.metricVec.with(labels).(Observer) } type constSummary struct { diff --git a/prometheus/untyped.go b/prometheus/untyped.go index 374bc2b..bb39b76 100644 --- a/prometheus/untyped.go +++ b/prometheus/untyped.go @@ -67,8 +67,7 @@ type UntypedVec struct { } // NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and -// partitioned by the given label names. At least one label name must be -// provided. +// partitioned by the given label names. func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec { desc := NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), @@ -83,22 +82,52 @@ func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec { } } -// GetMetricWithLabelValues replaces the method of the same name in -// MetricVec. The difference is that this method returns an Untyped and not a -// Metric so that no type conversion is required. +// GetMetricWithLabelValues returns the Untyped for the given slice of label +// values (same order as the VariableLabels in Desc). If that combination of +// label values is accessed for the first time, a new Untyped is created. +// +// It is possible to call this method without using the returned Untyped to only +// create the new Untyped but leave it at its starting value 0. See also the +// SummaryVec example. +// +// Keeping the Untyped for later use is possible (and should be considered if +// performance is critical), but keep in mind that Reset, DeleteLabelValues and +// Delete can be used to delete the Untyped from the UntypedVec. In that case, the +// Untyped will still exist, but it will not be exported anymore, even if a +// Untyped with the same label values is created later. See also the CounterVec +// example. +// +// An error is returned if the number of label values is not the same as the +// number of VariableLabels in Desc. +// +// Note that for more than one label value, this method is prone to mistakes +// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as +// an alternative to avoid that type of mistake. For higher label numbers, the +// latter has a much more readable (albeit more verbose) syntax, but it comes +// with a performance overhead (for creating and processing the Labels map). +// See also the GaugeVec example. func (m *UntypedVec) GetMetricWithLabelValues(lvs ...string) (Untyped, error) { - metric, err := m.metricVec.GetMetricWithLabelValues(lvs...) + metric, err := m.metricVec.getMetricWithLabelValues(lvs...) if metric != nil { return metric.(Untyped), err } return nil, err } -// GetMetricWith replaces the method of the same name in MetricVec. The -// difference is that this method returns an Untyped and not a Metric so that no -// type conversion is required. +// GetMetricWith returns the Untyped for the given Labels map (the label names +// must match those of the VariableLabels in Desc). If that label map is +// accessed for the first time, a new Untyped is created. Implications of +// creating a Untyped without using it and keeping the Untyped for later use are +// the same as for GetMetricWithLabelValues. +// +// An error is returned if the number and names of the Labels are inconsistent +// with those of the VariableLabels in Desc. +// +// This method is used for the same purpose as +// GetMetricWithLabelValues(...string). See there for pros and cons of the two +// methods. func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error) { - metric, err := m.metricVec.GetMetricWith(labels) + metric, err := m.metricVec.getMetricWith(labels) if metric != nil { return metric.(Untyped), err } @@ -110,14 +139,14 @@ func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error) { // error, WithLabelValues allows shortcuts like // myVec.WithLabelValues("404", "GET").Add(42) func (m *UntypedVec) WithLabelValues(lvs ...string) Untyped { - return m.metricVec.WithLabelValues(lvs...).(Untyped) + return m.metricVec.withLabelValues(lvs...).(Untyped) } // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. By not returning an error, With allows shortcuts like // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) func (m *UntypedVec) With(labels Labels) Untyped { - return m.metricVec.With(labels).(Untyped) + return m.metricVec.with(labels).(Untyped) } // UntypedFunc is an Untyped whose value is determined at collect time by diff --git a/prometheus/vec.go b/prometheus/vec.go index 7f3eef9..c493b24 100644 --- a/prometheus/vec.go +++ b/prometheus/vec.go @@ -20,12 +20,12 @@ import ( "github.com/prometheus/common/model" ) -// MetricVec is a Collector to bundle metrics of the same name that -// differ in their label values. MetricVec is usually not used directly but as a -// building block for implementations of vectors of a given metric -// type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already -// provided in this package. -type MetricVec struct { +// metricVec is a Collector to bundle metrics of the same name that differ in +// their label values. metricVec is not used directly (and therefore +// unexported). It is used as a building block for implementations of vectors of +// a given metric type, like GaugeVec, CounterVec, SummaryVec, HistogramVec, and +// UntypedVec. +type metricVec struct { mtx sync.RWMutex // Protects the children. children map[uint64][]metricWithLabelValues desc *Desc @@ -37,8 +37,8 @@ type MetricVec struct { // newMetricVec returns an initialized MetricVec. The concrete value is // returned for embedding into another struct. -func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec { - return &MetricVec{ +func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *metricVec { + return &metricVec{ children: map[uint64][]metricWithLabelValues{}, desc: desc, newMetric: newMetric, @@ -56,12 +56,12 @@ type metricWithLabelValues struct { // Describe implements Collector. The length of the returned slice // is always one. -func (m *MetricVec) Describe(ch chan<- *Desc) { +func (m *metricVec) Describe(ch chan<- *Desc) { ch <- m.desc } // Collect implements Collector. -func (m *MetricVec) Collect(ch chan<- Metric) { +func (m *metricVec) Collect(ch chan<- Metric) { m.mtx.RLock() defer m.mtx.RUnlock() @@ -72,31 +72,7 @@ func (m *MetricVec) Collect(ch chan<- Metric) { } } -// GetMetricWithLabelValues returns the Metric for the given slice of label -// values (same order as the VariableLabels in Desc). If that combination of -// label values is accessed for the first time, a new Metric is created. -// -// It is possible to call this method without using the returned Metric to only -// create the new Metric but leave it at its start value (e.g. a Summary or -// Histogram without any observations). See also the SummaryVec example. -// -// Keeping the Metric for later use is possible (and should be considered if -// performance is critical), but keep in mind that Reset, DeleteLabelValues and -// Delete can be used to delete the Metric from the MetricVec. In that case, the -// Metric will still exist, but it will not be exported anymore, even if a -// Metric with the same label values is created later. See also the CounterVec -// example. -// -// An error is returned if the number of label values is not the same as the -// number of VariableLabels in Desc. -// -// Note that for more than one label value, this method is prone to mistakes -// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as -// an alternative to avoid that type of mistake. For higher label numbers, the -// latter has a much more readable (albeit more verbose) syntax, but it comes -// with a performance overhead (for creating and processing the Labels map). -// See also the GaugeVec example. -func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { +func (m *metricVec) getMetricWithLabelValues(lvs ...string) (Metric, error) { h, err := m.hashLabelValues(lvs) if err != nil { return nil, err @@ -105,19 +81,7 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { return m.getOrCreateMetricWithLabelValues(h, lvs), nil } -// GetMetricWith returns the Metric for the given Labels map (the label names -// must match those of the VariableLabels in Desc). If that label map is -// accessed for the first time, a new Metric is created. Implications of -// creating a Metric without using it and keeping the Metric for later use are -// the same as for GetMetricWithLabelValues. -// -// An error is returned if the number and names of the Labels are inconsistent -// with those of the VariableLabels in Desc. -// -// This method is used for the same purpose as -// GetMetricWithLabelValues(...string). See there for pros and cons of the two -// methods. -func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) { +func (m *metricVec) getMetricWith(labels Labels) (Metric, error) { h, err := m.hashLabels(labels) if err != nil { return nil, err @@ -126,22 +90,16 @@ func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) { return m.getOrCreateMetricWithLabels(h, labels), nil } -// WithLabelValues works as GetMetricWithLabelValues, but panics if an error -// occurs. The method allows neat syntax like: -// httpReqs.WithLabelValues("404", "POST").Inc() -func (m *MetricVec) WithLabelValues(lvs ...string) Metric { - metric, err := m.GetMetricWithLabelValues(lvs...) +func (m *metricVec) withLabelValues(lvs ...string) Metric { + metric, err := m.getMetricWithLabelValues(lvs...) if err != nil { panic(err) } return metric } -// With works as GetMetricWith, but panics if an error occurs. The method allows -// neat syntax like: -// httpReqs.With(Labels{"status":"404", "method":"POST"}).Inc() -func (m *MetricVec) With(labels Labels) Metric { - metric, err := m.GetMetricWith(labels) +func (m *metricVec) with(labels Labels) Metric { + metric, err := m.getMetricWith(labels) if err != nil { panic(err) } @@ -153,8 +111,8 @@ func (m *MetricVec) With(labels Labels) Metric { // returns true if a metric was deleted. // // It is not an error if the number of label values is not the same as the -// number of VariableLabels in Desc. However, such inconsistent label count can -// never match an actual Metric, so the method will always return false in that +// number of VariableLabels in Desc. However, such inconsistent label count can +// never match an actual metric, so the method will always return false in that // case. // // Note that for more than one label value, this method is prone to mistakes @@ -163,7 +121,7 @@ func (m *MetricVec) With(labels Labels) Metric { // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). // See also the CounterVec example. -func (m *MetricVec) DeleteLabelValues(lvs ...string) bool { +func (m *metricVec) DeleteLabelValues(lvs ...string) bool { m.mtx.Lock() defer m.mtx.Unlock() @@ -178,13 +136,13 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool { // passed in as labels. It returns true if a metric was deleted. // // It is not an error if the number and names of the Labels are inconsistent -// with those of the VariableLabels in the Desc of the MetricVec. However, such -// inconsistent Labels can never match an actual Metric, so the method will -// always return false in that case. +// with those of the VariableLabels in Desc. However, such inconsistent Labels +// can never match an actual metric, so the method will always return false in +// that case. // // This method is used for the same purpose as DeleteLabelValues(...string). See // there for pros and cons of the two methods. -func (m *MetricVec) Delete(labels Labels) bool { +func (m *metricVec) Delete(labels Labels) bool { m.mtx.Lock() defer m.mtx.Unlock() @@ -199,7 +157,7 @@ func (m *MetricVec) Delete(labels Labels) bool { // deleteByHashWithLabelValues removes the metric from the hash bucket h. If // there are multiple matches in the bucket, use lvs to select a metric and // remove only that metric. -func (m *MetricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool { +func (m *metricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool { metrics, ok := m.children[h] if !ok { return false @@ -221,7 +179,7 @@ func (m *MetricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool { // deleteByHashWithLabels removes the metric from the hash bucket h. If there // are multiple matches in the bucket, use lvs to select a metric and remove // only that metric. -func (m *MetricVec) deleteByHashWithLabels(h uint64, labels Labels) bool { +func (m *metricVec) deleteByHashWithLabels(h uint64, labels Labels) bool { metrics, ok := m.children[h] if !ok { return false @@ -240,7 +198,7 @@ func (m *MetricVec) deleteByHashWithLabels(h uint64, labels Labels) bool { } // Reset deletes all metrics in this vector. -func (m *MetricVec) Reset() { +func (m *metricVec) Reset() { m.mtx.Lock() defer m.mtx.Unlock() @@ -249,7 +207,7 @@ func (m *MetricVec) Reset() { } } -func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) { +func (m *metricVec) hashLabelValues(vals []string) (uint64, error) { if len(vals) != len(m.desc.variableLabels) { return 0, errInconsistentCardinality } @@ -261,7 +219,7 @@ func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) { return h, nil } -func (m *MetricVec) hashLabels(labels Labels) (uint64, error) { +func (m *metricVec) hashLabels(labels Labels) (uint64, error) { if len(labels) != len(m.desc.variableLabels) { return 0, errInconsistentCardinality } @@ -281,9 +239,9 @@ func (m *MetricVec) hashLabels(labels Labels) (uint64, error) { // or creates it and returns the new one. // // This function holds the mutex. -func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) Metric { +func (m *metricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) Metric { m.mtx.RLock() - metric, ok := m.getMetricWithLabelValues(hash, lvs) + metric, ok := m.getMetricWithHashAndLabelValues(hash, lvs) m.mtx.RUnlock() if ok { return metric @@ -291,7 +249,7 @@ func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) m.mtx.Lock() defer m.mtx.Unlock() - metric, ok = m.getMetricWithLabelValues(hash, lvs) + metric, ok = m.getMetricWithHashAndLabelValues(hash, lvs) if !ok { // Copy to avoid allocation in case wo don't go down this code path. copiedLVs := make([]string, len(lvs)) @@ -306,9 +264,9 @@ func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) // or creates it and returns the new one. // // This function holds the mutex. -func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metric { +func (m *metricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metric { m.mtx.RLock() - metric, ok := m.getMetricWithLabels(hash, labels) + metric, ok := m.getMetricWithHashAndLabels(hash, labels) m.mtx.RUnlock() if ok { return metric @@ -316,7 +274,7 @@ func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metr m.mtx.Lock() defer m.mtx.Unlock() - metric, ok = m.getMetricWithLabels(hash, labels) + metric, ok = m.getMetricWithHashAndLabels(hash, labels) if !ok { lvs := m.extractLabelValues(labels) metric = m.newMetric(lvs...) @@ -325,9 +283,9 @@ func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metr return metric } -// getMetricWithLabelValues gets a metric while handling possible collisions in -// the hash space. Must be called while holding read mutex. -func (m *MetricVec) getMetricWithLabelValues(h uint64, lvs []string) (Metric, bool) { +// getMetricWithHashAndLabelValues gets a metric while handling possible +// collisions in the hash space. Must be called while holding the read mutex. +func (m *metricVec) getMetricWithHashAndLabelValues(h uint64, lvs []string) (Metric, bool) { metrics, ok := m.children[h] if ok { if i := m.findMetricWithLabelValues(metrics, lvs); i < len(metrics) { @@ -337,9 +295,9 @@ func (m *MetricVec) getMetricWithLabelValues(h uint64, lvs []string) (Metric, bo return nil, false } -// getMetricWithLabels gets a metric while handling possible collisions in +// getMetricWithHashAndLabels gets a metric while handling possible collisions in // the hash space. Must be called while holding read mutex. -func (m *MetricVec) getMetricWithLabels(h uint64, labels Labels) (Metric, bool) { +func (m *metricVec) getMetricWithHashAndLabels(h uint64, labels Labels) (Metric, bool) { metrics, ok := m.children[h] if ok { if i := m.findMetricWithLabels(metrics, labels); i < len(metrics) { @@ -351,7 +309,7 @@ func (m *MetricVec) getMetricWithLabels(h uint64, labels Labels) (Metric, bool) // findMetricWithLabelValues returns the index of the matching metric or // len(metrics) if not found. -func (m *MetricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, lvs []string) int { +func (m *metricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, lvs []string) int { for i, metric := range metrics { if m.matchLabelValues(metric.values, lvs) { return i @@ -362,7 +320,7 @@ func (m *MetricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, l // findMetricWithLabels returns the index of the matching metric or len(metrics) // if not found. -func (m *MetricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels Labels) int { +func (m *metricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels Labels) int { for i, metric := range metrics { if m.matchLabels(metric.values, labels) { return i @@ -371,7 +329,7 @@ func (m *MetricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels return len(metrics) } -func (m *MetricVec) matchLabelValues(values []string, lvs []string) bool { +func (m *metricVec) matchLabelValues(values []string, lvs []string) bool { if len(values) != len(lvs) { return false } @@ -383,7 +341,7 @@ func (m *MetricVec) matchLabelValues(values []string, lvs []string) bool { return true } -func (m *MetricVec) matchLabels(values []string, labels Labels) bool { +func (m *metricVec) matchLabels(values []string, labels Labels) bool { if len(labels) != len(values) { return false } @@ -395,7 +353,7 @@ func (m *MetricVec) matchLabels(values []string, labels Labels) bool { return true } -func (m *MetricVec) extractLabelValues(labels Labels) []string { +func (m *metricVec) extractLabelValues(labels Labels) []string { labelValues := make([]string, len(labels)) for i, k := range m.desc.variableLabels { labelValues[i] = labels[k]