From 532e8e29f41b3c3c8aad4ae584c8c11d1703f5dd Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Mon, 7 Sep 2020 15:19:01 -0600 Subject: [PATCH 01/30] Add error handlers --- opentelemetry-sdk/setup.cfg | 2 + .../sdk/error_handler/__init__.py | 62 +++++++++++++++++++ .../tests/error_handler/__init__.py | 0 .../tests/error_handler/test_error_handler.py | 27 ++++++++ 4 files changed, 91 insertions(+) create mode 100644 opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py create mode 100644 opentelemetry-sdk/tests/error_handler/__init__.py create mode 100644 opentelemetry-sdk/tests/error_handler/test_error_handler.py diff --git a/opentelemetry-sdk/setup.cfg b/opentelemetry-sdk/setup.cfg index dd7c9aee350..290df969673 100644 --- a/opentelemetry-sdk/setup.cfg +++ b/opentelemetry-sdk/setup.cfg @@ -51,6 +51,8 @@ opentelemetry_meter_provider = sdk_meter_provider = opentelemetry.sdk.metrics:MeterProvider opentelemetry_tracer_provider = sdk_tracer_provider = opentelemetry.sdk.trace:TracerProvider +opentelemetry_error_handler = + default_error_handler = opentelemetry.sdk.error_handler:DefaultErrorHandler [options.extras_require] test = diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py new file mode 100644 index 00000000000..404c0ad7287 --- /dev/null +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -0,0 +1,62 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABC, abstractmethod +from pkg_resources import iter_entry_points +from logging import getLogger + +logger = getLogger(__name__) + + +class ErrorHandler(ABC): + + @abstractmethod + def handle(error: Exception, *args, **kwargs): + """ + Handle an exception + """ + + +class DefaultErrorHandler(ErrorHandler): + """ + Default error handler + + This error handler just logs the exception using standard logging. + """ + + def handle(error: Exception, *args, **kwargs): + + logger.exception("Error handled by default error handler: ") + + +class GlobalErrorHandler: + + def handle(error: Exception): + """ + Handle the error through the registered error handlers. + """ + + handling_result = {} + + for error_handler_class in iter_entry_points( + "opentelemetry_error_handler" + ): + + if issubclass(error_handler_class, error): + + handling_result[ + error_handler_class + ] = error_handler_class().handle(error) + + return handling_result diff --git a/opentelemetry-sdk/tests/error_handler/__init__.py b/opentelemetry-sdk/tests/error_handler/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/opentelemetry-sdk/tests/error_handler/test_error_handler.py b/opentelemetry-sdk/tests/error_handler/test_error_handler.py new file mode 100644 index 00000000000..6fa1cd48f61 --- /dev/null +++ b/opentelemetry-sdk/tests/error_handler/test_error_handler.py @@ -0,0 +1,27 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest import TestCase + +from opentelemetry.sdk.error_handler import DefaultErrorHandler + + +class TestErrorHandler(TestCase): + + def test_default_error_handler(self): + + try: + raise Exception("some exception") + except Exception as error: + DefaultErrorHandler(error) From 7ba4018162098eb001a61723ddbccef1db8d940d Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Mon, 7 Sep 2020 15:26:56 -0600 Subject: [PATCH 02/30] Add test case --- opentelemetry-sdk/tests/error_handler/test_error_handler.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/opentelemetry-sdk/tests/error_handler/test_error_handler.py b/opentelemetry-sdk/tests/error_handler/test_error_handler.py index 6fa1cd48f61..60cf82f6799 100644 --- a/opentelemetry-sdk/tests/error_handler/test_error_handler.py +++ b/opentelemetry-sdk/tests/error_handler/test_error_handler.py @@ -13,8 +13,9 @@ # limitations under the License. from unittest import TestCase +from logging import ERROR -from opentelemetry.sdk.error_handler import DefaultErrorHandler +from opentelemetry.sdk.error_handler import DefaultErrorHandler, logger class TestErrorHandler(TestCase): @@ -24,4 +25,5 @@ def test_default_error_handler(self): try: raise Exception("some exception") except Exception as error: - DefaultErrorHandler(error) + with self.assertLogs(logger, ERROR): + DefaultErrorHandler().handle(error) From 13fa21dd57119ba80dad44e78a08061c6b64d276 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Mon, 7 Sep 2020 17:01:20 -0600 Subject: [PATCH 03/30] Add more test cases --- opentelemetry-sdk/setup.cfg | 2 - .../sdk/error_handler/__init__.py | 47 ++++++++++++--- .../tests/error_handler/test_error_handler.py | 59 ++++++++++++++++++- 3 files changed, 95 insertions(+), 13 deletions(-) diff --git a/opentelemetry-sdk/setup.cfg b/opentelemetry-sdk/setup.cfg index 290df969673..dd7c9aee350 100644 --- a/opentelemetry-sdk/setup.cfg +++ b/opentelemetry-sdk/setup.cfg @@ -51,8 +51,6 @@ opentelemetry_meter_provider = sdk_meter_provider = opentelemetry.sdk.metrics:MeterProvider opentelemetry_tracer_provider = sdk_tracer_provider = opentelemetry.sdk.trace:TracerProvider -opentelemetry_error_handler = - default_error_handler = opentelemetry.sdk.error_handler:DefaultErrorHandler [options.extras_require] test = diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py index 404c0ad7287..8751d5f6d2d 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -22,7 +22,7 @@ class ErrorHandler(ABC): @abstractmethod - def handle(error: Exception, *args, **kwargs): + def handle(self, error: Exception, *args, **kwargs): """ Handle an exception """ @@ -35,28 +35,57 @@ class DefaultErrorHandler(ErrorHandler): This error handler just logs the exception using standard logging. """ - def handle(error: Exception, *args, **kwargs): + def handle(self, error: Exception, *args, **kwargs): logger.exception("Error handled by default error handler: ") class GlobalErrorHandler: - def handle(error: Exception): + _instance = None + + def __new__(cls) -> "GlobalErrorHandler": + if cls._instance is None: + cls._instance = super().__new__(cls) + + return cls._instance + + def handle(self, error: Exception): """ Handle the error through the registered error handlers. """ - handling_result = {} + error_handling_result = {} for error_handler_class in iter_entry_points( "opentelemetry_error_handler" ): - if issubclass(error_handler_class, error): + if issubclass(error_handler_class, error.__class__): + + try: + + error_handling_result[ + error_handler_class + ] = error_handler_class().handle(error) + + except Exception as error_handling_error: + + logger.exception( + "Error while handling error " + "by {} error handler".format( + error_handler_class.__name__ + ) + ) + + error_handling_result[error_handler_class] = ( + error_handling_error + ) + + if not error_handling_result: - handling_result[ - error_handler_class - ] = error_handler_class().handle(error) + error_handling_result[DefaultErrorHandler] = ( + DefaultErrorHandler().handle(error) + ) - return handling_result + return error_handling_result diff --git a/opentelemetry-sdk/tests/error_handler/test_error_handler.py b/opentelemetry-sdk/tests/error_handler/test_error_handler.py index 60cf82f6799..889f6bc23c0 100644 --- a/opentelemetry-sdk/tests/error_handler/test_error_handler.py +++ b/opentelemetry-sdk/tests/error_handler/test_error_handler.py @@ -13,9 +13,12 @@ # limitations under the License. from unittest import TestCase -from logging import ERROR +from logging import ERROR, disable, NOTSET +from unittest.mock import patch -from opentelemetry.sdk.error_handler import DefaultErrorHandler, logger +from opentelemetry.sdk.error_handler import ( + DefaultErrorHandler, logger, GlobalErrorHandler, ErrorHandler +) class TestErrorHandler(TestCase): @@ -27,3 +30,55 @@ def test_default_error_handler(self): except Exception as error: with self.assertLogs(logger, ERROR): DefaultErrorHandler().handle(error) + + try: + raise Exception("some exception") + except Exception as error: + with self.assertLogs(logger, ERROR): + error_handling_result = GlobalErrorHandler.handle(error) + + self.assertIsNone(error_handling_result[DefaultErrorHandler]) + + @patch("opentelemetry.sdk.error_handler.iter_entry_points") + def test_plugin_error_handler(self, mock_iter_entry_points): + + class ZeroDivisionErrorHandler(ErrorHandler, ZeroDivisionError): + + def handle(self, error: Exception): + return 0 + + class AssertionErrorHandler(ErrorHandler, AssertionError): + + def handle(self, error: Exception): + return 1 + + mock_iter_entry_points.configure_mock( + **{ + "return_value": [ + ZeroDivisionErrorHandler, AssertionErrorHandler + ] + } + ) + + try: + 1 / 0 + except Exception as error: + error_handling_result = GlobalErrorHandler().handle(error) + + self.assertEqual(error_handling_result, {ZeroDivisionErrorHandler: 0}) + + try: + assert False + except Exception as error: + error_handling_result = GlobalErrorHandler().handle(error) + + self.assertEqual(error_handling_result, {AssertionErrorHandler: 1}) + + try: + {}[1] + except Exception as error: + disable(ERROR) + error_handling_result = GlobalErrorHandler().handle(error) + disable(NOTSET) + + self.assertEqual(error_handling_result, {DefaultErrorHandler: None}) From b6e082058eb8bf282b1afc03ca2960e71617f39f Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Mon, 7 Sep 2020 17:43:26 -0600 Subject: [PATCH 04/30] Add context manager --- .../sdk/error_handler/__init__.py | 8 +++++ .../tests/error_handler/test_error_handler.py | 30 +++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py index 8751d5f6d2d..141d0e8b4a0 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -50,6 +50,14 @@ def __new__(cls) -> "GlobalErrorHandler": return cls._instance + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_value, traceback): + if exc_value is not None: + self.handle(exc_value) + return True + def handle(self, error: Exception): """ Handle the error through the registered error handlers. diff --git a/opentelemetry-sdk/tests/error_handler/test_error_handler.py b/opentelemetry-sdk/tests/error_handler/test_error_handler.py index 889f6bc23c0..5222630bc22 100644 --- a/opentelemetry-sdk/tests/error_handler/test_error_handler.py +++ b/opentelemetry-sdk/tests/error_handler/test_error_handler.py @@ -14,7 +14,7 @@ from unittest import TestCase from logging import ERROR, disable, NOTSET -from unittest.mock import patch +from unittest.mock import patch, Mock from opentelemetry.sdk.error_handler import ( DefaultErrorHandler, logger, GlobalErrorHandler, ErrorHandler @@ -35,7 +35,7 @@ def test_default_error_handler(self): raise Exception("some exception") except Exception as error: with self.assertLogs(logger, ERROR): - error_handling_result = GlobalErrorHandler.handle(error) + error_handling_result = GlobalErrorHandler().handle(error) self.assertIsNone(error_handling_result[DefaultErrorHandler]) @@ -82,3 +82,29 @@ def handle(self, error: Exception): disable(NOTSET) self.assertEqual(error_handling_result, {DefaultErrorHandler: None}) + + @patch("opentelemetry.sdk.error_handler.iter_entry_points") + def test_plugin_error_handler_context_manager( + self, mock_iter_entry_points + ): + + mock_error_handler_instance = Mock() + + class MockErrorHandlerClass(IndexError): + + def __new__(cls): + return mock_error_handler_instance + + mock_iter_entry_points.configure_mock( + **{"return_value": [MockErrorHandlerClass]} + ) + + error = IndexError() + + with GlobalErrorHandler(): + raise error + + with GlobalErrorHandler(): + pass + + mock_error_handler_instance.handle.assert_called_once_with(error) From 4a2b8f962963c8d7ede8ea5ebb0f6f9694bc30a5 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Mon, 7 Sep 2020 18:25:42 -0600 Subject: [PATCH 05/30] Add a description --- .../src/opentelemetry/sdk/error_handler/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py index 141d0e8b4a0..a51c40a2767 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -41,6 +41,13 @@ def handle(self, error: Exception, *args, **kwargs): class GlobalErrorHandler: + """ + Global error handler + + This is a singleton class that can be instantiated anywhere to get the + global error handler. This object provides a handle method that receives + an exception object that will be handled by the registered error handlers. + """ _instance = None From f424294ed9d53bc49da75ac12427797784473ebd Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Mon, 7 Sep 2020 18:39:11 -0600 Subject: [PATCH 06/30] Fix lint --- .../sdk/error_handler/__init__.py | 27 +++++++++++-------- .../tests/error_handler/test_error_handler.py | 21 ++++++++------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py index a51c40a2767..f9ec04f9765 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -13,14 +13,14 @@ # limitations under the License. from abc import ABC, abstractmethod -from pkg_resources import iter_entry_points from logging import getLogger +from pkg_resources import iter_entry_points + logger = getLogger(__name__) class ErrorHandler(ABC): - @abstractmethod def handle(self, error: Exception, *args, **kwargs): """ @@ -35,9 +35,11 @@ class DefaultErrorHandler(ErrorHandler): This error handler just logs the exception using standard logging. """ + # pylint: disable=useless-return def handle(self, error: Exception, *args, **kwargs): logger.exception("Error handled by default error handler: ") + return None class GlobalErrorHandler: @@ -60,10 +62,12 @@ def __new__(cls) -> "GlobalErrorHandler": def __enter__(self): pass + # pylint: disable=no-self-use def __exit__(self, exc_type, exc_value, traceback): if exc_value is not None: self.handle(exc_value) return True + return None def handle(self, error: Exception): """ @@ -84,23 +88,24 @@ def handle(self, error: Exception): error_handler_class ] = error_handler_class().handle(error) + # pylint: disable=broad-except except Exception as error_handling_error: logger.exception( "Error while handling error " - "by {} error handler".format( - error_handler_class.__name__ - ) + "by %s error handler", + error_handler_class.__name__ ) - error_handling_result[error_handler_class] = ( - error_handling_error - ) + error_handling_result[ + error_handler_class + ] = error_handling_error if not error_handling_result: - error_handling_result[DefaultErrorHandler] = ( - DefaultErrorHandler().handle(error) - ) + # pylint: disable=assignment-from-none + error_handling_result[ + DefaultErrorHandler + ] = DefaultErrorHandler().handle(error) return error_handling_result diff --git a/opentelemetry-sdk/tests/error_handler/test_error_handler.py b/opentelemetry-sdk/tests/error_handler/test_error_handler.py index 5222630bc22..085f529ee76 100644 --- a/opentelemetry-sdk/tests/error_handler/test_error_handler.py +++ b/opentelemetry-sdk/tests/error_handler/test_error_handler.py @@ -11,18 +11,21 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# pylint: disable=broad-except +from logging import ERROR, NOTSET, disable from unittest import TestCase -from logging import ERROR, disable, NOTSET -from unittest.mock import patch, Mock +from unittest.mock import Mock, patch from opentelemetry.sdk.error_handler import ( - DefaultErrorHandler, logger, GlobalErrorHandler, ErrorHandler + DefaultErrorHandler, + ErrorHandler, + GlobalErrorHandler, + logger, ) class TestErrorHandler(TestCase): - def test_default_error_handler(self): try: @@ -41,21 +44,21 @@ def test_default_error_handler(self): @patch("opentelemetry.sdk.error_handler.iter_entry_points") def test_plugin_error_handler(self, mock_iter_entry_points): - class ZeroDivisionErrorHandler(ErrorHandler, ZeroDivisionError): - + # pylint: disable=arguments-differ def handle(self, error: Exception): return 0 class AssertionErrorHandler(ErrorHandler, AssertionError): - + # pylint: disable=arguments-differ def handle(self, error: Exception): return 1 mock_iter_entry_points.configure_mock( **{ "return_value": [ - ZeroDivisionErrorHandler, AssertionErrorHandler + ZeroDivisionErrorHandler, + AssertionErrorHandler, ] } ) @@ -83,6 +86,7 @@ def handle(self, error: Exception): self.assertEqual(error_handling_result, {DefaultErrorHandler: None}) + # pylint: disable=no-self-use @patch("opentelemetry.sdk.error_handler.iter_entry_points") def test_plugin_error_handler_context_manager( self, mock_iter_entry_points @@ -91,7 +95,6 @@ def test_plugin_error_handler_context_manager( mock_error_handler_instance = Mock() class MockErrorHandlerClass(IndexError): - def __new__(cls): return mock_error_handler_instance From e289f06d7053a43bd82416d0927910dff2296942 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Mon, 7 Sep 2020 18:42:40 -0600 Subject: [PATCH 07/30] Update changelog --- opentelemetry-sdk/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 7fd47150ca9..940faaebabe 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Add Global Error Handler + ([#1079](https://github.com/open-telemetry/opentelemetry-python/pull/1079)) - Update sampling result names ([#1128](https://github.com/open-telemetry/opentelemetry-python/pull/1128)) From e4d35bfc906f513145aaf0a6a01866e082bc1023 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 8 Sep 2020 09:38:12 -0600 Subject: [PATCH 08/30] Fix lint --- .../src/opentelemetry/sdk/error_handler/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py index f9ec04f9765..43d07e30714 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -92,9 +92,8 @@ def handle(self, error: Exception): except Exception as error_handling_error: logger.exception( - "Error while handling error " - "by %s error handler", - error_handler_class.__name__ + "Error while handling error " "by %s error handler", + error_handler_class.__name__, ) error_handling_result[ From 5618e456caa160f6dcccc0b7b0fa328701e137cc Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 8 Sep 2020 10:25:19 -0600 Subject: [PATCH 09/30] Load entry point --- .../src/opentelemetry/sdk/error_handler/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py index 43d07e30714..c734018a68f 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -76,10 +76,12 @@ def handle(self, error: Exception): error_handling_result = {} - for error_handler_class in iter_entry_points( + for error_handler_entry_point in iter_entry_points( "opentelemetry_error_handler" ): + error_handler_class = error_handler_entry_point.load() + if issubclass(error_handler_class, error.__class__): try: From 4edb6960e0103f8c16f7d1f62b9e1408495627b9 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 8 Sep 2020 10:37:41 -0600 Subject: [PATCH 10/30] Fix tests --- .../tests/error_handler/test_error_handler.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/opentelemetry-sdk/tests/error_handler/test_error_handler.py b/opentelemetry-sdk/tests/error_handler/test_error_handler.py index 085f529ee76..ba5b5bc2226 100644 --- a/opentelemetry-sdk/tests/error_handler/test_error_handler.py +++ b/opentelemetry-sdk/tests/error_handler/test_error_handler.py @@ -54,11 +54,20 @@ class AssertionErrorHandler(ErrorHandler, AssertionError): def handle(self, error: Exception): return 1 + mock_entry_point_zero_division_error_handler = Mock() + mock_entry_point_zero_division_error_handler.configure_mock( + **{"load.return_value": ZeroDivisionErrorHandler} + ) + mock_entry_point_assertion_error_handler = Mock() + mock_entry_point_assertion_error_handler.configure_mock( + **{"load.return_value": AssertionErrorHandler} + ) + mock_iter_entry_points.configure_mock( **{ "return_value": [ - ZeroDivisionErrorHandler, - AssertionErrorHandler, + mock_entry_point_zero_division_error_handler, + mock_entry_point_assertion_error_handler, ] } ) @@ -98,8 +107,13 @@ class MockErrorHandlerClass(IndexError): def __new__(cls): return mock_error_handler_instance + mock_entry_point_error_handler = Mock() + mock_entry_point_error_handler.configure_mock( + **{"load.return_value": MockErrorHandlerClass} + ) + mock_iter_entry_points.configure_mock( - **{"return_value": [MockErrorHandlerClass]} + **{"return_value": [mock_entry_point_error_handler]} ) error = IndexError() From 39511d5b16e33d47e77a3d77b5db8aeebfc057cd Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 8 Sep 2020 17:06:02 -0600 Subject: [PATCH 11/30] Add docs --- docs/sdk/error_handler.rst | 7 +++ docs/sdk/sdk.rst | 1 + .../sdk/error_handler/__init__.py | 47 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 docs/sdk/error_handler.rst diff --git a/docs/sdk/error_handler.rst b/docs/sdk/error_handler.rst new file mode 100644 index 00000000000..49962bf769c --- /dev/null +++ b/docs/sdk/error_handler.rst @@ -0,0 +1,7 @@ +opentelemetry.sdk.error_handler package +======================================= + +.. automodule:: opentelemetry.sdk.error_handler + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/sdk/sdk.rst b/docs/sdk/sdk.rst index b1dae535e21..e777aebac65 100644 --- a/docs/sdk/sdk.rst +++ b/docs/sdk/sdk.rst @@ -9,3 +9,4 @@ OpenTelemetry Python SDK metrics resources trace + error_handler diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py index c734018a68f..cb0fe8e1404 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -12,6 +12,53 @@ # See the License for the specific language governing permissions and # limitations under the License. +""" +Global Error Handler + +This module provides a global error handler and an interface that allows +error handlers to be registered with the global error handler via entry points. +A default error handler is also provided. + +To use this feature, users can create an error handler that is registered +using the ``opentelemetry_error_handler`` entry point. A class is to be +registered in this entry point, this class must inherit from the +``opentelemetry.sdk.error_handler.ErrorHandler`` class and implement the +corresponding ``handle`` method. This method will receive the exception object +that is to be handled. The error handler class should also inherit from the +exception classes it wants to handle. For example, this would be an error +handler that handles ``ZeroDivisionError``: + +.. code:: python + + from opentelemetry.sdk.error_handler import ErrorHandler + from logging import getLogger + + logger = getLogger(__name__) + + + class ErrorHandler0(ErrorHandler, ZeroDivisionError): + + def handle(self, error: Exception, *args, **kwargs): + + logger.exception("ErrorHandler0 handling a ZeroDivisionError") + +To use the global error handler, just instantiate it as a context manager where +you want exceptions to be handled: + + +.. code:: python + + from opentelemetry.sdk.error_handler import GlobalErrorHandler + + with GlobalErrorHandler(): + 1 / 0 + +If the class of the exception raised in the scope of the ``GlobalErrorHandler`` +object is not parent of any registered error handler, then the default error +handler will handle the exception. This default error handler will only log the +exception to standard logging, the exception won't be raised any further. +""" + from abc import ABC, abstractmethod from logging import getLogger From 3169ac3584fbf1322f9d68385a5843a0cc20f9ea Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 8 Sep 2020 19:12:38 -0600 Subject: [PATCH 12/30] Add example --- docs/examples/error_hander/README.rst | 149 ++++++++++++++++++ .../error_hander/error_handler_0/setup.cfg | 47 ++++++ .../error_hander/error_handler_0/setup.py | 26 +++ .../src/error_handler_0/__init__.py | 25 +++ .../src/error_handler_0/version.py | 15 ++ .../error_hander/error_handler_1/setup.cfg | 47 ++++++ .../error_hander/error_handler_1/setup.py | 26 +++ .../src/error_handler_1/__init__.py | 29 ++++ .../src/error_handler_1/version.py | 15 ++ docs/examples/error_hander/example.py | 29 ++++ 10 files changed, 408 insertions(+) create mode 100644 docs/examples/error_hander/README.rst create mode 100644 docs/examples/error_hander/error_handler_0/setup.cfg create mode 100644 docs/examples/error_hander/error_handler_0/setup.py create mode 100644 docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py create mode 100644 docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py create mode 100644 docs/examples/error_hander/error_handler_1/setup.cfg create mode 100644 docs/examples/error_hander/error_handler_1/setup.py create mode 100644 docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py create mode 100644 docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py create mode 100644 docs/examples/error_hander/example.py diff --git a/docs/examples/error_hander/README.rst b/docs/examples/error_hander/README.rst new file mode 100644 index 00000000000..515e2e79808 --- /dev/null +++ b/docs/examples/error_hander/README.rst @@ -0,0 +1,149 @@ +Global Error Handler +==================== + +Overview +-------- + +This example shows how to use the global error handler. + + +Preparation +----------- + +This example will be executed in a separate virtual environment: + +.. code:: sh + + $ mkdir global_error_handler + $ virtualenv global_error_handler + $ source global_error_handler/bin/activate + +Installation +------------ + +Here we install first `opentelemetry-sdk`, the only dependency. Afterwards, 2 +error handlers are installed: `error_handler_0` will handle `ZeroDivisionError` +exceptions, `error_handler_1` will handle `IndexError` and `KeyError` exceptions. + +.. code:: sh + + $ pip install opentelemetry-sdk + $ git clone https://github.com/open-telemetry/opentelemetry-python.git + $ pip install -e opentelemetry-python/docs/examples/error_handler/error_handler_0 + $ pip install -e opentelemetry-python/docs/examples/error_handler/error_handler_1 + +Execution +--------- + +An example is provided in the `opentelemetry-python/docs/examples/error_handler/example.py`. + +You can just run it, you should get output similar to this one: + +.. code:: + + ErrorHandler0 handling a ZeroDivisionError + Traceback (most recent call last): + File "test.py", line 5, in + 1 / 0 + ZeroDivisionError: division by zero + + ErrorHandler1 handling an IndexError + Traceback (most recent call last): + File "test.py", line 11, in + [1][2] + IndexError: list index out of range + + ErrorHandler1 handling a KeyError + Traceback (most recent call last): + File "test.py", line 17, in + {1: 2}[2] + KeyError: 2 + + Error handled by default error handler: + Traceback (most recent call last): + File "test.py", line 23, in + assert False + AssertionError + + No error raised + +The `opentelemetry-sdk.error_handler` module includes documentation that +explains how this works. We recommend you read it also, here is just a small +summary. + +In `example.py` we use `GlobalErrorHandler` as a context manager in several +places, for example: + + +.. code:: python + + with GlobalErrorHandler(): + {1: 2}[2] + +Running that code will raise a `KeyError` exception, of course. `GlobalErrorHandler` +will "capture" that exception and pass it down to the registered error handlers. +If there is one that handles `KeyError` exceptions then it will handle it. That +can be seen in the result of the execution of `example.py`: + +.. code:: + + ErrorHandler1 handling a KeyError + Traceback (most recent call last): + File "test.py", line 17, in + {1: 2}[2] + KeyError: 2 + +There is no registered error handler that can handle `AssertionError` exceptions +so this kind of errors are handled by the default error handler which just logs +the exception to standard logging, as seen here: + +.. code:: + + Error handled by default error handler: + Traceback (most recent call last): + File "test.py", line 23, in + assert False + AssertionError + +When no exception is raised, the code inside the scope of `GlobalErrorHandler` +is exectued normally: + +.. code:: + + No error raised + +Users can create Python packages that provide their own custom error handlers +and install them in their virtual environments before running their code which +instantiates `GlobalErrorHandler` context managers. `error_handler_0` and +`error_handler_1` can be used as examples to create these custom error handlers. + +In order for the error handlers to be registered, they need to create a class +that inherits from `opentelemetry.sdk.error_handler.ErrorHandler` and at least +one `Exception`-type class. For example, this is an error handler that handles +`ZeroDivisionError` exceptions: + +.. code:: python + + from opentelemetry.sdk.error_handler import ErrorHandler + from logging import getLogger + + logger = getLogger(__name__) + + + class ErrorHandler0(ErrorHandler, ZeroDivisionError): + + def handle(self, error: Exception, *args, **kwargs): + + logger.exception("ErrorHandler0 handling a ZeroDivisionError") + +To register this error handler, use the `opentelemetry_error_handler` entry +point in the setup of the error handler package: + +.. code:: + + [options.entry_points] + opentelemetry_error_handler = + error_handler_0 = error_handler_0:ErrorHandler0 + +This entry point should point to the error handler class, `ErrorHandler0` in +this case. diff --git a/docs/examples/error_hander/error_handler_0/setup.cfg b/docs/examples/error_hander/error_handler_0/setup.cfg new file mode 100644 index 00000000000..931900f2a1d --- /dev/null +++ b/docs/examples/error_hander/error_handler_0/setup.cfg @@ -0,0 +1,47 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +[metadata] +name = error-handler-0 +description = Error Handler 0 for OpenTelemetry +author = OpenTelemetry Authors +author_email = cncf-opentelemetry-contributors@lists.cncf.io +platforms = any +license = Apache-2.0 +classifiers = + Development Status :: 4 - Beta + Intended Audience :: Developers + License :: OSI Approved :: Apache Software License + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.4 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + +[options] +python_requires = >=3.4 +package_dir= + =src +packages=find_namespace: +install_requires = + opentelemetry-sdk == 0.13dev0 + +[options.packages.find] +where = src + +[options.entry_points] +opentelemetry_error_handler = + error_handler_0 = error_handler_0:ErrorHandler0 diff --git a/docs/examples/error_hander/error_handler_0/setup.py b/docs/examples/error_hander/error_handler_0/setup.py new file mode 100644 index 00000000000..9e174aa7bbe --- /dev/null +++ b/docs/examples/error_hander/error_handler_0/setup.py @@ -0,0 +1,26 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os + +import setuptools + +BASE_DIR = os.path.dirname(__file__) +VERSION_FILENAME = os.path.join( + BASE_DIR, "src", "error_handler_0", "version.py" +) +PACKAGE_INFO = {} +with open(VERSION_FILENAME) as f: + exec(f.read(), PACKAGE_INFO) + +setuptools.setup(version=PACKAGE_INFO["__version__"]) diff --git a/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py b/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py new file mode 100644 index 00000000000..1697f3b5271 --- /dev/null +++ b/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py @@ -0,0 +1,25 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opentelemetry.sdk.error_handler import ErrorHandler +from logging import getLogger + +logger = getLogger(__name__) + + +class ErrorHandler0(ErrorHandler, ZeroDivisionError): + + def handle(self, error: Exception, *args, **kwargs): + + logger.exception("ErrorHandler0 handling a ZeroDivisionError") diff --git a/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py b/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py new file mode 100644 index 00000000000..9cc445d09e1 --- /dev/null +++ b/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "0.13dev0" diff --git a/docs/examples/error_hander/error_handler_1/setup.cfg b/docs/examples/error_hander/error_handler_1/setup.cfg new file mode 100644 index 00000000000..6bf73160f9a --- /dev/null +++ b/docs/examples/error_hander/error_handler_1/setup.cfg @@ -0,0 +1,47 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +[metadata] +name = error_handler_1 +description = Error Handler 1 for OpenTelemetry +author = OpenTelemetry Authors +author_email = cncf-opentelemetry-contributors@lists.cncf.io +platforms = any +license = Apache-2.0 +classifiers = + Development Status :: 4 - Beta + Intended Audience :: Developers + License :: OSI Approved :: Apache Software License + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.4 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + +[options] +python_requires = >=3.4 +package_dir= + =src +packages=find_namespace: +install_requires = + opentelemetry-sdk == 0.13dev0 + +[options.packages.find] +where = src + +[options.entry_points] +opentelemetry_error_handler = + error_handler_1 = error_handler_1:ErrorHandler1 diff --git a/docs/examples/error_hander/error_handler_1/setup.py b/docs/examples/error_hander/error_handler_1/setup.py new file mode 100644 index 00000000000..ccb282dbb23 --- /dev/null +++ b/docs/examples/error_hander/error_handler_1/setup.py @@ -0,0 +1,26 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os + +import setuptools + +BASE_DIR = os.path.dirname(__file__) +VERSION_FILENAME = os.path.join( + BASE_DIR, "src", "error_handler_1", "version.py" +) +PACKAGE_INFO = {} +with open(VERSION_FILENAME) as f: + exec(f.read(), PACKAGE_INFO) + +setuptools.setup(version=PACKAGE_INFO["__version__"]) diff --git a/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py b/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py new file mode 100644 index 00000000000..4620cbec6b6 --- /dev/null +++ b/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py @@ -0,0 +1,29 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opentelemetry.sdk.error_handler import ErrorHandler +from logging import getLogger + +logger = getLogger(__name__) + + +class ErrorHandler1(ErrorHandler, IndexError, KeyError): + + def handle(self, error: Exception, *args, **kwargs): + + if isinstance(error, IndexError): + logger.exception("ErrorHandler1 handling an IndexError") + + elif isinstance(error, KeyError): + logger.exception("ErrorHandler1 handling a KeyError") diff --git a/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py b/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py new file mode 100644 index 00000000000..9cc445d09e1 --- /dev/null +++ b/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = "0.13dev0" diff --git a/docs/examples/error_hander/example.py b/docs/examples/error_hander/example.py new file mode 100644 index 00000000000..372c39c16fd --- /dev/null +++ b/docs/examples/error_hander/example.py @@ -0,0 +1,29 @@ +from opentelemetry.sdk.error_handler import GlobalErrorHandler + +# ZeroDivisionError to be handled by ErrorHandler0 +with GlobalErrorHandler(): + 1 / 0 + +print() + +# IndexError to be handled by ErrorHandler1 +with GlobalErrorHandler(): + [1][2] + +print() + +# KeyError to be handled by ErrorHandler1 +with GlobalErrorHandler(): + {1: 2}[2] + +print() + +# AssertionError to be handled by DefaultErrorHandler +with GlobalErrorHandler(): + assert False + +print() + +# No error raised +with GlobalErrorHandler(): + print("No error raised") From 836074d3c86ab8bbcb22d961c810854c72843d23 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 8 Sep 2020 19:35:05 -0600 Subject: [PATCH 13/30] Fix docs --- docs/examples/error_hander/README.rst | 48 ++++++++++--------- .../src/error_handler_0/__init__.py | 4 +- .../src/error_handler_1/__init__.py | 4 +- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/docs/examples/error_hander/README.rst b/docs/examples/error_hander/README.rst index 515e2e79808..948c9557e69 100644 --- a/docs/examples/error_hander/README.rst +++ b/docs/examples/error_hander/README.rst @@ -21,9 +21,10 @@ This example will be executed in a separate virtual environment: Installation ------------ -Here we install first `opentelemetry-sdk`, the only dependency. Afterwards, 2 -error handlers are installed: `error_handler_0` will handle `ZeroDivisionError` -exceptions, `error_handler_1` will handle `IndexError` and `KeyError` exceptions. +Here we install first ``opentelemetry-sdk``, the only dependency. Afterwards, 2 +error handlers are installed: ``error_handler_0`` will handle +``ZeroDivisionError`` exceptions, ``error_handler_1`` will handle +``IndexError`` and ``KeyError`` exceptions. .. code:: sh @@ -35,7 +36,8 @@ exceptions, `error_handler_1` will handle `IndexError` and `KeyError` exceptions Execution --------- -An example is provided in the `opentelemetry-python/docs/examples/error_handler/example.py`. +An example is provided in the +``opentelemetry-python/docs/examples/error_handler/example.py``. You can just run it, you should get output similar to this one: @@ -67,11 +69,11 @@ You can just run it, you should get output similar to this one: No error raised -The `opentelemetry-sdk.error_handler` module includes documentation that +The ``opentelemetry-sdk.error_handler`` module includes documentation that explains how this works. We recommend you read it also, here is just a small summary. -In `example.py` we use `GlobalErrorHandler` as a context manager in several +In ``example.py`` we use ``GlobalErrorHandler`` as a context manager in several places, for example: @@ -80,10 +82,11 @@ places, for example: with GlobalErrorHandler(): {1: 2}[2] -Running that code will raise a `KeyError` exception, of course. `GlobalErrorHandler` -will "capture" that exception and pass it down to the registered error handlers. -If there is one that handles `KeyError` exceptions then it will handle it. That -can be seen in the result of the execution of `example.py`: +Running that code will raise a ``KeyError`` exception, of course. +``GlobalErrorHandler`` will "capture" that exception and pass it down to the +registered error handlers. If there is one that handles ``KeyError`` exceptions +then it will handle it. That can be seen in the result of the execution of +``example.py``: .. code:: @@ -93,9 +96,9 @@ can be seen in the result of the execution of `example.py`: {1: 2}[2] KeyError: 2 -There is no registered error handler that can handle `AssertionError` exceptions -so this kind of errors are handled by the default error handler which just logs -the exception to standard logging, as seen here: +There is no registered error handler that can handle ``AssertionError`` +exceptions so this kind of errors are handled by the default error handler +which just logs the exception to standard logging, as seen here: .. code:: @@ -105,8 +108,8 @@ the exception to standard logging, as seen here: assert False AssertionError -When no exception is raised, the code inside the scope of `GlobalErrorHandler` -is exectued normally: +When no exception is raised, the code inside the scope of +``GlobalErrorHandler`` is exectued normally: .. code:: @@ -114,13 +117,14 @@ is exectued normally: Users can create Python packages that provide their own custom error handlers and install them in their virtual environments before running their code which -instantiates `GlobalErrorHandler` context managers. `error_handler_0` and -`error_handler_1` can be used as examples to create these custom error handlers. +instantiates ``GlobalErrorHandler`` context managers. ``error_handler_0`` and +``error_handler_1`` can be used as examples to create these custom error +handlers. In order for the error handlers to be registered, they need to create a class -that inherits from `opentelemetry.sdk.error_handler.ErrorHandler` and at least -one `Exception`-type class. For example, this is an error handler that handles -`ZeroDivisionError` exceptions: +that inherits from ``opentelemetry.sdk.error_handler.ErrorHandler`` and at +least one ``Exception``-type class. For example, this is an error handler that +handles ``ZeroDivisionError`` exceptions: .. code:: python @@ -136,7 +140,7 @@ one `Exception`-type class. For example, this is an error handler that handles logger.exception("ErrorHandler0 handling a ZeroDivisionError") -To register this error handler, use the `opentelemetry_error_handler` entry +To register this error handler, use the ``opentelemetry_error_handler`` entry point in the setup of the error handler package: .. code:: @@ -145,5 +149,5 @@ point in the setup of the error handler package: opentelemetry_error_handler = error_handler_0 = error_handler_0:ErrorHandler0 -This entry point should point to the error handler class, `ErrorHandler0` in +This entry point should point to the error handler class, ``ErrorHandler0`` in this case. diff --git a/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py b/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py index 1697f3b5271..427eb0b2df3 100644 --- a/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py +++ b/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py @@ -12,14 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -from opentelemetry.sdk.error_handler import ErrorHandler from logging import getLogger +from opentelemetry.sdk.error_handler import ErrorHandler + logger = getLogger(__name__) class ErrorHandler0(ErrorHandler, ZeroDivisionError): - def handle(self, error: Exception, *args, **kwargs): logger.exception("ErrorHandler0 handling a ZeroDivisionError") diff --git a/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py b/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py index 4620cbec6b6..3f1f369d718 100644 --- a/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py +++ b/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py @@ -12,14 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -from opentelemetry.sdk.error_handler import ErrorHandler from logging import getLogger +from opentelemetry.sdk.error_handler import ErrorHandler + logger = getLogger(__name__) class ErrorHandler1(ErrorHandler, IndexError, KeyError): - def handle(self, error: Exception, *args, **kwargs): if isinstance(error, IndexError): From 199f1cab2f956b7ea56d2da4cec83878db8968c0 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 8 Sep 2020 21:13:34 -0600 Subject: [PATCH 14/30] Fix lint --- .../error_hander/error_handler_1/src/error_handler_1/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py b/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py index 3f1f369d718..8c3ce1c7ce7 100644 --- a/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py +++ b/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py @@ -19,6 +19,7 @@ logger = getLogger(__name__) +# pylint: disable=too-many-ancestors class ErrorHandler1(ErrorHandler, IndexError, KeyError): def handle(self, error: Exception, *args, **kwargs): From efe47ccacfac5bfc92d77250ea52fb8bb5c6e72e Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 9 Sep 2020 09:59:20 -0600 Subject: [PATCH 15/30] Skip README check --- scripts/check_for_valid_readme.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/check_for_valid_readme.py b/scripts/check_for_valid_readme.py index d555b4fa2f9..c468bb787e2 100644 --- a/scripts/check_for_valid_readme.py +++ b/scripts/check_for_valid_readme.py @@ -29,6 +29,12 @@ def main(): error = False for path in map(Path, args.paths): + + # docs/examples/error_handler incldues two Python packages that lack a + # README file. This is intentional so they are skipped here. + if "error_handler" in path.as_posix(): + continue + readme = path / "README.rst" try: if not is_valid_rst(readme): From 9637c05d099fc2a7d7b48ee5f2e928287b4a127f Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 9 Sep 2020 10:05:41 -0600 Subject: [PATCH 16/30] Update docs/examples/error_hander/README.rst Co-authored-by: Daniel <61800298+ffe4@users.noreply.github.com> --- docs/examples/error_hander/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/error_hander/README.rst b/docs/examples/error_hander/README.rst index 948c9557e69..d21d04452d8 100644 --- a/docs/examples/error_hander/README.rst +++ b/docs/examples/error_hander/README.rst @@ -41,7 +41,7 @@ An example is provided in the You can just run it, you should get output similar to this one: -.. code:: +.. code:: pytb ErrorHandler0 handling a ZeroDivisionError Traceback (most recent call last): From 00c597b16513bfc23d4de7139c7174532cb95bc4 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 15 Sep 2020 16:14:46 -0600 Subject: [PATCH 17/30] Remove result returning --- .../src/error_handler_0/__init__.py | 2 +- .../src/error_handler_1/__init__.py | 2 +- .../sdk/error_handler/__init__.py | 44 ++++------ .../tests/error_handler/test_error_handler.py | 80 ++++++++++--------- 4 files changed, 62 insertions(+), 66 deletions(-) diff --git a/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py b/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py index 427eb0b2df3..8b42b7c70eb 100644 --- a/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py +++ b/docs/examples/error_hander/error_handler_0/src/error_handler_0/__init__.py @@ -20,6 +20,6 @@ class ErrorHandler0(ErrorHandler, ZeroDivisionError): - def handle(self, error: Exception, *args, **kwargs): + def _handle(self, error: Exception, *args, **kwargs): logger.exception("ErrorHandler0 handling a ZeroDivisionError") diff --git a/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py b/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py index 8c3ce1c7ce7..cc63465617f 100644 --- a/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py +++ b/docs/examples/error_hander/error_handler_1/src/error_handler_1/__init__.py @@ -21,7 +21,7 @@ # pylint: disable=too-many-ancestors class ErrorHandler1(ErrorHandler, IndexError, KeyError): - def handle(self, error: Exception, *args, **kwargs): + def _handle(self, error: Exception, *args, **kwargs): if isinstance(error, IndexError): logger.exception("ErrorHandler1 handling an IndexError") diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py index cb0fe8e1404..6afbd7c2f3b 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/error_handler/__init__.py @@ -38,7 +38,7 @@ class ErrorHandler0(ErrorHandler, ZeroDivisionError): - def handle(self, error: Exception, *args, **kwargs): + def _handle(self, error: Exception, *args, **kwargs): logger.exception("ErrorHandler0 handling a ZeroDivisionError") @@ -69,7 +69,7 @@ def handle(self, error: Exception, *args, **kwargs): class ErrorHandler(ABC): @abstractmethod - def handle(self, error: Exception, *args, **kwargs): + def _handle(self, error: Exception, *args, **kwargs): """ Handle an exception """ @@ -83,7 +83,7 @@ class DefaultErrorHandler(ErrorHandler): """ # pylint: disable=useless-return - def handle(self, error: Exception, *args, **kwargs): + def _handle(self, error: Exception, *args, **kwargs): logger.exception("Error handled by default error handler: ") return None @@ -111,17 +111,12 @@ def __enter__(self): # pylint: disable=no-self-use def __exit__(self, exc_type, exc_value, traceback): - if exc_value is not None: - self.handle(exc_value) - return True - return None - def handle(self, error: Exception): - """ - Handle the error through the registered error handlers. - """ + if exc_value is None: - error_handling_result = {} + return None + + plugin_handled = False for error_handler_entry_point in iter_entry_points( "opentelemetry_error_handler" @@ -129,31 +124,26 @@ def handle(self, error: Exception): error_handler_class = error_handler_entry_point.load() - if issubclass(error_handler_class, error.__class__): + if issubclass(error_handler_class, exc_value.__class__): try: - error_handling_result[ - error_handler_class - ] = error_handler_class().handle(error) + error_handler_class()._handle(exc_value) + plugin_handled = True # pylint: disable=broad-except except Exception as error_handling_error: logger.exception( - "Error while handling error " "by %s error handler", + "%s error while handling error" + " %s by error handler %s", + error_handling_error.__class__.__name__, + exc_value.__class__.__name__, error_handler_class.__name__, ) - error_handling_result[ - error_handler_class - ] = error_handling_error - - if not error_handling_result: + if not plugin_handled: - # pylint: disable=assignment-from-none - error_handling_result[ - DefaultErrorHandler - ] = DefaultErrorHandler().handle(error) + DefaultErrorHandler()._handle(exc_value) - return error_handling_result + return True diff --git a/opentelemetry-sdk/tests/error_handler/test_error_handler.py b/opentelemetry-sdk/tests/error_handler/test_error_handler.py index ba5b5bc2226..7ec572d9379 100644 --- a/opentelemetry-sdk/tests/error_handler/test_error_handler.py +++ b/opentelemetry-sdk/tests/error_handler/test_error_handler.py @@ -13,12 +13,11 @@ # limitations under the License. # pylint: disable=broad-except -from logging import ERROR, NOTSET, disable +from logging import ERROR from unittest import TestCase from unittest.mock import Mock, patch from opentelemetry.sdk.error_handler import ( - DefaultErrorHandler, ErrorHandler, GlobalErrorHandler, logger, @@ -28,31 +27,22 @@ class TestErrorHandler(TestCase): def test_default_error_handler(self): - try: - raise Exception("some exception") - except Exception as error: - with self.assertLogs(logger, ERROR): - DefaultErrorHandler().handle(error) - - try: - raise Exception("some exception") - except Exception as error: - with self.assertLogs(logger, ERROR): - error_handling_result = GlobalErrorHandler().handle(error) - - self.assertIsNone(error_handling_result[DefaultErrorHandler]) + with self.assertLogs(logger, ERROR): + with GlobalErrorHandler(): + raise Exception("some exception") + # pylint: disable=no-self-use @patch("opentelemetry.sdk.error_handler.iter_entry_points") def test_plugin_error_handler(self, mock_iter_entry_points): class ZeroDivisionErrorHandler(ErrorHandler, ZeroDivisionError): # pylint: disable=arguments-differ - def handle(self, error: Exception): - return 0 + + _handle = Mock() class AssertionErrorHandler(ErrorHandler, AssertionError): # pylint: disable=arguments-differ - def handle(self, error: Exception): - return 1 + + _handle = Mock() mock_entry_point_zero_division_error_handler = Mock() mock_entry_point_zero_division_error_handler.configure_mock( @@ -72,28 +62,43 @@ def handle(self, error: Exception): } ) - try: - 1 / 0 - except Exception as error: - error_handling_result = GlobalErrorHandler().handle(error) + error = ZeroDivisionError() + + with GlobalErrorHandler(): + raise error + + # pylint: disable=protected-access + ZeroDivisionErrorHandler._handle.assert_called_with(error) + + error = AssertionError() - self.assertEqual(error_handling_result, {ZeroDivisionErrorHandler: 0}) + with GlobalErrorHandler(): + raise error + + AssertionErrorHandler._handle.assert_called_with(error) + + @patch("opentelemetry.sdk.error_handler.iter_entry_points") + def test_error_in_handler(self, mock_iter_entry_points): + class ErrorErrorHandler(ErrorHandler, ZeroDivisionError): + # pylint: disable=arguments-differ + + def _handle(self, error: Exception): + assert False - try: - assert False - except Exception as error: - error_handling_result = GlobalErrorHandler().handle(error) + mock_entry_point_error_error_handler = Mock() + mock_entry_point_error_error_handler.configure_mock( + **{"load.return_value": ErrorErrorHandler} + ) - self.assertEqual(error_handling_result, {AssertionErrorHandler: 1}) + mock_iter_entry_points.configure_mock( + **{"return_value": [mock_entry_point_error_error_handler]} + ) - try: - {}[1] - except Exception as error: - disable(ERROR) - error_handling_result = GlobalErrorHandler().handle(error) - disable(NOTSET) + error = ZeroDivisionError() - self.assertEqual(error_handling_result, {DefaultErrorHandler: None}) + with self.assertLogs(logger, ERROR): + with GlobalErrorHandler(): + raise error # pylint: disable=no-self-use @patch("opentelemetry.sdk.error_handler.iter_entry_points") @@ -124,4 +129,5 @@ def __new__(cls): with GlobalErrorHandler(): pass - mock_error_handler_instance.handle.assert_called_once_with(error) + # pylint: disable=protected-access + mock_error_handler_instance._handle.assert_called_once_with(error) From ac6461aa15ae21d496f580e1634a0afeb5f2f223 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:13:14 -0600 Subject: [PATCH 18/30] Update scripts/check_for_valid_readme.py Co-authored-by: alrex --- scripts/check_for_valid_readme.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_for_valid_readme.py b/scripts/check_for_valid_readme.py index c468bb787e2..e25b318a1f0 100644 --- a/scripts/check_for_valid_readme.py +++ b/scripts/check_for_valid_readme.py @@ -30,7 +30,7 @@ def main(): for path in map(Path, args.paths): - # docs/examples/error_handler incldues two Python packages that lack a + # docs/examples/error_handler includes two Python packages that lack a # README file. This is intentional so they are skipped here. if "error_handler" in path.as_posix(): continue From 49cb3553931715c9bf27ec261c5847cae742e44d Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:13:42 -0600 Subject: [PATCH 19/30] Update docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py Co-authored-by: alrex --- .../error_hander/error_handler_1/src/error_handler_1/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py b/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py index 9cc445d09e1..0f990278982 100644 --- a/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py +++ b/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.13dev0" +__version__ = "0.14.dev0" From 037ca398fe762d8a87d1f445411fb02f33b4c0e4 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:13:51 -0600 Subject: [PATCH 20/30] Update docs/examples/error_hander/error_handler_1/setup.cfg Co-authored-by: alrex --- docs/examples/error_hander/error_handler_1/setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/examples/error_hander/error_handler_1/setup.cfg b/docs/examples/error_hander/error_handler_1/setup.cfg index 6bf73160f9a..860fc29b443 100644 --- a/docs/examples/error_hander/error_handler_1/setup.cfg +++ b/docs/examples/error_hander/error_handler_1/setup.cfg @@ -25,7 +25,6 @@ classifiers = License :: OSI Approved :: Apache Software License Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 From 33080e292471bcf20e37c0bd8f0c75cefe0993d8 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:16:15 -0600 Subject: [PATCH 21/30] Update docs/examples/error_hander/error_handler_1/setup.cfg Co-authored-by: alrex --- docs/examples/error_hander/error_handler_1/setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/error_hander/error_handler_1/setup.cfg b/docs/examples/error_hander/error_handler_1/setup.cfg index 860fc29b443..0f2fdedd7d7 100644 --- a/docs/examples/error_hander/error_handler_1/setup.cfg +++ b/docs/examples/error_hander/error_handler_1/setup.cfg @@ -36,7 +36,7 @@ package_dir= =src packages=find_namespace: install_requires = - opentelemetry-sdk == 0.13dev0 + opentelemetry-sdk == 0.14.dev0 [options.packages.find] where = src From dc8fd8b152c04853a261e1d0c3a98f09ad819bc2 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:16:24 -0600 Subject: [PATCH 22/30] Update docs/examples/error_hander/error_handler_0/setup.cfg Co-authored-by: alrex --- docs/examples/error_hander/error_handler_0/setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/error_hander/error_handler_0/setup.cfg b/docs/examples/error_hander/error_handler_0/setup.cfg index 931900f2a1d..82168ca5fe2 100644 --- a/docs/examples/error_hander/error_handler_0/setup.cfg +++ b/docs/examples/error_hander/error_handler_0/setup.cfg @@ -32,7 +32,7 @@ classifiers = Programming Language :: Python :: 3.8 [options] -python_requires = >=3.4 +python_requires = >=3.5 package_dir= =src packages=find_namespace: From 4079706a817a5a6bf7cf4b5d1f68b11d042fb51a Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:16:49 -0600 Subject: [PATCH 23/30] Update docs/examples/error_hander/error_handler_0/setup.cfg Co-authored-by: alrex --- docs/examples/error_hander/error_handler_0/setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/error_hander/error_handler_0/setup.cfg b/docs/examples/error_hander/error_handler_0/setup.cfg index 82168ca5fe2..a71b87d3b3e 100644 --- a/docs/examples/error_hander/error_handler_0/setup.cfg +++ b/docs/examples/error_hander/error_handler_0/setup.cfg @@ -37,7 +37,7 @@ package_dir= =src packages=find_namespace: install_requires = - opentelemetry-sdk == 0.13dev0 + opentelemetry-sdk == 0.14.dev0 [options.packages.find] where = src From d846c824c028bf94f6ea077a80569498cdbbc95c Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:17:37 -0600 Subject: [PATCH 24/30] Update docs/examples/error_hander/README.rst Co-authored-by: alrex --- docs/examples/error_hander/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/error_hander/README.rst b/docs/examples/error_hander/README.rst index d21d04452d8..45b3d0bdacd 100644 --- a/docs/examples/error_hander/README.rst +++ b/docs/examples/error_hander/README.rst @@ -82,7 +82,7 @@ places, for example: with GlobalErrorHandler(): {1: 2}[2] -Running that code will raise a ``KeyError`` exception, of course. +Running that code will raise a ``KeyError`` exception. ``GlobalErrorHandler`` will "capture" that exception and pass it down to the registered error handlers. If there is one that handles ``KeyError`` exceptions then it will handle it. That can be seen in the result of the execution of From 21994a1132865e404b3780b953e8b4762b2b4c41 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:18:03 -0600 Subject: [PATCH 25/30] Update docs/examples/error_hander/error_handler_0/setup.cfg Co-authored-by: alrex --- docs/examples/error_hander/error_handler_0/setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/examples/error_hander/error_handler_0/setup.cfg b/docs/examples/error_hander/error_handler_0/setup.cfg index a71b87d3b3e..e59b6afe4c1 100644 --- a/docs/examples/error_hander/error_handler_0/setup.cfg +++ b/docs/examples/error_hander/error_handler_0/setup.cfg @@ -25,7 +25,6 @@ classifiers = License :: OSI Approved :: Apache Software License Programming Language :: Python Programming Language :: Python :: 3 - Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 From d1a5eb6ef79fbfbb7f238a1bdf666160998162e9 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:19:36 -0600 Subject: [PATCH 26/30] Update docs/examples/error_hander/error_handler_1/setup.cfg Co-authored-by: alrex --- docs/examples/error_hander/error_handler_1/setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/error_hander/error_handler_1/setup.cfg b/docs/examples/error_hander/error_handler_1/setup.cfg index 0f2fdedd7d7..e89144a2fac 100644 --- a/docs/examples/error_hander/error_handler_1/setup.cfg +++ b/docs/examples/error_hander/error_handler_1/setup.cfg @@ -31,7 +31,7 @@ classifiers = Programming Language :: Python :: 3.8 [options] -python_requires = >=3.4 +python_requires = >=3.5 package_dir= =src packages=find_namespace: From 9f64488f6a07efd69b11e67fa5c889abf1955934 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 15:19:51 -0600 Subject: [PATCH 27/30] Update docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py Co-authored-by: alrex --- .../error_hander/error_handler_0/src/error_handler_0/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py b/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py index 9cc445d09e1..0f990278982 100644 --- a/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py +++ b/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.13dev0" +__version__ = "0.14.dev0" From 31a880bd0030e071216cd21c05ef664cec53aba2 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 16:24:25 -0600 Subject: [PATCH 28/30] Add READMEs --- docs/examples/error_hander/error_handler_0/README.rst | 4 ++++ docs/examples/error_hander/error_handler_1/README.rst | 4 ++++ scripts/check_for_valid_readme.py | 5 ----- 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 docs/examples/error_hander/error_handler_0/README.rst create mode 100644 docs/examples/error_hander/error_handler_1/README.rst diff --git a/docs/examples/error_hander/error_handler_0/README.rst b/docs/examples/error_hander/error_handler_0/README.rst new file mode 100644 index 00000000000..0c86902e4ca --- /dev/null +++ b/docs/examples/error_hander/error_handler_0/README.rst @@ -0,0 +1,4 @@ +Error Handler 0 +=============== + +This is just an error handler for this example. diff --git a/docs/examples/error_hander/error_handler_1/README.rst b/docs/examples/error_hander/error_handler_1/README.rst new file mode 100644 index 00000000000..029b95f5c0f --- /dev/null +++ b/docs/examples/error_hander/error_handler_1/README.rst @@ -0,0 +1,4 @@ +Error Handler 1 +=============== + +This is just an error handler for this example. diff --git a/scripts/check_for_valid_readme.py b/scripts/check_for_valid_readme.py index e25b318a1f0..7eff0ae582e 100644 --- a/scripts/check_for_valid_readme.py +++ b/scripts/check_for_valid_readme.py @@ -30,11 +30,6 @@ def main(): for path in map(Path, args.paths): - # docs/examples/error_handler includes two Python packages that lack a - # README file. This is intentional so they are skipped here. - if "error_handler" in path.as_posix(): - continue - readme = path / "README.rst" try: if not is_valid_rst(readme): From 6173b48940fecfad0d40fbfb6a75113984240857 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Fri, 25 Sep 2020 16:26:56 -0600 Subject: [PATCH 29/30] Update descriptions --- docs/examples/error_hander/error_handler_0/setup.cfg | 2 +- docs/examples/error_hander/error_handler_1/setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/error_hander/error_handler_0/setup.cfg b/docs/examples/error_hander/error_handler_0/setup.cfg index e59b6afe4c1..61760f5dea1 100644 --- a/docs/examples/error_hander/error_handler_0/setup.cfg +++ b/docs/examples/error_hander/error_handler_0/setup.cfg @@ -14,7 +14,7 @@ # [metadata] name = error-handler-0 -description = Error Handler 0 for OpenTelemetry +description = This is just an error handler example package author = OpenTelemetry Authors author_email = cncf-opentelemetry-contributors@lists.cncf.io platforms = any diff --git a/docs/examples/error_hander/error_handler_1/setup.cfg b/docs/examples/error_hander/error_handler_1/setup.cfg index e89144a2fac..0237f3692e1 100644 --- a/docs/examples/error_hander/error_handler_1/setup.cfg +++ b/docs/examples/error_hander/error_handler_1/setup.cfg @@ -14,7 +14,7 @@ # [metadata] name = error_handler_1 -description = Error Handler 1 for OpenTelemetry +description = This is just an error handler example package author = OpenTelemetry Authors author_email = cncf-opentelemetry-contributors@lists.cncf.io platforms = any From 8a7ea9477728a789ca73c7115a7c25fd9b1c5dcc Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 29 Sep 2020 09:22:23 -0700 Subject: [PATCH 30/30] Update CHANGELOG.md --- opentelemetry-sdk/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 70fa9e00fa0..1688de79b20 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -3,7 +3,7 @@ ## Unreleased - Add Global Error Handler - ([#1079](https://github.com/open-telemetry/opentelemetry-python/pull/1079)) + ([#1080](https://github.com/open-telemetry/opentelemetry-python/pull/1080)) - Update sampling result names ([#1128](https://github.com/open-telemetry/opentelemetry-python/pull/1128)) - Add support for `OTEL_BSP_MAX_QUEUE_SIZE`, `OTEL_BSP_SCHEDULE_DELAY_MILLIS`, `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` and `OTEL_BSP_EXPORT_TIMEOUT_MILLIS` environment variables