From 1b7e161fd3bd871095436ff4e5bab4863120991a Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 25 Jan 2022 14:20:30 -0600 Subject: [PATCH] Make shutdown function be called always (#2405) * Make shutdown function be called always Fixes #2404 * Fix warning handling * Log specific metric reader Co-authored-by: Alex Boten --- .../opentelemetry/sdk/_metrics/__init__.py | 14 +++++++---- .../tests/metrics/test_metrics.py | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/__init__.py index 57c44160c8a..705e814d695 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/__init__.py @@ -198,13 +198,17 @@ def shutdown(self): _logger.warning("shutdown can only be called once") return False - result = True + overall_result = True for metric_reader in self._sdk_config.metric_readers: - result = result and metric_reader.shutdown() + metric_reader_result = metric_reader.shutdown() - if not result: - _logger.warning("A MetricReader failed to shutdown") + if not metric_reader_result: + _logger.warning( + "MetricReader {metric_reader} failed to shutdown" + ) + + overall_result = overall_result and metric_reader_result self._shutdown = True @@ -212,7 +216,7 @@ def shutdown(self): unregister(self._atexit_handler) self._atexit_handler = None - return result + return overall_result def get_meter( self, diff --git a/opentelemetry-sdk/tests/metrics/test_metrics.py b/opentelemetry-sdk/tests/metrics/test_metrics.py index bfe1d0df9d9..3510e9691e7 100644 --- a/opentelemetry-sdk/tests/metrics/test_metrics.py +++ b/opentelemetry-sdk/tests/metrics/test_metrics.py @@ -90,6 +90,30 @@ def test_get_meter_duplicate(self): self.assertIs(meter1, meter2) self.assertIsNot(meter1, meter3) + def test_shutdown(self): + + mock_metric_reader_0 = Mock(**{"shutdown.return_value": False}) + mock_metric_reader_1 = Mock(**{"shutdown.return_value": True}) + + meter_provider = MeterProvider( + metric_readers=[mock_metric_reader_0, mock_metric_reader_1] + ) + + self.assertFalse(meter_provider.shutdown()) + mock_metric_reader_0.shutdown.assert_called_once() + mock_metric_reader_1.shutdown.assert_called_once() + + mock_metric_reader_0 = Mock(**{"shutdown.return_value": True}) + mock_metric_reader_1 = Mock(**{"shutdown.return_value": True}) + + meter_provider = MeterProvider( + metric_readers=[mock_metric_reader_0, mock_metric_reader_1] + ) + + self.assertTrue(meter_provider.shutdown()) + mock_metric_reader_0.shutdown.assert_called_once() + mock_metric_reader_1.shutdown.assert_called_once() + def test_shutdown_subsequent_calls(self): """ No subsequent attempts to get a `Meter` are allowed after calling