Skip to content

Commit

Permalink
Also allow to add deferred labels for 'gauge' and 'summary' metrics
Browse files Browse the repository at this point in the history
For this to work the 'observability' check needs to be deferred as
well, in case a label is added inside the context manager thereby
making the metric observable.
  • Loading branch information
witsch committed Dec 1, 2021
1 parent bd7319c commit 6544542
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
2 changes: 2 additions & 0 deletions prometheus_client/context_managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def __enter__(self):
def __exit__(self, typ, value, traceback):
# Time can go backwards.
duration = max(default_timer() - self._start, 0)
instance = self._callback.__self__
instance._raise_if_not_observable()
self._callback(duration)

def labels(self, *args, **kw):
Expand Down
2 changes: 0 additions & 2 deletions prometheus_client/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,6 @@ def time(self):
Can be used as a function decorator or context manager.
"""
self._raise_if_not_observable()
return Timer(self.set)

def set_function(self, f):
Expand Down Expand Up @@ -475,7 +474,6 @@ def time(self):
Can be used as a function decorator or context manager.
"""
self._raise_if_not_observable()
return Timer(self.observe)

def _child_samples(self):
Expand Down
27 changes: 25 additions & 2 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,25 @@ def test_time_block_decorator(self):
time.sleep(.001)
self.assertNotEqual(0, self.registry.get_sample_value('g'))

def test_time_block_decorator_with_label(self):
value = self.registry.get_sample_value
self.assertEqual(None, value('g2', {'label1': 'foo'}))
with self.gauge_with_label.time() as metric:
metric.labels('foo')
self.assertLess(0, value('g2', {'label1': 'foo'}))

def test_track_in_progress_not_observable(self):
g = Gauge('test', 'help', labelnames=('label',), registry=self.registry)
assert_not_observable(g.track_inprogress)

def test_timer_not_observable(self):
g = Gauge('test', 'help', labelnames=('label',), registry=self.registry)
assert_not_observable(g.time)

def manager():
with g.time():
pass

assert_not_observable(manager)


class TestSummary(unittest.TestCase):
Expand Down Expand Up @@ -318,10 +330,21 @@ def test_block_decorator(self):
pass
self.assertEqual(1, self.registry.get_sample_value('s_count'))

def test_block_decorator_with_label(self):
value = self.registry.get_sample_value
self.assertEqual(None, value('s_with_labels_count', {'label1': 'foo'}))
with self.summary_with_labels.time() as metric:
metric.labels('foo')
self.assertEqual(1, value('s_with_labels_count', {'label1': 'foo'}))

def test_timer_not_observable(self):
s = Summary('test', 'help', labelnames=('label',), registry=self.registry)

assert_not_observable(s.time)
def manager():
with s.time():
pass

assert_not_observable(manager)


class TestHistogram(unittest.TestCase):
Expand Down

0 comments on commit 6544542

Please sign in to comment.