diff --git a/prometheus_client/multiprocess.py b/prometheus_client/multiprocess.py index db55874e..420d5977 100644 --- a/prometheus_client/multiprocess.py +++ b/prometheus_client/multiprocess.py @@ -119,7 +119,7 @@ def _accumulate_metrics(metrics, accumulate): elif metric._multiprocess_mode in ('mostrecent', 'livemostrecent'): current_timestamp = sample_timestamps[labels][name] timestamp = float(timestamp or 0) - if current_timestamp < timestamp: + if (name, labels) not in samples[labels] or current_timestamp < timestamp: samples[labels][(name, labels)] = value sample_timestamps[labels][name] = timestamp else: # all/liveall diff --git a/tests/test_multiprocess.py b/tests/test_multiprocess.py index ee0c7423..b21bc36e 100644 --- a/tests/test_multiprocess.py +++ b/tests/test_multiprocess.py @@ -205,6 +205,16 @@ def test_gauge_livemostrecent(self): mark_process_dead(123, os.environ['PROMETHEUS_MULTIPROC_DIR']) self.assertEqual(2, self.registry.get_sample_value('g')) + def test_gauge_mostrecent_never_set(self): + # A child created but never set() has a stored timestamp of 0. It must + # still be reported as 0, like every other gauge mode, rather than + # dropped from collection because 0 is not strictly greater than the + # default timestamp of 0. + Gauge('g', 'help', registry=None, multiprocess_mode='mostrecent') + values.ValueClass = MultiProcessValue(lambda: 456) + Gauge('g', 'help', registry=None, multiprocess_mode='mostrecent') + self.assertEqual(0, self.registry.get_sample_value('g')) + def test_namespace_subsystem(self): c1 = Counter('c', 'help', registry=None, namespace='ns', subsystem='ss') c1.inc(1)