|
| 1 | +Global Error Handler |
| 2 | +==================== |
| 3 | + |
| 4 | +Overview |
| 5 | +-------- |
| 6 | + |
| 7 | +This example shows how to use the global error handler. |
| 8 | + |
| 9 | + |
| 10 | +Preparation |
| 11 | +----------- |
| 12 | + |
| 13 | +This example will be executed in a separate virtual environment: |
| 14 | + |
| 15 | +.. code:: sh |
| 16 | +
|
| 17 | + $ mkdir global_error_handler |
| 18 | + $ virtualenv global_error_handler |
| 19 | + $ source global_error_handler/bin/activate |
| 20 | +
|
| 21 | +Installation |
| 22 | +------------ |
| 23 | + |
| 24 | +Here we install first ``opentelemetry-sdk``, the only dependency. Afterwards, 2 |
| 25 | +error handlers are installed: ``error_handler_0`` will handle |
| 26 | +``ZeroDivisionError`` exceptions, ``error_handler_1`` will handle |
| 27 | +``IndexError`` and ``KeyError`` exceptions. |
| 28 | + |
| 29 | +.. code:: sh |
| 30 | +
|
| 31 | + $ pip install opentelemetry-sdk |
| 32 | + $ git clone https://github.com/open-telemetry/opentelemetry-python.git |
| 33 | + $ pip install -e opentelemetry-python/docs/examples/error_handler/error_handler_0 |
| 34 | + $ pip install -e opentelemetry-python/docs/examples/error_handler/error_handler_1 |
| 35 | +
|
| 36 | +Execution |
| 37 | +--------- |
| 38 | + |
| 39 | +An example is provided in the |
| 40 | +``opentelemetry-python/docs/examples/error_handler/example.py``. |
| 41 | + |
| 42 | +You can just run it, you should get output similar to this one: |
| 43 | + |
| 44 | +.. code:: pytb |
| 45 | +
|
| 46 | + ErrorHandler0 handling a ZeroDivisionError |
| 47 | + Traceback (most recent call last): |
| 48 | + File "test.py", line 5, in <module> |
| 49 | + 1 / 0 |
| 50 | + ZeroDivisionError: division by zero |
| 51 | +
|
| 52 | + ErrorHandler1 handling an IndexError |
| 53 | + Traceback (most recent call last): |
| 54 | + File "test.py", line 11, in <module> |
| 55 | + [1][2] |
| 56 | + IndexError: list index out of range |
| 57 | +
|
| 58 | + ErrorHandler1 handling a KeyError |
| 59 | + Traceback (most recent call last): |
| 60 | + File "test.py", line 17, in <module> |
| 61 | + {1: 2}[2] |
| 62 | + KeyError: 2 |
| 63 | +
|
| 64 | + Error handled by default error handler: |
| 65 | + Traceback (most recent call last): |
| 66 | + File "test.py", line 23, in <module> |
| 67 | + assert False |
| 68 | + AssertionError |
| 69 | +
|
| 70 | + No error raised |
| 71 | +
|
| 72 | +The ``opentelemetry-sdk.error_handler`` module includes documentation that |
| 73 | +explains how this works. We recommend you read it also, here is just a small |
| 74 | +summary. |
| 75 | + |
| 76 | +In ``example.py`` we use ``GlobalErrorHandler`` as a context manager in several |
| 77 | +places, for example: |
| 78 | + |
| 79 | + |
| 80 | +.. code:: python |
| 81 | +
|
| 82 | + with GlobalErrorHandler(): |
| 83 | + {1: 2}[2] |
| 84 | +
|
| 85 | +Running that code will raise a ``KeyError`` exception. |
| 86 | +``GlobalErrorHandler`` will "capture" that exception and pass it down to the |
| 87 | +registered error handlers. If there is one that handles ``KeyError`` exceptions |
| 88 | +then it will handle it. That can be seen in the result of the execution of |
| 89 | +``example.py``: |
| 90 | + |
| 91 | +.. code:: |
| 92 | +
|
| 93 | + ErrorHandler1 handling a KeyError |
| 94 | + Traceback (most recent call last): |
| 95 | + File "test.py", line 17, in <module> |
| 96 | + {1: 2}[2] |
| 97 | + KeyError: 2 |
| 98 | +
|
| 99 | +There is no registered error handler that can handle ``AssertionError`` |
| 100 | +exceptions so this kind of errors are handled by the default error handler |
| 101 | +which just logs the exception to standard logging, as seen here: |
| 102 | + |
| 103 | +.. code:: |
| 104 | +
|
| 105 | + Error handled by default error handler: |
| 106 | + Traceback (most recent call last): |
| 107 | + File "test.py", line 23, in <module> |
| 108 | + assert False |
| 109 | + AssertionError |
| 110 | +
|
| 111 | +When no exception is raised, the code inside the scope of |
| 112 | +``GlobalErrorHandler`` is exectued normally: |
| 113 | + |
| 114 | +.. code:: |
| 115 | +
|
| 116 | + No error raised |
| 117 | +
|
| 118 | +Users can create Python packages that provide their own custom error handlers |
| 119 | +and install them in their virtual environments before running their code which |
| 120 | +instantiates ``GlobalErrorHandler`` context managers. ``error_handler_0`` and |
| 121 | +``error_handler_1`` can be used as examples to create these custom error |
| 122 | +handlers. |
| 123 | + |
| 124 | +In order for the error handlers to be registered, they need to create a class |
| 125 | +that inherits from ``opentelemetry.sdk.error_handler.ErrorHandler`` and at |
| 126 | +least one ``Exception``-type class. For example, this is an error handler that |
| 127 | +handles ``ZeroDivisionError`` exceptions: |
| 128 | + |
| 129 | +.. code:: python |
| 130 | +
|
| 131 | + from opentelemetry.sdk.error_handler import ErrorHandler |
| 132 | + from logging import getLogger |
| 133 | +
|
| 134 | + logger = getLogger(__name__) |
| 135 | +
|
| 136 | +
|
| 137 | + class ErrorHandler0(ErrorHandler, ZeroDivisionError): |
| 138 | +
|
| 139 | + def handle(self, error: Exception, *args, **kwargs): |
| 140 | +
|
| 141 | + logger.exception("ErrorHandler0 handling a ZeroDivisionError") |
| 142 | +
|
| 143 | +To register this error handler, use the ``opentelemetry_error_handler`` entry |
| 144 | +point in the setup of the error handler package: |
| 145 | + |
| 146 | +.. code:: |
| 147 | +
|
| 148 | + [options.entry_points] |
| 149 | + opentelemetry_error_handler = |
| 150 | + error_handler_0 = error_handler_0:ErrorHandler0 |
| 151 | +
|
| 152 | +This entry point should point to the error handler class, ``ErrorHandler0`` in |
| 153 | +this case. |
0 commit comments