Skip to content

Commit 4b6a52d

Browse files
authored
Rename "handle" to "bound metric" (#470)
bound metric is the new name, as dictated in the spec.
1 parent d5f3a7f commit 4b6a52d

File tree

7 files changed

+167
-181
lines changed

7 files changed

+167
-181
lines changed

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,20 +77,20 @@ from opentelemetry.sdk.metrics.export.controller import PushController
7777
metrics.set_preferred_meter_provider_implementation(lambda _: MeterProvider())
7878
meter = metrics.get_meter(__name__)
7979
exporter = ConsoleMetricsExporter()
80-
controller = PushController(meter, exporter, 5)
80+
controller = PushController(meter=meter, exporter=exporter, interval=5)
8181

8282
counter = meter.create_metric(
83-
"available memory",
84-
"available memory",
85-
"bytes",
86-
int,
87-
Counter,
88-
("environment",),
83+
name="available memory",
84+
description="available memory",
85+
unit="bytes",
86+
value_type=int,
87+
metric_type=Counter,
88+
label_keys=("environment",),
8989
)
9090

91-
label_values = ("staging",)
92-
counter_handle = counter.get_handle(label_values)
93-
counter_handle.add(100)
91+
label_set = meter.get_label_set({"environment": "staging"})
92+
bound_counter = counter.bind(label_set)
93+
bound_counter.add(100)
9494
```
9595

9696
See the [API documentation](https://open-telemetry.github.io/opentelemetry-python/) for more detail, and the [examples folder](./examples) for a more sample code.

docs/examples/metrics/record.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,15 @@
6060
# The meter takes a dictionary of key value pairs
6161
label_set = meter.get_label_set({"environment": "staging"})
6262

63-
# Handle usage
64-
# You can record metrics with metric handles. Handles are created by passing in
65-
# a labelset. A handle is essentially metric data that corresponds to a specific
66-
# set of labels. Therefore, getting a handle using the same set of labels will
67-
# yield the same metric handle.
68-
counter_handle = counter.get_handle(label_set)
69-
counter_handle.add(100)
63+
# Bound instrument usage
64+
65+
# You can record metrics with bound metric instruments. Bound metric
66+
# instruments are created by passing in a labelset. A bound metric instrument
67+
# is essentially metric data that corresponds to a specific set of labels.
68+
# Therefore, getting a bound metric instrument using the same set of labels
69+
# will yield the same bound metric instrument.
70+
bound_counter = counter.bind(label_set)
71+
bound_counter.add(100)
7072

7173
# Direct metric usage
7274
# You can record metrics directly using the metric instrument. You pass in a

opentelemetry-api/src/opentelemetry/metrics/__init__.py

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,54 +37,54 @@
3737
ValueT = TypeVar("ValueT", int, float)
3838

3939

40-
class DefaultMetricHandle:
41-
"""The default MetricHandle.
40+
class DefaultBoundInstrument:
41+
"""The default bound metric instrument.
4242
43-
Used when no MetricHandle implementation is available.
43+
Used when no bound instrument implementation is available.
4444
"""
4545

4646
def add(self, value: ValueT) -> None:
47-
"""No-op implementation of `CounterHandle` add.
47+
"""No-op implementation of `BoundCounter` add.
4848
4949
Args:
50-
value: The value to add to the handle.
50+
value: The value to add to the bound metric instrument.
5151
"""
5252

5353
def record(self, value: ValueT) -> None:
54-
"""No-op implementation of `MeasureHandle` record.
54+
"""No-op implementation of `BoundMeasure` record.
5555
5656
Args:
57-
value: The value to record to the handle.
57+
value: The value to record to the bound metric instrument.
5858
"""
5959

6060

61-
class CounterHandle:
61+
class BoundCounter:
6262
def add(self, value: ValueT) -> None:
63-
"""Increases the value of the handle by ``value``.
63+
"""Increases the value of the bound counter by ``value``.
6464
6565
Args:
66-
value: The value to add to the handle.
66+
value: The value to add to the bound counter.
6767
"""
6868

6969

70-
class MeasureHandle:
70+
class BoundMeasure:
7171
def record(self, value: ValueT) -> None:
72-
"""Records the given ``value`` to this handle.
72+
"""Records the given ``value`` to this bound measure.
7373
7474
Args:
75-
value: The value to record to the handle.
75+
value: The value to record to the bound measure.
7676
"""
7777

7878

7979
class LabelSet(abc.ABC):
8080
"""A canonicalized set of labels useful for preaggregation
8181
8282
Re-usable LabelSet objects provide a potential optimization for scenarios
83-
where handles might not be effective. For example, if the LabelSet will be
84-
re-used but only used once per metrics, handles do not offer any
85-
optimization. It may best to pre-compute a canonicalized LabelSet once and
86-
re-use it with the direct calling convention. LabelSets are immutable and
87-
should be opaque in implementation.
83+
where bound metric instruments might not be effective. For example, if the
84+
LabelSet will be re-used but only used once per metrics, bound metric
85+
instruments do not offer any optimization. It may best to pre-compute a
86+
canonicalized LabelSet once and re-use it with the direct calling
87+
convention. LabelSets are immutable and should be opaque in implementation.
8888
"""
8989

9090

@@ -99,66 +99,67 @@ class Metric(abc.ABC):
9999
"""Base class for various types of metrics.
100100
101101
Metric class that inherit from this class are specialized with the type of
102-
handle that the metric holds.
102+
bound metric instrument that the metric holds.
103103
"""
104104

105105
@abc.abstractmethod
106-
def get_handle(self, label_set: LabelSet) -> "object":
107-
"""Gets a handle, used for repeated-use of metrics instruments.
106+
def bind(self, label_set: LabelSet) -> "object":
107+
"""Gets a bound metric instrument.
108108
109-
Handles are useful to reduce the cost of repeatedly recording a metric
110-
with a pre-defined set of label values. All metric kinds (counter,
111-
measure) support declaring a set of required label keys. The
112-
values corresponding to these keys should be specified in every handle.
113-
"Unspecified" label values, in cases where a handle is requested but
114-
a value was not provided are permitted.
109+
Bound metric instruments are useful to reduce the cost of repeatedly
110+
recording a metric with a pre-defined set of label values. All metric
111+
kinds (counter, measure) support declaring a set of required label
112+
keys. The values corresponding to these keys should be specified in
113+
every bound metric instrument. "Unspecified" label values, in cases
114+
where a bound metric instrument is requested but a value was not
115+
provided are permitted.
115116
116117
Args:
117-
label_set: `LabelSet` to associate with the returned handle.
118+
label_set: `LabelSet` to associate with the bound instrument.
118119
"""
119120

120121

121122
class DefaultMetric(Metric):
122123
"""The default Metric used when no Metric implementation is available."""
123124

124-
def get_handle(self, label_set: LabelSet) -> "DefaultMetricHandle":
125-
"""Gets a `DefaultMetricHandle`.
125+
def bind(self, label_set: LabelSet) -> "DefaultBoundInstrument":
126+
"""Gets a `DefaultBoundInstrument`.
126127
127128
Args:
128-
label_set: `LabelSet` to associate with the returned handle.
129+
label_set: `LabelSet` to associate with the bound instrument.
129130
"""
130-
return DefaultMetricHandle()
131+
return DefaultBoundInstrument()
131132

132133
def add(self, value: ValueT, label_set: LabelSet) -> None:
133134
"""No-op implementation of `Counter` add.
134135
135136
Args:
136137
value: The value to add to the counter metric.
137-
label_set: `LabelSet` to associate with the returned handle.
138+
label_set: `LabelSet` to associate with the bound instrument.
138139
"""
139140

140141
def record(self, value: ValueT, label_set: LabelSet) -> None:
141142
"""No-op implementation of `Measure` record.
142143
143144
Args:
144145
value: The value to record to this measure metric.
145-
label_set: `LabelSet` to associate with the returned handle.
146+
label_set: `LabelSet` to associate with the bound instrument.
146147
"""
147148

148149

149150
class Counter(Metric):
150151
"""A counter type metric that expresses the computation of a sum."""
151152

152-
def get_handle(self, label_set: LabelSet) -> "CounterHandle":
153-
"""Gets a `CounterHandle`."""
154-
return CounterHandle()
153+
def bind(self, label_set: LabelSet) -> "BoundCounter":
154+
"""Gets a `BoundCounter`."""
155+
return BoundCounter()
155156

156157
def add(self, value: ValueT, label_set: LabelSet) -> None:
157158
"""Increases the value of the counter by ``value``.
158159
159160
Args:
160161
value: The value to add to the counter metric.
161-
label_set: `LabelSet` to associate with the returned handle.
162+
label_set: `LabelSet` to associate with the returned bound counter.
162163
"""
163164

164165

@@ -168,21 +169,22 @@ class Measure(Metric):
168169
Measure metrics represent raw statistics that are recorded.
169170
"""
170171

171-
def get_handle(self, label_set: LabelSet) -> "MeasureHandle":
172-
"""Gets a `MeasureHandle` with a float value."""
173-
return MeasureHandle()
172+
def bind(self, label_set: LabelSet) -> "BoundMeasure":
173+
"""Gets a `BoundMeasure`."""
174+
return BoundMeasure()
174175

175176
def record(self, value: ValueT, label_set: LabelSet) -> None:
176177
"""Records the ``value`` to the measure.
177178
178179
Args:
179180
value: The value to record to this measure metric.
180-
label_set: `LabelSet` to associate with the returned handle.
181+
label_set: `LabelSet` to associate with the returned bound measure.
181182
"""
182183

183184

184185
class Observer(abc.ABC):
185-
"""An observer type metric instrument used to capture a current set of values.
186+
"""An observer type metric instrument used to capture a current set of
187+
values.
186188
187189
188190
Observer instruments are asynchronous, a callback is invoked with the
@@ -283,16 +285,15 @@ def record_batch(
283285
) -> None:
284286
"""Atomically records a batch of `Metric` and value pairs.
285287
286-
Allows the functionality of acting upon multiple metrics with
287-
a single API call. Implementations should find metric and handles that
288-
match the key-value pairs in the label tuples.
288+
Allows the functionality of acting upon multiple metrics with a single
289+
API call. Implementations should find bound metric instruments that
290+
match the key-value pairs in the labelset.
289291
290-
Args:
291-
label_set: The `LabelSet` associated with all measurements in
292-
the batch. A measurement is a tuple, representing the `Metric`
293-
being recorded and the corresponding value to record.
294-
record_tuples: A sequence of pairs of `Metric` s and the
295-
corresponding value to record for that metric.
292+
Args: label_set: The `LabelSet` associated with all measurements in the
293+
batch. A measurement is a tuple, representing the `Metric` being
294+
recorded and the corresponding value to record. record_tuples: A
295+
sequence of pairs of `Metric` s and the corresponding value to
296+
record for that metric.
296297
"""
297298

298299
@abc.abstractmethod

opentelemetry-api/tests/metrics/test_metrics.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@ class TestMetrics(unittest.TestCase):
2222
def test_default(self):
2323
default = metrics.DefaultMetric()
2424
default_ls = metrics.DefaultLabelSet()
25-
handle = default.get_handle(default_ls)
26-
self.assertIsInstance(handle, metrics.DefaultMetricHandle)
25+
bound_metric_instr = default.bind(default_ls)
26+
self.assertIsInstance(
27+
bound_metric_instr, metrics.DefaultBoundInstrument
28+
)
2729

2830
def test_counter(self):
2931
counter = metrics.Counter()
3032
label_set = metrics.LabelSet()
31-
handle = counter.get_handle(label_set)
32-
self.assertIsInstance(handle, metrics.CounterHandle)
33+
bound_counter = counter.bind(label_set)
34+
self.assertIsInstance(bound_counter, metrics.BoundCounter)
3335

3436
def test_counter_add(self):
3537
counter = metrics.Counter()
@@ -39,21 +41,21 @@ def test_counter_add(self):
3941
def test_measure(self):
4042
measure = metrics.Measure()
4143
label_set = metrics.LabelSet()
42-
handle = measure.get_handle(label_set)
43-
self.assertIsInstance(handle, metrics.MeasureHandle)
44+
bound_measure = measure.bind(label_set)
45+
self.assertIsInstance(bound_measure, metrics.BoundMeasure)
4446

4547
def test_measure_record(self):
4648
measure = metrics.Measure()
4749
label_set = metrics.LabelSet()
4850
measure.record(1, label_set)
4951

50-
def test_default_handle(self):
51-
metrics.DefaultMetricHandle()
52+
def test_default_bound_metric(self):
53+
metrics.DefaultBoundInstrument()
5254

53-
def test_counter_handle(self):
54-
handle = metrics.CounterHandle()
55-
handle.add(1)
55+
def test_bound_counter(self):
56+
bound_counter = metrics.BoundCounter()
57+
bound_counter.add(1)
5658

57-
def test_measure_handle(self):
58-
handle = metrics.MeasureHandle()
59-
handle.record(1)
59+
def test_bound_measure(self):
60+
bound_measure = metrics.BoundMeasure()
61+
bound_measure.record(1)

0 commit comments

Comments
 (0)