commit
310ce84375
|
@ -74,12 +74,11 @@ func (c *counter) Add(v float64) {
|
||||||
// CounterVec embeds MetricVec. See there for a full list of methods with
|
// CounterVec embeds MetricVec. See there for a full list of methods with
|
||||||
// detailed documentation.
|
// detailed documentation.
|
||||||
type CounterVec struct {
|
type CounterVec struct {
|
||||||
*MetricVec
|
*metricVec
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCounterVec creates a new CounterVec based on the provided CounterOpts and
|
// NewCounterVec creates a new CounterVec based on the provided CounterOpts and
|
||||||
// partitioned by the given label names. At least one label name must be
|
// partitioned by the given label names.
|
||||||
// provided.
|
|
||||||
func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
|
func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
|
||||||
desc := NewDesc(
|
desc := NewDesc(
|
||||||
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||||
|
@ -88,7 +87,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
|
||||||
opts.ConstLabels,
|
opts.ConstLabels,
|
||||||
)
|
)
|
||||||
return &CounterVec{
|
return &CounterVec{
|
||||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
metricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||||
result := &counter{value: value{
|
result := &counter{value: value{
|
||||||
desc: desc,
|
desc: desc,
|
||||||
valType: CounterValue,
|
valType: CounterValue,
|
||||||
|
@ -100,22 +99,51 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWithLabelValues replaces the method of the same name in
|
// GetMetricWithLabelValues returns the Counter for the given slice of label
|
||||||
// MetricVec. The difference is that this method returns a Counter and not a
|
// values (same order as the VariableLabels in Desc). If that combination of
|
||||||
// Metric so that no type conversion is required.
|
// 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) {
|
func (m *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
|
metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Counter), err
|
return metric.(Counter), err
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWith replaces the method of the same name in MetricVec. The
|
// GetMetricWith returns the Counter for the given Labels map (the label names
|
||||||
// difference is that this method returns a Counter and not a Metric so that no
|
// must match those of the VariableLabels in Desc). If that label map is
|
||||||
// type conversion is required.
|
// 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) {
|
func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWith(labels)
|
metric, err := m.metricVec.getMetricWith(labels)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Counter), err
|
return metric.(Counter), err
|
||||||
}
|
}
|
||||||
|
@ -127,14 +155,14 @@ func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
|
||||||
// error, WithLabelValues allows shortcuts like
|
// error, WithLabelValues allows shortcuts like
|
||||||
// myVec.WithLabelValues("404", "GET").Add(42)
|
// myVec.WithLabelValues("404", "GET").Add(42)
|
||||||
func (m *CounterVec) WithLabelValues(lvs ...string) Counter {
|
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
|
// With works as GetMetricWith, but panics where GetMetricWithLabels would have
|
||||||
// returned an error. By not returning an error, With allows shortcuts like
|
// returned an error. By not returning an error, With allows shortcuts like
|
||||||
// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
|
// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
|
||||||
func (m *CounterVec) With(labels Labels) Counter {
|
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
|
// CounterFunc is a Counter whose value is determined at collect time by calling a
|
||||||
|
|
|
@ -63,12 +63,11 @@ func NewGauge(opts GaugeOpts) Gauge {
|
||||||
// (e.g. number of operations queued, partitioned by user and operation
|
// (e.g. number of operations queued, partitioned by user and operation
|
||||||
// type). Create instances with NewGaugeVec.
|
// type). Create instances with NewGaugeVec.
|
||||||
type GaugeVec struct {
|
type GaugeVec struct {
|
||||||
*MetricVec
|
*metricVec
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
|
// NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
|
||||||
// partitioned by the given label names. At least one label name must be
|
// partitioned by the given label names.
|
||||||
// provided.
|
|
||||||
func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
|
func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
|
||||||
desc := NewDesc(
|
desc := NewDesc(
|
||||||
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||||
|
@ -77,28 +76,57 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
|
||||||
opts.ConstLabels,
|
opts.ConstLabels,
|
||||||
)
|
)
|
||||||
return &GaugeVec{
|
return &GaugeVec{
|
||||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
metricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||||
return newValue(desc, GaugeValue, 0, lvs...)
|
return newValue(desc, GaugeValue, 0, lvs...)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWithLabelValues replaces the method of the same name in
|
// GetMetricWithLabelValues returns the Gauge for the given slice of label
|
||||||
// MetricVec. The difference is that this method returns a Gauge and not a
|
// values (same order as the VariableLabels in Desc). If that combination of
|
||||||
// Metric so that no type conversion is required.
|
// 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) {
|
func (m *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
|
metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Gauge), err
|
return metric.(Gauge), err
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWith replaces the method of the same name in MetricVec. The
|
// GetMetricWith returns the Gauge for the given Labels map (the label names
|
||||||
// difference is that this method returns a Gauge and not a Metric so that no
|
// must match those of the VariableLabels in Desc). If that label map is
|
||||||
// type conversion is required.
|
// 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) {
|
func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWith(labels)
|
metric, err := m.metricVec.getMetricWith(labels)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Gauge), err
|
return metric.(Gauge), err
|
||||||
}
|
}
|
||||||
|
@ -110,14 +138,14 @@ func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
|
||||||
// error, WithLabelValues allows shortcuts like
|
// error, WithLabelValues allows shortcuts like
|
||||||
// myVec.WithLabelValues("404", "GET").Add(42)
|
// myVec.WithLabelValues("404", "GET").Add(42)
|
||||||
func (m *GaugeVec) WithLabelValues(lvs ...string) Gauge {
|
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
|
// With works as GetMetricWith, but panics where GetMetricWithLabels would have
|
||||||
// returned an error. By not returning an error, With allows shortcuts like
|
// returned an error. By not returning an error, With allows shortcuts like
|
||||||
// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
|
// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
|
||||||
func (m *GaugeVec) With(labels Labels) Gauge {
|
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
|
// GaugeFunc is a Gauge whose value is determined at collect time by calling a
|
||||||
|
|
|
@ -287,12 +287,11 @@ func (h *histogram) Write(out *dto.Metric) error {
|
||||||
// (e.g. HTTP request latencies, partitioned by status code and method). Create
|
// (e.g. HTTP request latencies, partitioned by status code and method). Create
|
||||||
// instances with NewHistogramVec.
|
// instances with NewHistogramVec.
|
||||||
type HistogramVec struct {
|
type HistogramVec struct {
|
||||||
*MetricVec
|
*metricVec
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and
|
// NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and
|
||||||
// partitioned by the given label names. At least one label name must be
|
// partitioned by the given label names.
|
||||||
// provided.
|
|
||||||
func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
|
func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
|
||||||
desc := NewDesc(
|
desc := NewDesc(
|
||||||
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||||
|
@ -301,28 +300,58 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
|
||||||
opts.ConstLabels,
|
opts.ConstLabels,
|
||||||
)
|
)
|
||||||
return &HistogramVec{
|
return &HistogramVec{
|
||||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
metricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||||
return newHistogram(desc, opts, lvs...)
|
return newHistogram(desc, opts, lvs...)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWithLabelValues replaces the method of the same name in
|
// GetMetricWithLabelValues returns the Histogram for the given slice of label
|
||||||
// MetricVec. The difference is that this method returns an Observer and not a
|
// values (same order as the VariableLabels in Desc). If that combination of
|
||||||
// Metric so that no type conversion to an Observer is required.
|
// 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) {
|
func (m *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
|
metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Observer), err
|
return metric.(Observer), err
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWith replaces the method of the same name in MetricVec. The
|
// GetMetricWith returns the Histogram for the given Labels map (the label names
|
||||||
// difference is that this method returns an Observer and not a Metric so that no
|
// must match those of the VariableLabels in Desc). If that label map is
|
||||||
// type conversion to an Observer is required.
|
// 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) {
|
func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWith(labels)
|
metric, err := m.metricVec.getMetricWith(labels)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Observer), err
|
return metric.(Observer), err
|
||||||
}
|
}
|
||||||
|
@ -334,14 +363,14 @@ func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
|
||||||
// error, WithLabelValues allows shortcuts like
|
// error, WithLabelValues allows shortcuts like
|
||||||
// myVec.WithLabelValues("404", "GET").Observe(42.21)
|
// myVec.WithLabelValues("404", "GET").Observe(42.21)
|
||||||
func (m *HistogramVec) WithLabelValues(lvs ...string) Observer {
|
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
|
// With works as GetMetricWith, but panics where GetMetricWithLabels would have
|
||||||
// returned an error. By not returning an error, With allows shortcuts like
|
// returned an error. By not returning an error, With allows shortcuts like
|
||||||
// myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
|
// myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
|
||||||
func (m *HistogramVec) With(labels Labels) Observer {
|
func (m *HistogramVec) With(labels Labels) Observer {
|
||||||
return m.MetricVec.With(labels).(Observer)
|
return m.metricVec.with(labels).(Observer)
|
||||||
}
|
}
|
||||||
|
|
||||||
type constHistogram struct {
|
type constHistogram struct {
|
||||||
|
|
|
@ -399,12 +399,11 @@ func (s quantSort) Less(i, j int) bool {
|
||||||
// (e.g. HTTP request latencies, partitioned by status code and method). Create
|
// (e.g. HTTP request latencies, partitioned by status code and method). Create
|
||||||
// instances with NewSummaryVec.
|
// instances with NewSummaryVec.
|
||||||
type SummaryVec struct {
|
type SummaryVec struct {
|
||||||
*MetricVec
|
*metricVec
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and
|
// NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and
|
||||||
// partitioned by the given label names. At least one label name must be
|
// partitioned by the given label names.
|
||||||
// provided.
|
|
||||||
func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
|
func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
|
||||||
desc := NewDesc(
|
desc := NewDesc(
|
||||||
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||||
|
@ -413,28 +412,58 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
|
||||||
opts.ConstLabels,
|
opts.ConstLabels,
|
||||||
)
|
)
|
||||||
return &SummaryVec{
|
return &SummaryVec{
|
||||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
metricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||||
return newSummary(desc, opts, lvs...)
|
return newSummary(desc, opts, lvs...)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWithLabelValues replaces the method of the same name in MetricVec.
|
// GetMetricWithLabelValues returns the Summary for the given slice of label
|
||||||
// The difference is that this method returns an Observer and not a Metric so
|
// values (same order as the VariableLabels in Desc). If that combination of
|
||||||
// that no type conversion to an Observer is required.
|
// 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) {
|
func (m *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
|
metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Observer), err
|
return metric.(Observer), err
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWith replaces the method of the same name in MetricVec. The
|
// GetMetricWith returns the Summary for the given Labels map (the label names
|
||||||
// difference is that this method returns an Observer and not a Metric so that
|
// must match those of the VariableLabels in Desc). If that label map is
|
||||||
// no type conversion to an Observer is required.
|
// 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) {
|
func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWith(labels)
|
metric, err := m.metricVec.getMetricWith(labels)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Observer), err
|
return metric.(Observer), err
|
||||||
}
|
}
|
||||||
|
@ -446,14 +475,14 @@ func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
|
||||||
// error, WithLabelValues allows shortcuts like
|
// error, WithLabelValues allows shortcuts like
|
||||||
// myVec.WithLabelValues("404", "GET").Observe(42.21)
|
// myVec.WithLabelValues("404", "GET").Observe(42.21)
|
||||||
func (m *SummaryVec) WithLabelValues(lvs ...string) Observer {
|
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
|
// With works as GetMetricWith, but panics where GetMetricWithLabels would have
|
||||||
// returned an error. By not returning an error, With allows shortcuts like
|
// returned an error. By not returning an error, With allows shortcuts like
|
||||||
// myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
|
// myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
|
||||||
func (m *SummaryVec) With(labels Labels) Observer {
|
func (m *SummaryVec) With(labels Labels) Observer {
|
||||||
return m.MetricVec.With(labels).(Observer)
|
return m.metricVec.with(labels).(Observer)
|
||||||
}
|
}
|
||||||
|
|
||||||
type constSummary struct {
|
type constSummary struct {
|
||||||
|
|
|
@ -60,13 +60,14 @@ func NewUntyped(opts UntypedOpts) Untyped {
|
||||||
// share the same Desc, but have different values for their variable
|
// share the same Desc, but have different values for their variable
|
||||||
// labels. This is used if you want to count the same thing partitioned by
|
// labels. This is used if you want to count the same thing partitioned by
|
||||||
// various dimensions. Create instances with NewUntypedVec.
|
// various dimensions. Create instances with NewUntypedVec.
|
||||||
|
//
|
||||||
|
// Deprecated: UntypedVec is deprecated for the same reasons as Untyped.
|
||||||
type UntypedVec struct {
|
type UntypedVec struct {
|
||||||
*MetricVec
|
*metricVec
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and
|
// NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and
|
||||||
// partitioned by the given label names. At least one label name must be
|
// partitioned by the given label names.
|
||||||
// provided.
|
|
||||||
func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
|
func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
|
||||||
desc := NewDesc(
|
desc := NewDesc(
|
||||||
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||||
|
@ -75,28 +76,58 @@ func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
|
||||||
opts.ConstLabels,
|
opts.ConstLabels,
|
||||||
)
|
)
|
||||||
return &UntypedVec{
|
return &UntypedVec{
|
||||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
metricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||||
return newValue(desc, UntypedValue, 0, lvs...)
|
return newValue(desc, UntypedValue, 0, lvs...)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWithLabelValues replaces the method of the same name in
|
// GetMetricWithLabelValues returns the Untyped for the given slice of label
|
||||||
// MetricVec. The difference is that this method returns an Untyped and not a
|
// values (same order as the VariableLabels in Desc). If that combination of
|
||||||
// Metric so that no type conversion is required.
|
// 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) {
|
func (m *UntypedVec) GetMetricWithLabelValues(lvs ...string) (Untyped, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
|
metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Untyped), err
|
return metric.(Untyped), err
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWith replaces the method of the same name in MetricVec. The
|
// GetMetricWith returns the Untyped for the given Labels map (the label names
|
||||||
// difference is that this method returns an Untyped and not a Metric so that no
|
// must match those of the VariableLabels in Desc). If that label map is
|
||||||
// type conversion is required.
|
// 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) {
|
func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error) {
|
||||||
metric, err := m.MetricVec.GetMetricWith(labels)
|
metric, err := m.metricVec.getMetricWith(labels)
|
||||||
if metric != nil {
|
if metric != nil {
|
||||||
return metric.(Untyped), err
|
return metric.(Untyped), err
|
||||||
}
|
}
|
||||||
|
@ -108,14 +139,14 @@ func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error) {
|
||||||
// error, WithLabelValues allows shortcuts like
|
// error, WithLabelValues allows shortcuts like
|
||||||
// myVec.WithLabelValues("404", "GET").Add(42)
|
// myVec.WithLabelValues("404", "GET").Add(42)
|
||||||
func (m *UntypedVec) WithLabelValues(lvs ...string) Untyped {
|
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
|
// With works as GetMetricWith, but panics where GetMetricWithLabels would have
|
||||||
// returned an error. By not returning an error, With allows shortcuts like
|
// returned an error. By not returning an error, With allows shortcuts like
|
||||||
// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
|
// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
|
||||||
func (m *UntypedVec) With(labels Labels) Untyped {
|
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
|
// UntypedFunc is an Untyped whose value is determined at collect time by
|
||||||
|
|
|
@ -20,12 +20,12 @@ import (
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MetricVec is a Collector to bundle metrics of the same name that
|
// metricVec is a Collector to bundle metrics of the same name that differ in
|
||||||
// differ in their label values. MetricVec is usually not used directly but as a
|
// their label values. metricVec is not used directly (and therefore
|
||||||
// building block for implementations of vectors of a given metric
|
// unexported). It is used as a building block for implementations of vectors of
|
||||||
// type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already
|
// a given metric type, like GaugeVec, CounterVec, SummaryVec, HistogramVec, and
|
||||||
// provided in this package.
|
// UntypedVec.
|
||||||
type MetricVec struct {
|
type metricVec struct {
|
||||||
mtx sync.RWMutex // Protects the children.
|
mtx sync.RWMutex // Protects the children.
|
||||||
children map[uint64][]metricWithLabelValues
|
children map[uint64][]metricWithLabelValues
|
||||||
desc *Desc
|
desc *Desc
|
||||||
|
@ -37,8 +37,8 @@ type MetricVec struct {
|
||||||
|
|
||||||
// newMetricVec returns an initialized MetricVec. The concrete value is
|
// newMetricVec returns an initialized MetricVec. The concrete value is
|
||||||
// returned for embedding into another struct.
|
// returned for embedding into another struct.
|
||||||
func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec {
|
func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *metricVec {
|
||||||
return &MetricVec{
|
return &metricVec{
|
||||||
children: map[uint64][]metricWithLabelValues{},
|
children: map[uint64][]metricWithLabelValues{},
|
||||||
desc: desc,
|
desc: desc,
|
||||||
newMetric: newMetric,
|
newMetric: newMetric,
|
||||||
|
@ -56,12 +56,12 @@ type metricWithLabelValues struct {
|
||||||
|
|
||||||
// Describe implements Collector. The length of the returned slice
|
// Describe implements Collector. The length of the returned slice
|
||||||
// is always one.
|
// is always one.
|
||||||
func (m *MetricVec) Describe(ch chan<- *Desc) {
|
func (m *metricVec) Describe(ch chan<- *Desc) {
|
||||||
ch <- m.desc
|
ch <- m.desc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect implements Collector.
|
// Collect implements Collector.
|
||||||
func (m *MetricVec) Collect(ch chan<- Metric) {
|
func (m *metricVec) Collect(ch chan<- Metric) {
|
||||||
m.mtx.RLock()
|
m.mtx.RLock()
|
||||||
defer m.mtx.RUnlock()
|
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
|
func (m *metricVec) getMetricWithLabelValues(lvs ...string) (Metric, error) {
|
||||||
// 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) {
|
|
||||||
h, err := m.hashLabelValues(lvs)
|
h, err := m.hashLabelValues(lvs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -105,19 +81,7 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
|
||||||
return m.getOrCreateMetricWithLabelValues(h, lvs), nil
|
return m.getOrCreateMetricWithLabelValues(h, lvs), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricWith returns the Metric for the given Labels map (the label names
|
func (m *metricVec) getMetricWith(labels Labels) (Metric, error) {
|
||||||
// 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) {
|
|
||||||
h, err := m.hashLabels(labels)
|
h, err := m.hashLabels(labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -126,22 +90,16 @@ func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
|
||||||
return m.getOrCreateMetricWithLabels(h, labels), nil
|
return m.getOrCreateMetricWithLabels(h, labels), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithLabelValues works as GetMetricWithLabelValues, but panics if an error
|
func (m *metricVec) withLabelValues(lvs ...string) Metric {
|
||||||
// occurs. The method allows neat syntax like:
|
metric, err := m.getMetricWithLabelValues(lvs...)
|
||||||
// httpReqs.WithLabelValues("404", "POST").Inc()
|
|
||||||
func (m *MetricVec) WithLabelValues(lvs ...string) Metric {
|
|
||||||
metric, err := m.GetMetricWithLabelValues(lvs...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return metric
|
return metric
|
||||||
}
|
}
|
||||||
|
|
||||||
// With works as GetMetricWith, but panics if an error occurs. The method allows
|
func (m *metricVec) with(labels Labels) Metric {
|
||||||
// neat syntax like:
|
metric, err := m.getMetricWith(labels)
|
||||||
// httpReqs.With(Labels{"status":"404", "method":"POST"}).Inc()
|
|
||||||
func (m *MetricVec) With(labels Labels) Metric {
|
|
||||||
metric, err := m.GetMetricWith(labels)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -153,8 +111,8 @@ func (m *MetricVec) With(labels Labels) Metric {
|
||||||
// returns true if a metric was deleted.
|
// returns true if a metric was deleted.
|
||||||
//
|
//
|
||||||
// It is not an error if the number of label values is not the same as the
|
// 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
|
// 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
|
// never match an actual metric, so the method will always return false in that
|
||||||
// case.
|
// case.
|
||||||
//
|
//
|
||||||
// Note that for more than one label value, this method is prone to mistakes
|
// 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
|
// latter has a much more readable (albeit more verbose) syntax, but it comes
|
||||||
// with a performance overhead (for creating and processing the Labels map).
|
// with a performance overhead (for creating and processing the Labels map).
|
||||||
// See also the CounterVec example.
|
// See also the CounterVec example.
|
||||||
func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
|
func (m *metricVec) DeleteLabelValues(lvs ...string) bool {
|
||||||
m.mtx.Lock()
|
m.mtx.Lock()
|
||||||
defer m.mtx.Unlock()
|
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.
|
// 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
|
// 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
|
// with those of the VariableLabels in Desc. However, such inconsistent Labels
|
||||||
// inconsistent Labels can never match an actual Metric, so the method will
|
// can never match an actual metric, so the method will always return false in
|
||||||
// always return false in that case.
|
// that case.
|
||||||
//
|
//
|
||||||
// This method is used for the same purpose as DeleteLabelValues(...string). See
|
// This method is used for the same purpose as DeleteLabelValues(...string). See
|
||||||
// there for pros and cons of the two methods.
|
// 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()
|
m.mtx.Lock()
|
||||||
defer m.mtx.Unlock()
|
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
|
// deleteByHashWithLabelValues removes the metric from the hash bucket h. If
|
||||||
// there are multiple matches in the bucket, use lvs to select a metric and
|
// there are multiple matches in the bucket, use lvs to select a metric and
|
||||||
// remove only that metric.
|
// 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]
|
metrics, ok := m.children[h]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
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
|
// 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
|
// are multiple matches in the bucket, use lvs to select a metric and remove
|
||||||
// only that metric.
|
// 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]
|
metrics, ok := m.children[h]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
|
@ -240,7 +198,7 @@ func (m *MetricVec) deleteByHashWithLabels(h uint64, labels Labels) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset deletes all metrics in this vector.
|
// Reset deletes all metrics in this vector.
|
||||||
func (m *MetricVec) Reset() {
|
func (m *metricVec) Reset() {
|
||||||
m.mtx.Lock()
|
m.mtx.Lock()
|
||||||
defer m.mtx.Unlock()
|
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) {
|
if len(vals) != len(m.desc.variableLabels) {
|
||||||
return 0, errInconsistentCardinality
|
return 0, errInconsistentCardinality
|
||||||
}
|
}
|
||||||
|
@ -261,7 +219,7 @@ func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
|
||||||
return h, nil
|
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) {
|
if len(labels) != len(m.desc.variableLabels) {
|
||||||
return 0, errInconsistentCardinality
|
return 0, errInconsistentCardinality
|
||||||
}
|
}
|
||||||
|
@ -281,9 +239,9 @@ func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
|
||||||
// or creates it and returns the new one.
|
// or creates it and returns the new one.
|
||||||
//
|
//
|
||||||
// This function holds the mutex.
|
// 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()
|
m.mtx.RLock()
|
||||||
metric, ok := m.getMetricWithLabelValues(hash, lvs)
|
metric, ok := m.getMetricWithHashAndLabelValues(hash, lvs)
|
||||||
m.mtx.RUnlock()
|
m.mtx.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
return metric
|
return metric
|
||||||
|
@ -291,7 +249,7 @@ func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string)
|
||||||
|
|
||||||
m.mtx.Lock()
|
m.mtx.Lock()
|
||||||
defer m.mtx.Unlock()
|
defer m.mtx.Unlock()
|
||||||
metric, ok = m.getMetricWithLabelValues(hash, lvs)
|
metric, ok = m.getMetricWithHashAndLabelValues(hash, lvs)
|
||||||
if !ok {
|
if !ok {
|
||||||
// Copy to avoid allocation in case wo don't go down this code path.
|
// Copy to avoid allocation in case wo don't go down this code path.
|
||||||
copiedLVs := make([]string, len(lvs))
|
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.
|
// or creates it and returns the new one.
|
||||||
//
|
//
|
||||||
// This function holds the mutex.
|
// 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()
|
m.mtx.RLock()
|
||||||
metric, ok := m.getMetricWithLabels(hash, labels)
|
metric, ok := m.getMetricWithHashAndLabels(hash, labels)
|
||||||
m.mtx.RUnlock()
|
m.mtx.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
return metric
|
return metric
|
||||||
|
@ -316,7 +274,7 @@ func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metr
|
||||||
|
|
||||||
m.mtx.Lock()
|
m.mtx.Lock()
|
||||||
defer m.mtx.Unlock()
|
defer m.mtx.Unlock()
|
||||||
metric, ok = m.getMetricWithLabels(hash, labels)
|
metric, ok = m.getMetricWithHashAndLabels(hash, labels)
|
||||||
if !ok {
|
if !ok {
|
||||||
lvs := m.extractLabelValues(labels)
|
lvs := m.extractLabelValues(labels)
|
||||||
metric = m.newMetric(lvs...)
|
metric = m.newMetric(lvs...)
|
||||||
|
@ -325,9 +283,9 @@ func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metr
|
||||||
return metric
|
return metric
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMetricWithLabelValues gets a metric while handling possible collisions in
|
// getMetricWithHashAndLabelValues gets a metric while handling possible
|
||||||
// the hash space. Must be called while holding read mutex.
|
// collisions in the hash space. Must be called while holding the read mutex.
|
||||||
func (m *MetricVec) getMetricWithLabelValues(h uint64, lvs []string) (Metric, bool) {
|
func (m *metricVec) getMetricWithHashAndLabelValues(h uint64, lvs []string) (Metric, bool) {
|
||||||
metrics, ok := m.children[h]
|
metrics, ok := m.children[h]
|
||||||
if ok {
|
if ok {
|
||||||
if i := m.findMetricWithLabelValues(metrics, lvs); i < len(metrics) {
|
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
|
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.
|
// 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]
|
metrics, ok := m.children[h]
|
||||||
if ok {
|
if ok {
|
||||||
if i := m.findMetricWithLabels(metrics, labels); i < len(metrics) {
|
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
|
// findMetricWithLabelValues returns the index of the matching metric or
|
||||||
// len(metrics) if not found.
|
// 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 {
|
for i, metric := range metrics {
|
||||||
if m.matchLabelValues(metric.values, lvs) {
|
if m.matchLabelValues(metric.values, lvs) {
|
||||||
return i
|
return i
|
||||||
|
@ -362,7 +320,7 @@ func (m *MetricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, l
|
||||||
|
|
||||||
// findMetricWithLabels returns the index of the matching metric or len(metrics)
|
// findMetricWithLabels returns the index of the matching metric or len(metrics)
|
||||||
// if not found.
|
// 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 {
|
for i, metric := range metrics {
|
||||||
if m.matchLabels(metric.values, labels) {
|
if m.matchLabels(metric.values, labels) {
|
||||||
return i
|
return i
|
||||||
|
@ -371,7 +329,7 @@ func (m *MetricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels
|
||||||
return len(metrics)
|
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) {
|
if len(values) != len(lvs) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -383,7 +341,7 @@ func (m *MetricVec) matchLabelValues(values []string, lvs []string) bool {
|
||||||
return true
|
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) {
|
if len(labels) != len(values) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -395,7 +353,7 @@ func (m *MetricVec) matchLabels(values []string, labels Labels) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MetricVec) extractLabelValues(labels Labels) []string {
|
func (m *metricVec) extractLabelValues(labels Labels) []string {
|
||||||
labelValues := make([]string, len(labels))
|
labelValues := make([]string, len(labels))
|
||||||
for i, k := range m.desc.variableLabels {
|
for i, k := range m.desc.variableLabels {
|
||||||
labelValues[i] = labels[k]
|
labelValues[i] = labels[k]
|
||||||
|
|
Loading…
Reference in New Issue