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

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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.
356364
"""
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