From 079dc181f822985da653dae8ddb18411da90a017 Mon Sep 17 00:00:00 2001 From: Eugene Orlovsky Date: Fri, 29 Nov 2024 10:02:25 +0100 Subject: [PATCH 1/2] create_programmatic_error --- README.md | 10 ++++---- src/lumigo_opentelemetry/__init__.py | 7 ++++++ src/test/unit/test_tracer.py | 34 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 37e380a8..e6397507 100644 --- a/README.md +++ b/README.md @@ -202,16 +202,18 @@ Programmatic Errors indicating that a non-fatal error occurred, such as an appli #### Creating a Programmatic Error -Programmatic errors are created by adding [span events](https://opentelemetry.io/docs/instrumentation/python/manual/#adding-events) with a custom attribute being set with the key name `lumigo.type`. +Programmatic errors can now be created easily using the `create_programmatic_error` function provided by the `lumigo_opentelemetry` package. This allows you to capture and report errors with minimal setup, without requiring direct interaction with the OpenTelemetry trace SDK. -For example, you could add a programmatic error as follows: +For example, you can add a programmatic error as follows: ```python -from opentelemetry.trace import get_current_span +from lumigo_opentelemetry import create_programmatic_error -get_current_span().add_event('', {'lumigo.type': ''}) +create_programmatic_error("Error message", "ErrorType") ``` +The first argument, "Error message", is a descriptive message for the error, while the second argument, "ErrorType", represents the type of the error. + ## Python 3.7 Support **Deprecation Notice:** As of version 1.0.156, support for Python 3.7 has been deprecated. The last version of the Lumigo OpenTelemetry Distro to support Python 3.7 is version 1.0.155. diff --git a/src/lumigo_opentelemetry/__init__.py b/src/lumigo_opentelemetry/__init__.py index 8dfce10c..71e3c36c 100644 --- a/src/lumigo_opentelemetry/__init__.py +++ b/src/lumigo_opentelemetry/__init__.py @@ -296,6 +296,12 @@ def wrapper(*args: List[Any], **kwargs: Dict[Any, Any]) -> T: return wrapper +def create_programmatic_error(error_message: str, error_type: str) -> None: + from opentelemetry.trace import get_current_span + + get_current_span().add_event(error_message, {"lumigo.type": error_type}) + + # Load the package on import init_data = init() @@ -309,4 +315,5 @@ def wrapper(*args: List[Any], **kwargs: Dict[Any, Any]) -> T: "logger", "tracer_provider", "logger_provider", + "create_programmatic_error", ] diff --git a/src/test/unit/test_tracer.py b/src/test/unit/test_tracer.py index 4fa81c8e..876d334a 100644 --- a/src/test/unit/test_tracer.py +++ b/src/test/unit/test_tracer.py @@ -9,6 +9,8 @@ from json import loads from os import environ +from opentelemetry.sdk.trace import SpanProcessor + from lumigo_opentelemetry import init @@ -147,3 +149,35 @@ def test_python_version_too_new(self): "Unsupported Python version 3.13; only Python 3.8 to 3.12 are supported.", cm.output[0], ) + + +class TestCreateProgrammaticError(unittest.TestCase): + @httpretty.activate(allow_net_connect=False) + def test_create_event_with_correct_attributes(self): + from lumigo_opentelemetry import create_programmatic_error, tracer_provider + + self.assertIsNotNone(create_programmatic_error) + + span_processor = Mock(SpanProcessor) + tracer_provider.add_span_processor(span_processor) + + tracer = tracer_provider.get_tracer(__name__) + with tracer.start_as_current_span("Root") as span: + create_programmatic_error("Error message", "ErrorType") + + # Verify `on_start` was called + span_processor.on_start.assert_called() + + # Capture the span passed to `on_start` + span = span_processor.on_start.call_args[0][ + 0 + ] # Extract the `span` argument from the first call + + events = span.events + # Verify the event was added + self.assertEqual(len(events), 1) + + event = events[0] + # Verify the event has the correct attributes + self.assertEqual(event.name, "Error message") + self.assertEqual(event.attributes["lumigo.type"], "ErrorType") From d91ea110bad7829e494eed3b794b0c0b81194058 Mon Sep 17 00:00:00 2001 From: Eugene Orlovsky Date: Mon, 2 Dec 2024 09:10:22 +0100 Subject: [PATCH 2/2] README.md updated, --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6397507..65ba8f51 100644 --- a/README.md +++ b/README.md @@ -209,11 +209,21 @@ For example, you can add a programmatic error as follows: ```python from lumigo_opentelemetry import create_programmatic_error -create_programmatic_error("Error message", "ErrorType") +create_programmatic_error("The customer 123 was not found", "CustomerNotExist") ``` The first argument, "Error message", is a descriptive message for the error, while the second argument, "ErrorType", represents the type of the error. +Alternately, programmatic errors can also be created by adding [span events](https://opentelemetry.io/docs/instrumentation/python/manual/#adding-events) with a custom attribute being set with the key name `lumigo.type`. + +For example, you could add a programmatic error as follows: + +```python +from opentelemetry.trace import get_current_span + +get_current_span().add_event('', {'lumigo.type': ''}) +``` + ## Python 3.7 Support **Deprecation Notice:** As of version 1.0.156, support for Python 3.7 has been deprecated. The last version of the Lumigo OpenTelemetry Distro to support Python 3.7 is version 1.0.155.