8000 Add observability check to counters (#455) · lweith/client_python@dd59d9a · GitHub
[go: up one dir, main page]

Skip to content

Commit dd59d9a

Browse files
AlexPadronbrian-brazil
authored andcommitted
Add observability check to counters (prometheus#455)
* add observability check to counters * add raise in other classes as well Signed-off-by: AlexPadron <alexp@kensho.com>
1 parent 024423d commit dd59d9a

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

prometheus_client/metrics.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ def _is_observable(self):
5858
# * the child of a labelled metric.
5959
return not self._labelnames or (self._labelnames and self._labelvalues)
6060

61+
def _raise_if_not_observable(self):
62+
# Functions that mutate the state of the metric, for example incrementing
63+
# a counter, will fail if the metric is not observable, because only if a
64+
# metric is observable will the value be initialized.
65+
if not self._is_observable():
66+
raise ValueError('%s metric is missing label values' % str(self._type))
67+
6168
def _is_parent(self):
6269
return self._labelnames and not self._labelvalues
6370

@@ -250,6 +257,7 @@ def count_exceptions(self, exception=Exception):
250257
Increments the counter when an exception of the given
251258
type is raised up out of the code.
252259
"""
260+
self._raise_if_not_observable()
253261
return ExceptionCounter(self, exception)
254262

255263
def _child_samples(self):
@@ -354,13 +362,15 @@ def track_inprogress(self):
354362
Increments the gauge when the code is entered,
355363
and decrements when it is exited.
356 10000 364
"""
365+
self._raise_if_not_observable()
357366
return InprogressTracker(self)
358367

359368
def time(self):
360369
"""Time a block of code or function, and set the duration in seconds.
361370
362371
Can be used as a function decorator or context manager.
363372
"""
373+
self._raise_if_not_observable()
364374
return Timer(self.set)
365375

366376
def set_function(self, f):
@@ -428,6 +438,7 @@ def time(self):
428438
429439
Can be used as a function decorator or context manager.
430440
"""
441+
self._raise_if_not_observable()
431442
return Timer(self.observe)
432443

433444
def _child_samples(self):

tests/test_core.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ def test_block_decorator(self):
7070
self.assertTrue(raised)
7171
self.assertEqual(1, self.registry.get_sample_value('c_total'))
7272

73+
def test_count_exceptions_not_observable(self):
74+
counter = Counter('counter', 'help', labelnames=('label',), registry=self.registry)
75+
76+
try:
77+
counter.count_exceptions()
78+
except ValueError as e:
79+
self.assertIn('missing label values', str(e))
80+
7381

7482
class TestGauge(unittest.TestCase):
7583
def setUp(self):
@@ -150,6 +158,22 @@ def test_time_block_decorator(self):
150158
time.sleep(.001)
151159
self.assertNotEqual(0, self.registry.get_sample_value('g'))
152160

161+
def test_track_in_progress_not_observable(self):
162+
g = Gauge('test', 'help', labelnames=('label',), registry=self.registry)
163+
164+
try:
165+
g.track_inprogress()
166+
except ValueError as e:
167+
self.assertIn('missing label values', str(e))
168+
169+
def test_timer_not_observable(self):
170+
g = Gauge('test', 'help', labelnames=('label',), registry=self.registry)
171+
172+
try:
173+
g.time()
174+
except ValueError as e:
175+
self.assertIn('missing label values', str(e))
176+
153177

154178
class TestSummary(unittest.TestCase):
155179
def setUp(self):
@@ -230,6 +254,14 @@ def test_block_decorator(self):
230254
pass
231255
self.assertEqual(1, self.registry.get_sample_value('s_count'))
232256

257+
def test_timer_not_observable(self):
258+
s = Summary('test', 'help', labelnames=('label',), registry=self.registry)
259+
260+
try:
261+
s.time()
262+
except ValueError as e:
263+
self.assertIn('missing label values', str(e))
264+
233265

234266
class TestHistogram(unittest.TestCase):
235267
def setUp(self):

0 commit comments

Comments
 (0)
0