8000 fix: error if the metrics are not observable (#666) · lvillis/client_python@9a24236 · 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 9a24236

Browse files
authored
fix: error if the metrics are not observable (prometheus#666)
Signed-off-by: Pietro De Nicolao <pd@bendingspoons.com>
1 parent 921fd67 commit 9a24236

File tree

2 files changed

+63
-20
lines changed

2 files changed

+63
-20
lines changed

prometheus_client/metrics.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ def _metric_init(self):
258258

259259
def inc(self, amount=1):
260260
"""Increment counter by the given amount."""
261+
self._raise_if_not_observable()
261262
if amount < 0:
262263
raise ValueError('Counters can only be incremented by non-negative amounts.')
263264
self._value.inc(amount)
@@ -353,14 +354,17 @@ def _metric_init(self):
353354

354355
def inc(self, amount=1):
355356
"""Increment gauge by the given amount."""
357+
self._raise_if_not_observable()
356358
self._value.inc(amount)
357359

358360
def dec(self, amount=1):
359361
"""Decrement gauge by the given amount."""
362+
self._raise_if_not_observable()
360363
self._value.inc(-amount)
361364

362365
def set(self, value):
363366
"""Set gauge to the given value."""
367+
self._raise_if_not_observable()
364368
self._value.set(float(value))
365369

366370
def set_to_current_time(self):
@@ -392,6 +396,8 @@ def set_function(self, f):
392396
multiple threads. All other methods of the Gauge become NOOPs.
393397
"""
394398

399+
self._raise_if_not_observable()
400+
395401
def samples(self):
396402
return (('', {}, float(f())),)
397403

@@ -450,6 +456,7 @@ def observe(self, amount):
450456
https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
451457
for details.
452458
"""
459+
self._raise_if_not_observable()
453460
self._count.inc(1)
454461
self._sum.inc(amount)
455462

@@ -567,6 +574,7 @@ def observe(self, amount):
567574
https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
568575
for details.
569576
"""
577+
self._raise_if_not_observable()
570578
self._sum.inc(amount)
571579
for i, bound in enumerate(self._upper_bounds):
572580
if amount <= bound:

tests/test_core.py

Lines changed: 55 additions & 20 deletions
< 8000 /tr>
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,21 @@
1919
import unittest
2020

2121

22+
def assert_not_observable(fn, *args, **kwargs):
23+
"""
24+
Assert that a function call falls with a ValueError exception containing
25+
'missing label values'
26+
"""
27+
28+
try:
29+
fn(*args, **kwargs)
30+
except ValueError as e:
31+
assert 'missing label values' in str(e)
32+
return
33+
34+
assert False, "Did not raise a 'missing label values' exception"
35+
36+
2237
class TestCounter(unittest.TestCase):
2338
def setUp(self):
2439
self.registry = CollectorRegistry()
@@ -36,7 +51,6 @@ def test_repr(self):
3651

3752
def test_negative_increment_raises(self):
3853
self.assertRaises(ValueError, self.counter.inc, -1)
39-
4054

4155
def test_function_decorator(self):
4256
@self.counter.count_exceptions(ValueError)
@@ -76,18 +90,21 @@ def test_block_decorator(self):
7690

7791
def test_count_exceptions_not_observable(self):
7892 10000
counter = Counter('counter', 'help', labelnames=('label',), registry=self.registry)
93+
assert_not_observable(counter.count_exceptions)
7994

80-
try:
81-
counter.count_exceptions()
82-
except ValueError as e:
83-
self.assertIn('missing label values', str(e))
95+
def test_inc_not_observable(self):
96+
""".inc() must fail if the counter is not observable."""
97+
98+
counter = Counter('counter', 'help', labelnames=('label',), registry=self.registry)
99+
assert_not_observable(counter.inc)
84100

85101

86102
class TestGauge(unittest.TestCase):
87103
def setUp(self):
88104
self.registry = CollectorRegistry()
89105
self.gauge = Gauge('g', 'help', registry=self.registry)
90-
106+
self.gauge_with_label = Gauge('g2', 'help', labelnames=("label1",), registry=self.registry)
107+
91108
def test_repr(self):
92109
self.assertEqual(repr(self.gauge), "prometheus_client.metrics.Gauge(g)")
93110

@@ -100,6 +117,21 @@ def test_gauge(self):
100117
self.gauge.set(9)
101118
self.assertEqual(9, self.registry.get_sample_value('g'))
102119

120+
def test_inc_not_observable(self):
121+
""".inc() must fail if the gauge is not observable."""
122+
123+
assert_not_observable(self.gauge_with_label.inc)
124+
125+
def test_dec_not_observable(self):
126+
""".dec() must fail if the gauge is not observable."""
127+
128+
assert_not_observable(self.gauge_with_label.dec)
129+
130+
def test_set_not_observable(self):
131+
""".set() must fail if the gauge is not observable."""
132+
133+
assert_not_observable(self.gauge_with_label.set, 1)
134+
103135
def test_inprogress_function_decorator(self):
104136
self.assertEqual(0, self.registry.get_sample_value('g'))
105137

@@ -127,6 +159,11 @@ def test_gauge_function(self):
127159
x['a'] = None
128160
self.assertEqual(1, self.registry.get_sample_value('g'))
129161

162+
def test_set_function_not_observable(self):
163+
""".set_function() must fail if the gauge is not observable."""
164+
165+
assert_not_observable(self.gauge_with_label.set_function, lambda: 1)
166+
130167
def test_time_function_decorator(self):
131168
self.assertEqual(0, self.registry.get_sample_value('g'))
132169

@@ -167,25 +204,18 @@ def test_time_block_decorator(self):
167204

168205
def test_track_in_progress_not_observable(self):
169206
g = Gauge('test', 'help', labelnames=('label',), registry=self.registry)
170-
171-
try:
172-
g.track_inprogress()
173-
except ValueError as e:
174-
self.assertIn('missing label values', str(e))
207+
assert_not_observable(g.track_inprogress)
175208

176209
def test_timer_not_observable(self):
177210
g = Gauge('test', 'help', labelnames=('label',), registry=self.registry)
178-
179-
try:
180-
g.time()
181-
except ValueError as e:
182-
self.assertIn('missing label values', str(e))
211+
assert_not_observable(g.time)
183212

184213

185214
class TestSummary(unittest.TestCase):
186215
def setUp(self):
187216
self.registry = CollectorRegistry()
188217
self.summary = Summary('s', 'help', registry=self.registry)
218+
self.summary_with_labels = Summary('s_with_labels', 'help', labelnames=("label1",), registry=self.registry)
189219

190220
def test_repr(self):
191221
self.assertEqual(repr(self.summary), "prometheus_client.metrics.Summary(s)")
@@ -197,6 +227,10 @@ def test_summary(self):
197227
self.assertEqual(1, self.registry.get_sample_value('s_count'))
198228
self.assertEqual(10, self.registry.get_sample_value('s_sum'))
199229

230+
def test_summary_not_observable(self):
231+
""".observe() must fail if the Summary is not observable."""
232+
assert_not_observable(self.summary_with_labels.observe, 1)
233+
200234
def test_function_decorator(self):
201235
self.assertEqual(0, self.registry.get_sample_value('s_count'))
202236

@@ -267,10 +301,7 @@ def test_block_decorator(self):
267301
def test_timer_not_observable(self):
268302
s = Summary('test', 'help', labelnames=('label',), registry=self.registry)
269303

270-
try:
271-
s.time()
272-
except ValueError as e:
273-
self.assertIn('missing label values', str(e))
304+
assert_not_observable(s.time)
274305

275306

276307
class TestHistogram(unittest.TestCase):
@@ -315,6 +346,10 @@ def test_histogram(self):
315346
self.assertEqual(3, self.registry.get_sample_value('h_count'))
316347
self.assertEqual(float("inf"), self.registry.get_sample_value('h_sum'))
317348

349+
def test_histogram_not_observable(self):
350+
""".observe() must fail if the Summary is not observable."""
351+
assert_not_observable(self.labels.observe, 1)
352+
318353
def test_setting_buckets(self):
319354
h = Histogram('h', 'help', registry=None, buckets=[0, 1, 2])
320355
self.assertEqual([0.0, 1.0, 2.0, float("inf")], h._upper_bounds)

0 commit comments

Comments
 (0)
0