Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6fc9e4c

Browse files
authored
Fix SDK observable instruments to emit SDK Measurement (open-telemetry#2501)
1 parent b783d16 commit 6fc9e4c

File tree

3 files changed

+300
-100
lines changed

3 files changed

+300
-100
lines changed

opentelemetry-sdk/src/opentelemetry/sdk/_metrics/instrument.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import logging
1818
from abc import ABC, abstractmethod
19-
from typing import Dict, Generator, Iterable, Union
19+
from typing import Callable, Dict, Generator, Iterable, Union
2020

2121
from opentelemetry._metrics.instrument import CallbackT
2222
from opentelemetry._metrics.instrument import Counter as APICounter
@@ -31,6 +31,7 @@
3131
ObservableUpDownCounter as APIObservableUpDownCounter,
3232
)
3333
from opentelemetry._metrics.instrument import UpDownCounter as APIUpDownCounter
34+
from opentelemetry._metrics.measurement import Measurement as APIMeasurement
3435
from opentelemetry.sdk._metrics.aggregation import (
3536
_Aggregation,
3637
_ExplicitBucketHistogramAggregation,
@@ -86,18 +87,24 @@ def __init__(
8687
self._measurement_consumer = measurement_consumer
8788
super().__init__(name, callback, unit=unit, description=description)
8889

89-
self._callback = callback
90+
self._callback: Callable[[], Iterable[APIMeasurement]]
9091

9192
if isinstance(callback, Generator):
9293

9394
def inner() -> Iterable[Measurement]:
9495
return next(callback)
9596

9697
self._callback = inner
97-
98-
@property
99-
def callback(self) -> CallbackT:
100-
return self._callback
98+
else:
99+
self._callback = callback
100+
101+
def callback(self) -> Iterable[Measurement]:
102+
for api_measurement in self._callback():
103+
yield Measurement(
104+
api_measurement.value,
105+
instrument=self,
106+
attributes=api_measurement.attributes,
107+
)
101108

102109

103110
class Counter(_Synchronous, APICounter):

opentelemetry-sdk/tests/metrics/integration_test/test_cpu_time.py

Lines changed: 148 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
# type: ignore
1515

1616
import io
17-
from typing import Generator, Iterable
17+
from typing import Generator, Iterable, List
1818
from unittest import TestCase
1919

20-
from opentelemetry._metrics.measurement import Measurement
20+
from opentelemetry._metrics.instrument import Instrument
21+
from opentelemetry._metrics.measurement import Measurement as APIMeasurement
2122
from opentelemetry.sdk._metrics import MeterProvider
23+
from opentelemetry.sdk._metrics.measurement import Measurement
2224

2325
# FIXME Test that the instrument methods can be called concurrently safely.
2426

@@ -39,61 +41,137 @@ class TestCpuTimeIntegration(TestCase):
3941
procs_blocked 0
4042
softirq 1644603067 0 166540056 208 309152755 8936439 0 1354908 935642970 13 222975718\n"""
4143

42-
measurements_expected = [
43-
Measurement(6150, {"cpu": "cpu0", "state": "user"}),
44-
Measurement(3177, {"cpu": "cpu0", "state": "nice"}),
45-
Measurement(5946, {"cpu": "cpu0", "state": "system"}),
46-
Measurement(891264, {"cpu": "cpu0", "state": "idle"}),
47-
Measurement(1296, {"cpu": "cpu0", "state": "iowait"}),
48-
Measurement(0, {"cpu": "cpu0", "state": "irq"}),
49-
Measurement(8343, {"cpu": "cpu0", "state": "softirq"}),
50-
Measurement(421, {"cpu": "cpu0", "state": "guest"}),
51-
Measurement(0, {"cpu": "cpu0", "state": "guest_nice"}),
52-
Measurement(5882, {"cpu": "cpu1", "state": "user"}),
53-
Measurement(3491, {"cpu": "cpu1", "state": "nice"}),
54-
Measurement(6404, {"cpu": "cpu1", "state": "system"}),
55-
Measurement(891564, {"cpu": "cpu1", "state": "idle"}),
56-
Measurement(1244, {"cpu": "cpu1", "state": "iowait"}),
57-
Measurement(0, {"cpu": "cpu1", "state": "irq"}),
58-
Measurement(2410, {"cpu": "cpu1", "state": "softirq"}),
59-
Measurement(418, {"cpu": "cpu1", "state": "guest"}),
60-
Measurement(0, {"cpu": "cpu1", "state": "guest_nice"}),
61-
]
44+
@staticmethod
45+
def create_measurements_expected(
46+
instrument: Instrument,
47+
) -> List[Measurement]:
48+
return [
49+
Measurement(
50+
6150.29,
51+
instrument=instrument,
52+
attributes={"cpu": "cpu0", "state": "user"},
53+
),
54+
Measurement(
55+
3177.46,
56+
instrument=instrument,
57+
attributes={"cpu": "cpu0", "state": "nice"},
58+
),
59+
Measurement(
60+
5946.01,
61+
instrument=instrument,
62+
attributes={"cpu": "cpu0", "state": "system"},
63+
),
64+
Measurement(
65+
891264.59,
66+
instrument=instrument,
67+
attributes={"cpu": "cpu0", "state": "idle"},
68+
),
69+
Measurement(
70+
1296.29,
71+
instrument=instrument,
72+
attributes={"cpu": "cpu0", "state": "iowait"},
73+
),
74+
Measurement(
75+
0.0,
76+
instrument=instrument,
77+
attributes={"cpu": "cpu0", "state": "irq"},
78+
),
79+
Measurement(
80+
8343.46,
81+
instrument=instrument,
82+
attributes={"cpu": "cpu0", "state": "softirq"},
83+
),
84+
Measurement(
85+
421.37,
86+
instrument=instrument,
87+
attributes={"cpu": "cpu0", "state": "guest"},
88+
),
89+
Measurement(
90+
0,
91+
instrument=instrument,
92+
attributes={"cpu": "cpu0", "state": "guest_nice"},
93+
),
94+
Measurement(
95+
5882.32,
96+
instrument=instrument,
97+
attributes={"cpu": "cpu1", "state": "user"},
98+
),
99+
Measurement(
100+
3491.85,
101+
instrument=instrument,
102+
attributes={"cpu": "cpu1", "state": "nice"},
103+
),
104+
Measurement(
105+
6404.92,
106+
instrument=instrument,
107+
attributes={"cpu": "cpu1", "state": "system"},
108+
),
109+
Measurement(
110+
891564.11,
111+
instrument=instrument,
112+
attributes={"cpu": "cpu1", "state": "idle"},
113+
),
114+
Measurement(
115+
1244.85,
116+
instrument=instrument,
117+
attributes={"cpu": "cpu1", "state": "iowait"},
118+
),
119+
Measurement(
120+
0,
121+
instrument=instrument,
122+
attributes={"cpu": "cpu1", "state": "irq"},
123+
),
124+
Measurement(
125+
2410.04,
126+
instrument=instrument,
127+
attributes={"cpu": "cpu1", "state": "softirq"},
128+
),
129+
Measurement(
130+
418.62,
131+
instrument=instrument,
132+
attributes={"cpu": "cpu1", "state": "guest"},
133+
),
134+
Measurement(
135+
0,
136+
instrument=instrument,
137+
attributes={"cpu": "cpu1", "state": "guest_nice"},
138+
),
139+
]
62140

63141
def test_cpu_time_callback(self):
64-
def cpu_time_callback() -> Iterable[Measurement]:
142+
def cpu_time_callback() -> Iterable[APIMeasurement]:
65143
procstat = io.StringIO(self.procstat_str)
66144
procstat.readline() # skip the first line
67145
for line in procstat:
68146
if not line.startswith("cpu"):
69147
break
70148
cpu, *states = line.split()
71-
yield Measurement(
72-
int(states[0]) // 100, {"cpu": cpu, "state": "user"}
149+
yield APIMeasurement(
150+
int(states[0]) / 100, {"cpu": cpu, "state": "user"}
73151
)
74-
yield Measurement(
75-
int(states[1]) // 100, {"cpu": cpu, "state": "nice"}
152+
yield APIMeasurement(
153+
int(states[1]) / 100, {"cpu": cpu, "state": "nice"}
76154
)
77-
yield Measurement(
78-
int(states[2]) // 100, {"cpu": cpu, "state": "system"}
155+
yield APIMeasurement(
156+
int(states[2]) / 100, {"cpu": cpu, "state": "system"}
79157
)
80-
yield Measurement(
81-
int(states[3]) // 100, {"cpu": cpu, "state": "idle"}
158+
yield APIMeasurement(
159+
int(states[3]) / 100, {"cpu": cpu, "state": "idle"}
82160
)
83-
yield Measurement(
84-
int(states[4]) // 100, {"cpu": cpu, "state": "iowait"}
161+
yield APIMeasurement(
162+
int(states[4]) / 100, {"cpu": cpu, "state": "iowait"}
85163
)
86-
yield Measurement(
87-
int(states[5]) // 100, {"cpu": cpu, "state": "irq"}
164+
yield APIMeasurement(
165+
int(states[5]) / 100, {"cpu": cpu, "state": "irq"}
88166
)
89-
yield Measurement(
90-
int(states[6]) // 100, {"cpu": cpu, "state": "softirq"}
167+
yield APIMeasurement(
168+
int(states[6]) / 100, {"cpu": cpu, "state": "softirq"}
91169
)
92-
yield Measurement(
93-
int(states[7]) // 100, {"cpu": cpu, "state": "guest"}
170+
yield APIMeasurement(
171+
int(states[7]) / 100, {"cpu": cpu, "state": "guest"}
94172
)
95-
yield Measurement(
96-
int(states[8]) // 100, {"cpu": cpu, "state": "guest_nice"}
173+
yield APIMeasurement(
174+
int(states[8]) / 100, {"cpu": cpu, "state": "guest_nice"}
97175
)
98176

99177
meter = MeterProvider().get_meter("name")
@@ -103,12 +181,14 @@ def cpu_time_callback() -> Iterable[Measurement]:
103181
unit="s",
104182
description="CPU time",
105183
)
106-
measurements = list(observable_counter._callback())
107-
self.assertEqual(measurements, self.measurements_expected)
184+
measurements = list(observable_counter.callback())
185+
self.assertEqual(
186+
measurements, self.create_measurements_expected(observable_counter)
187+
)
108188

109189
def test_cpu_time_generator(self):
110190
def cpu_time_generator() -> Generator[
111-
Iterable[Measurement], None, None
191+
Iterable[APIMeasurement], None, None
112192
]:
113193
while True:
114194
measurements = []
@@ -119,55 +199,55 @@ def cpu_time_generator() -> Generator[
119199
break
120200
cpu, *states = line.split()
121201
measurements.append(
122-
Measurement(
123-
int(states[0]) // 100,
202+
APIMeasurement(
203+
int(states[0]) / 100,
124204
{"cpu": cpu, "state": "user"},
125205
)
126206
)
127207
measurements.append(
128-
Measurement(
129-
int(states[1]) // 100,
208+
APIMeasurement(
209+
int(states[1]) / 100,
130210
{"cpu": cpu, "state": "nice"},
131211
)
132212
)
133213
measurements.append(
134-
Measurement(
135-
int(states[2]) // 100,
214+
APIMeasurement(
215+
int(states[2]) / 100,
136216
{"cpu": cpu, "state": "system"},
137217
)
138218
)
139219
measurements.append(
140-
Measurement(
141-
int(states[3]) // 100,
220+
APIMeasurement(
221+
int(states[3]) / 100,
142222
{"cpu": cpu, "state": "idle"},
143223
)
144224
)
145225
measurements.append(
146-
Measurement(
147-
int(states[4]) // 100,
226+
APIMeasurement(
227+
int(states[4]) / 100,
148228
{"cpu": cpu, "state": "iowait"},
149229
)
150230
)
151231
measurements.append(
152-
Measurement(
153-
int(states[5]) // 100, {"cpu": cpu, "state": "irq"}
232+
APIMeasurement(
233+
int(states[5]) / 100, {"cpu": cpu, "state": "irq"}
154234
)
155235
)
156236
measurements.append(
157-
Measurement(
158-
int(states[6]) // 100,
237+
APIMeasurement(
238+
int(states[6]) / 100,
159239
{"cpu": cpu, "state": "softirq"},
160240
)
161241
)
162242
measurements.append(
163-
Measurement(
164-
int(states[7]) // 100,
243+
APIMeasurement(
244+
int(states[7]) / 100,
165245
{"cpu": cpu, "state": "guest"},
166246
)
167247
)
168248
measurements.append(
169-
Measurement(
170-
int(states[8]) // 100,
249+
APIMeasurement(
250+
int(states[8]) / 100,
171251
{"cpu": cpu, "state": "guest_nice"},
172252
)
173253
)
@@ -180,5 +260,9 @@ def cpu_time_generator() -> Generator[
180260
unit="s",
181261
description="CPU time",
182262
)
183-
measurements = list(observable_counter._callback())
184-
self.assertEqual(measurements, self.measurements_expected)
263+
measurements = list(observable_counter.callback())
264+
self.assertEqual(
265+
measurements, self.create_measurements_expected(observable_counter)
266+
)
267+
268+
maxDiff = None

0 commit comments

Comments
 (0)