Skip to content

Commit e6ea98b

Browse files
authored
Merge pull request #803 from prometheus/beorn7/vec
Export MetricVec (again)
2 parents 6007b2b + 85aa957 commit e6ea98b

File tree

8 files changed

+306
-68
lines changed

8 files changed

+306
-68
lines changed

prometheus/counter.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func (c *counter) updateExemplar(v float64, l Labels) {
163163
// (e.g. number of HTTP requests, partitioned by response code and
164164
// method). Create instances with NewCounterVec.
165165
type CounterVec struct {
166-
*metricVec
166+
*MetricVec
167167
}
168168

169169
// NewCounterVec creates a new CounterVec based on the provided CounterOpts and
@@ -176,19 +176,19 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
176176
opts.ConstLabels,
177177
)
178178
return &CounterVec{
179-
metricVec: newMetricVec(desc, func(lvs ...string) Metric {
179+
MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
180180
if len(lvs) != len(desc.variableLabels) {
181181
panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs))
182182
}
183-
result := &counter{desc: desc, labelPairs: makeLabelPairs(desc, lvs), now: time.Now}
183+
result := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: time.Now}
184184
result.init(result) // Init self-collection.
185185
return result
186186
}),
187187
}
188188
}
189189

190190
// GetMetricWithLabelValues returns the Counter for the given slice of label
191-
// values (same order as the VariableLabels in Desc). If that combination of
191+
// values (same order as the variable labels in Desc). If that combination of
192192
// label values is accessed for the first time, a new Counter is created.
193193
//
194194
// It is possible to call this method without using the returned Counter to only
@@ -202,7 +202,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
202202
// Counter with the same label values is created later.
203203
//
204204
// An error is returned if the number of label values is not the same as the
205-
// number of VariableLabels in Desc (minus any curried labels).
205+
// number of variable labels in Desc (minus any curried labels).
206206
//
207207
// Note that for more than one label value, this method is prone to mistakes
208208
// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
@@ -211,27 +211,27 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
211211
// with a performance overhead (for creating and processing the Labels map).
212212
// See also the GaugeVec example.
213213
func (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {
214-
metric, err := v.metricVec.getMetricWithLabelValues(lvs...)
214+
metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)
215215
if metric != nil {
216216
return metric.(Counter), err
217217
}
218218
return nil, err
219219
}
220220

221221
// GetMetricWith returns the Counter for the given Labels map (the label names
222-
// must match those of the VariableLabels in Desc). If that label map is
222+
// must match those of the variable labels in Desc). If that label map is
223223
// accessed for the first time, a new Counter is created. Implications of
224224
// creating a Counter without using it and keeping the Counter for later use are
225225
// the same as for GetMetricWithLabelValues.
226226
//
227227
// An error is returned if the number and names of the Labels are inconsistent
228-
// with those of the VariableLabels in Desc (minus any curried labels).
228+
// with those of the variable labels in Desc (minus any curried labels).
229229
//
230230
// This method is used for the same purpose as
231231
// GetMetricWithLabelValues(...string). See there for pros and cons of the two
232232
// methods.
233233
func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
234-
metric, err := v.metricVec.getMetricWith(labels)
234+
metric, err := v.MetricVec.GetMetricWith(labels)
235235
if metric != nil {
236236
return metric.(Counter), err
237237
}
@@ -275,7 +275,7 @@ func (v *CounterVec) With(labels Labels) Counter {
275275
// registered with a given registry (usually the uncurried version). The Reset
276276
// method deletes all metrics, even if called on a curried vector.
277277
func (v *CounterVec) CurryWith(labels Labels) (*CounterVec, error) {
278-
vec, err := v.curryWith(labels)
278+
vec, err := v.MetricVec.CurryWith(labels)
279279
if vec != nil {
280280
return &CounterVec{vec}, err
281281
}

prometheus/desc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ type Desc struct {
5151
// constLabelPairs contains precalculated DTO label pairs based on
5252
// the constant labels.
5353
constLabelPairs []*dto.LabelPair
54-
// VariableLabels contains names of labels for which the metric
54+
// variableLabels contains names of labels for which the metric
5555
// maintains variable values.
5656
variableLabels []string
5757
// id is a hash of the values of the ConstLabels and fqName. This

prometheus/example_metricvec_test.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Copyright 2020 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package prometheus_test
15+
16+
import (
17+
//lint:ignore SA1019 Need to keep deprecated package for compatibility.
18+
"fmt"
19+
20+
"github.com/golang/protobuf/proto"
21+
22+
dto "github.com/prometheus/client_model/go"
23+
24+
"github.com/prometheus/client_golang/prometheus"
25+
)
26+
27+
// Info implements an info pseudo-metric, which is modeled as a Gauge that
28+
// always has a value of 1. In practice, you would just use a Gauge directly,
29+
// but for this example, we pretend it would be useful to have a “native”
30+
// implementation.
31+
type Info struct {
32+
desc *prometheus.Desc
33+
labelPairs []*dto.LabelPair
34+
}
35+
36+
func (i Info) Desc() *prometheus.Desc {
37+
return i.desc
38+
}
39+
40+
func (i Info) Write(out *dto.Metric) error {
41+
out.Label = i.labelPairs
42+
out.Gauge = &dto.Gauge{Value: proto.Float64(1)}
43+
return nil
44+
}
45+
46+
// InfoVec is the vector version for Info. As an info metric never changes, we
47+
// wouldn't really need to wrap GetMetricWithLabelValues and GetMetricWith
48+
// because Info has no additional methods compared to the vanilla Metric that
49+
// the unwrapped MetricVec methods return. However, to demonstrate all there is
50+
// to do to fully implement a vector for a custom Metric implementation, we do
51+
// it in this example anyway.
52+
type InfoVec struct {
53+
*prometheus.MetricVec
54+
}
55+
56+
func NewInfoVec(name, help string, labelNames []string) *InfoVec {
57+
desc := prometheus.NewDesc(name, help, labelNames, nil)
58+
return &InfoVec{
59+
MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric {
60+
if len(lvs) != len(labelNames) {
61+
panic("inconsistent label cardinality")
62+
}
63+
return Info{desc: desc, labelPairs: prometheus.MakeLabelPairs(desc, lvs)}
64+
}),
65+
}
66+
}
67+
68+
func (v *InfoVec) GetMetricWithLabelValues(lvs ...string) (Info, error) {
69+
metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)
70+
return metric.(Info), err
71+
}
72+
73+
func (v *InfoVec) GetMetricWith(labels prometheus.Labels) (Info, error) {
74+
metric, err := v.MetricVec.GetMetricWith(labels)
75+
return metric.(Info), err
76+
}
77+
78+
func (v *InfoVec) WithLabelValues(lvs ...string) Info {
79+
i, err := v.GetMetricWithLabelValues(lvs...)
80+
if err != nil {
81+
panic(err)
82+
}
83+
return i
84+
}
85+
86+
func (v *InfoVec) With(labels prometheus.Labels) Info {
87+
i, err := v.GetMetricWith(labels)
88+
if err != nil {
89+
panic(err)
90+
}
91+
return i
92+
}
93+
94+
func (v *InfoVec) CurryWith(labels prometheus.Labels) (*InfoVec, error) {
95+
vec, err := v.MetricVec.CurryWith(labels)
96+
if vec != nil {
97+
return &InfoVec{vec}, err
98+
}
99+
return nil, err
100+
}
101+
102+
func (v *InfoVec) MustCurryWith(labels prometheus.Labels) *InfoVec {
103+
vec, err := v.CurryWith(labels)
104+
if err != nil {
105+
panic(err)
106+
}
107+
return vec
108+
}
109+
110+
func ExampleMetricVec() {
111+
112+
infoVec := NewInfoVec(
113+
"library_version_info",
114+
"Versions of the libraries used in this binary.",
115+
[]string{"library", "version"},
116+
)
117+
118+
infoVec.WithLabelValues("prometheus/client_golang", "1.7.1")
119+
infoVec.WithLabelValues("k8s.io/client-go", "0.18.8")
120+
121+
// Just for demonstration, let's check the state of the InfoVec by
122+
// registering it with a custom registry and then let it collect the
123+
// metrics.
124+
reg := prometheus.NewRegistry()
125+
reg.MustRegister(infoVec)
126+
127+
metricFamilies, err := reg.Gather()
128+
if err != nil || len(metricFamilies) != 1 {
129+
panic("unexpected behavior of custom test registry")
130+
}
131+
fmt.Println(proto.MarshalTextString(metricFamilies[0]))
132+
133+
// Output:
134+
// name: "library_version_info"
135+
// help: "Versions of the libraries used in this binary."
136+
// type: GAUGE
137+
// metric: <
138+
// label: <
139+
// name: "library"
140+
// value: "k8s.io/client-go"
141+
// >
142+
// label: <
143+
// name: "version"
144+
// value: "0.18.8"
145+
// >
146+
// gauge: <
147+
// value: 1
148+
// >
149+
// >
150+
// metric: <
151+
// label: <
152+
// name: "library"
153+
// value: "prometheus/client_golang"
154+
// >
155+
// label: <
156+
// name: "version"
157+
// value: "1.7.1"
158+
// >
159+
// gauge: <
160+
// value: 1
161+
// >
162+
// >
163+
}

prometheus/gauge.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func (g *gauge) Write(out *dto.Metric) error {
132132
// (e.g. number of operations queued, partitioned by user and operation
133133
// type). Create instances with NewGaugeVec.
134134
type GaugeVec struct {
135-
*metricVec
135+
*MetricVec
136136
}
137137

138138
// NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
@@ -145,19 +145,19 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
145145
opts.ConstLabels,
146146
)
147147
return &GaugeVec{
148-
metricVec: newMetricVec(desc, func(lvs ...string) Metric {
148+
MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
149149
if len(lvs) != len(desc.variableLabels) {
150150
panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs))
151151
}
152-
result := &gauge{desc: desc, labelPairs: makeLabelPairs(desc, lvs)}
152+
result := &gauge{desc: desc, labelPairs: MakeLabelPairs(desc, lvs)}
153153
result.init(result) // Init self-collection.
154154
return result
155155
}),
156156
}
157157
}
158158

159159
// GetMetricWithLabelValues returns the Gauge for the given slice of label
160-
// values (same order as the VariableLabels in Desc). If that combination of
160+
// values (same order as the variable labels in Desc). If that combination of
161161
// label values is accessed for the first time, a new Gauge is created.
162162
//
163163
// It is possible to call this method without using the returned Gauge to only
@@ -172,35 +172,35 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
172172
// example.
173173
//
174174
// An error is returned if the number of label values is not the same as the
175-
// number of VariableLabels in Desc (minus any curried labels).
175+
// number of variable labels in Desc (minus any curried labels).
176176
//
177177
// Note that for more than one label value, this method is prone to mistakes
178178
// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
179179
// an alternative to avoid that type of mistake. For higher label numbers, the
180180
// latter has a much more readable (albeit more verbose) syntax, but it comes
181181
// with a performance overhead (for creating and processing the Labels map).
182182
func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {
183-
metric, err := v.metricVec.getMetricWithLabelValues(lvs...)
183+
metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)
184184
if metric != nil {
185185
return metric.(Gauge), err
186186
}
187187
return nil, err
188188
}
189189

190190
// GetMetricWith returns the Gauge for the given Labels map (the label names
191-
// must match those of the VariableLabels in Desc). If that label map is
191+
// must match those of the variable labels in Desc). If that label map is
192192
// accessed for the first time, a new Gauge is created. Implications of
193193
// creating a Gauge without using it and keeping the Gauge for later use are
194194
// the same as for GetMetricWithLabelValues.
195195
//
196196
// An error is returned if the number and names of the Labels are inconsistent
197-
// with those of the VariableLabels in Desc (minus any curried labels).
197+
// with those of the variable labels in Desc (minus any curried labels).
198198
//
199199
// This method is used for the same purpose as
200200
// GetMetricWithLabelValues(...string). See there for pros and cons of the two
201201
// methods.
202202
func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
203-
metric, err := v.metricVec.getMetricWith(labels)
203+
metric, err := v.MetricVec.GetMetricWith(labels)
204204
if metric != nil {
205205
return metric.(Gauge), err
206206
}
@@ -244,7 +244,7 @@ func (v *GaugeVec) With(labels Labels) Gauge {
244244
// registered with a given registry (usually the uncurried version). The Reset
245245
// method deletes all metrics, even if called on a curried vector.
246246
func (v *GaugeVec) CurryWith(labels Labels) (*GaugeVec, error) {
247-
vec, err := v.curryWith(labels)
247+
vec, err := v.MetricVec.CurryWith(labels)
248248
if vec != nil {
249249
return &GaugeVec{vec}, err
250250
}

0 commit comments

Comments
 (0)