diff --git a/instrumentation/opentelemetry-instrumentation-celery/CHANGELOG.md b/instrumentation/opentelemetry-instrumentation-celery/CHANGELOG.md index e164a89134b..da615bcc7b3 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/CHANGELOG.md +++ b/instrumentation/opentelemetry-instrumentation-celery/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Span operation names now include the task type. ([#1135](https://github.com/open-telemetry/opentelemetry-python/pull/1135)) +- Added automatic context propagation. ([#1135](https://github.com/open-telemetry/opentelemetry-python/pull/1135)) + ## Version 0.12b0 Released 2020-08-14 diff --git a/instrumentation/opentelemetry-instrumentation-celery/README.rst b/instrumentation/opentelemetry-instrumentation-celery/README.rst index 42fe6646d1c..307fd352b97 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/README.rst +++ b/instrumentation/opentelemetry-instrumentation-celery/README.rst @@ -29,11 +29,20 @@ Usage .. code-block:: python + from opentelemetry import trace + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import BatchExportSpanProcessor from opentelemetry.instrumentation.celery import CeleryInstrumentor - CeleryInstrumentor().instrument() - from celery import Celery + from celery.signals import worker_process_init + + @worker_process_init.connect(weak=False) + def init_celery_tracing(*args, **kwargs): + trace.set_tracer_provider(TracerProvider()) + span_processor = BatchExportSpanProcessor(ConsoleSpanExporter()) + trace.get_tracer_provider().add_span_processor(span_processor) + CeleryInstrumentor().instrument() app = Celery("tasks", broker="amqp://localhost") @@ -43,6 +52,15 @@ Usage add.delay(42, 50) + +Setting up tracing +-------------------- + +When tracing a celery worker process, tracing and instrumention both must be initialized after the celery worker +process is initialized. This is required for any tracing components that might use threading to work correctly +such as the BatchExportSpanProcessor. Celery provides a signal called ``worker_process_init`` that can be used to +accomplish this as shown in the example above. + References ---------- * `OpenTelemetry Celery Instrumentation `_ diff --git a/instrumentation/opentelemetry-instrumentation-celery/setup.cfg b/instrumentation/opentelemetry-instrumentation-celery/setup.cfg index 79b63d928a9..b5a039de119 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-celery/setup.cfg @@ -46,6 +46,7 @@ install_requires = [options.extras_require] test = pytest + celery ~= 4.0 opentelemetry-test == 0.14.dev0 [options.packages.find] diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py index 7e2551142e4..4768e93d18e 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py @@ -30,11 +30,20 @@ .. code:: python + from opentelemetry import trace + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import BatchExportSpanProcessor from opentelemetry.instrumentation.celery import CeleryInstrumentor - CeleryInstrumentor().instrument() - from celery import Celery + from celery.signals import worker_process_init + + @worker_process_init.connect(weak=False) + def init_celery_tracing(*args, **kwargs): + trace.set_tracer_provider(TracerProvider()) + span_processor = BatchExportSpanProcessor(ConsoleSpanExporter()) + trace.get_tracer_provider().add_span_processor(span_processor) + CeleryInstrumentor().instrument() app = Celery("tasks", broker="amqp://localhost") @@ -50,13 +59,15 @@ def add(x, y): import logging import signal +from collections.abc import Iterable from celery import signals # pylint: disable=no-name-in-module -from opentelemetry import trace +from opentelemetry import propagators, trace from opentelemetry.instrumentation.celery import utils from opentelemetry.instrumentation.celery.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.trace.propagation import get_current_span from opentelemetry.trace.status import Status, StatusCanonicalCode logger = logging.getLogger(__name__) @@ -106,9 +117,16 @@ def _trace_prerun(self, *args, **kwargs): if task is None or task_id is None: return + request = task.request + tracectx = propagators.extract(carrier_extractor, request) or {} + parent = get_current_span(tracectx) + logger.debug("prerun signal start task_id=%s", task_id) - span = self._tracer.start_span(task.name, kind=trace.SpanKind.CONSUMER) + operation_name = "{0}/{1}".format(_TASK_RUN, task.name) + span = self._tracer.start_span( + operation_name, parent=parent, kind=trace.SpanKind.CONSUMER + ) activation = self._tracer.use_span(span, end_on_exit=True) activation.__enter__() @@ -146,7 +164,10 @@ def _trace_before_publish(self, *args, **kwargs): if task is None or task_id is None: return - span = self._tracer.start_span(task.name, kind=trace.SpanKind.PRODUCER) + operation_name = "{0}/{1}".format(_TASK_APPLY_ASYNC, task.name) + span = self._tracer.start_span( + operation_name, kind=trace.SpanKind.PRODUCER + ) # apply some attributes here because most of the data is not available span.set_attribute(_TASK_TAG_KEY, _TASK_APPLY_ASYNC) @@ -158,6 +179,10 @@ def _trace_before_publish(self, *args, **kwargs): activation.__enter__() utils.attach_span(task, task_id, (span, activation), is_publish=True) + headers = kwargs.get("headers") + if headers: + propagators.inject(type(headers).__setitem__, headers) + @staticmethod def _trace_after_publish(*args, **kwargs): task = utils.retrieve_task_from_sender(kwargs) @@ -221,3 +246,10 @@ def _trace_retry(*args, **kwargs): # Use `str(reason)` instead of `reason.message` in case we get # something that isn't an `Exception` span.set_attribute(_TASK_RETRY_REASON_KEY, str(reason)) + + +def carrier_extractor(carrier, key): + value = getattr(carrier, key, []) + if isinstance(value, str) or not isinstance(value, Iterable): + value = (value,) + return value diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py b/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py new file mode 100644 index 00000000000..d9660412f04 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.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 celery import Celery + + +class Config: + result_backend = "rpc" + broker_backend = "memory" + + +app = Celery(broker="memory:///") +app.config_from_object(Config) + + +@app.task +def task_add(num_a, num_b): + return num_a + num_b diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py b/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py new file mode 100644 index 00000000000..3a05ebf331a --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py @@ -0,0 +1,78 @@ +# 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 threading +import time + +from opentelemetry.instrumentation.celery import CeleryInstrumentor +from opentelemetry.test.test_base import TestBase +from opentelemetry.trace import SpanKind + +from .celery_test_tasks import app, task_add + + +class TestCeleryInstrumentation(TestBase): + def setUp(self): + super().setUp() + self._worker = app.Worker(app=app, pool="solo", concurrency=1) + self._thread = threading.Thread(target=self._worker.start) + self._thread.daemon = True + self._thread.start() + + def tearDown(self): + super().tearDown() + self._worker.stop() + self._thread.join() + + def test_task(self): + CeleryInstrumentor().instrument() + + result = task_add.delay(1, 2) + while not result.ready(): + time.sleep(0.05) + + spans = self.sorted_spans(self.memory_exporter.get_finished_spans()) + self.assertEqual(len(spans), 2) + + consumer, producer = spans + + self.assertEqual(consumer.name, "run/tests.celery_test_tasks.task_add") + self.assertEqual(consumer.kind, SpanKind.CONSUMER) + self.assert_span_has_attributes( + consumer, + { + "celery.action": "run", + "celery.state": "SUCCESS", + "messaging.destination": "celery", + "celery.task_name": "tests.celery_test_tasks.task_add", + }, + ) + + self.assertEqual( + producer.name, "apply_async/tests.celery_test_tasks.task_add" + ) + self.assertEqual(producer.kind, SpanKind.PRODUCER) + self.assert_span_has_attributes( + producer, + { + "celery.action": "apply_async", + "celery.task_name": "tests.celery_test_tasks.task_add", + "messaging.destination_kind": "queue", + "messaging.destination": "celery", + }, + ) + + self.assertNotEqual(consumer.parent, producer.context) + self.assertEqual(consumer.parent.span_id, producer.context.span_id) + self.assertEqual(consumer.context.trace_id, producer.context.trace_id) diff --git a/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py b/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py index f18c6cdba14..c4be6762ea0 100644 --- a/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py +++ b/tests/opentelemetry-docker-tests/tests/celery/test_celery_functional.py @@ -46,21 +46,21 @@ def fn_task(): async_span, run_span = spans - assert ( - async_span.instrumentation_info.name - == opentelemetry.instrumentation.celery.__name__ + assert run_span.parent == async_span.context + assert run_span.parent.span_id == async_span.context.span_id + assert run_span.context.trace_id == async_span.context.trace_id + + assert async_span.instrumentation_info.name == "apply_async/{0}".format( + opentelemetry.instrumentation.celery.__name__ ) - assert ( - async_span.instrumentation_info.version - == opentelemetry.instrumentation.celery.__version__ + assert async_span.instrumentation_info.version == "apply_async/{0}".format( + opentelemetry.instrumentation.celery.__version__ ) - assert ( - run_span.instrumentation_info.name - == opentelemetry.instrumentation.celery.__name__ + assert run_span.instrumentation_info.name == "run/{0}".format( + opentelemetry.instrumentation.celery.__name__ ) - assert ( - run_span.instrumentation_info.version - == opentelemetry.instrumentation.celery.__version__ + assert run_span.instrumentation_info.version == "run/{0}".format( + opentelemetry.instrumentation.celery.__version__ ) @@ -103,7 +103,7 @@ def fn_task(): span = spans[0] assert span.status.is_ok is True - assert span.name == "test_celery_functional.fn_task" + assert span.name == "run/test_celery_functional.fn_task" assert span.attributes.get("messaging.message_id") == t.task_id assert ( span.attributes.get("celery.task_name") @@ -128,7 +128,7 @@ def fn_task(self): span = spans[0] assert span.status.is_ok is True - assert span.name == "test_celery_functional.fn_task" + assert span.name == "run/test_celery_functional.fn_task" assert span.attributes.get("messaging.message_id") == t.task_id assert ( span.attributes.get("celery.task_name") @@ -157,7 +157,10 @@ def fn_task_parameters(user, force_logout=False): assert run_span.context.trace_id != async_span.context.trace_id assert async_span.status.is_ok is True - assert async_span.name == "test_celery_functional.fn_task_parameters" + assert ( + async_span.name + == "apply_async/test_celery_functional.fn_task_parameters" + ) assert async_span.attributes.get("celery.action") == "apply_async" assert async_span.attributes.get("messaging.message_id") == result.task_id assert ( @@ -209,7 +212,10 @@ def fn_task_parameters(user, force_logout=False): assert run_span.context.trace_id != async_span.context.trace_id assert async_span.status.is_ok is True - assert async_span.name == "test_celery_functional.fn_task_parameters" + assert ( + async_span.name + == "apply_async/test_celery_functional.fn_task_parameters" + ) assert async_span.attributes.get("celery.action") == "apply_async" assert async_span.attributes.get("messaging.message_id") == result.task_id assert ( @@ -218,7 +224,7 @@ def fn_task_parameters(user, force_logout=False): ) assert run_span.status.is_ok is True - assert run_span.name == "test_celery_functional.fn_task_parameters" + assert run_span.name == "run/test_celery_functional.fn_task_parameters" assert run_span.attributes.get("celery.action") == "run" assert run_span.attributes.get("celery.state") == "SUCCESS" assert run_span.attributes.get("messaging.message_id") == result.task_id @@ -244,7 +250,7 @@ def fn_exception(): span = spans[0] assert span.status.is_ok is False - assert span.name == "test_celery_functional.fn_exception" + assert span.name == "run/test_celery_functional.fn_exception" assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "FAILURE" assert ( @@ -273,7 +279,7 @@ def fn_exception(): assert span.status.is_ok is True assert span.status.canonical_code == StatusCanonicalCode.OK - assert span.name == "test_celery_functional.fn_exception" + assert span.name == "run/test_celery_functional.fn_exception" assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "FAILURE" assert ( @@ -300,7 +306,7 @@ def fn_exception(): assert span.status.is_ok is True assert span.status.canonical_code == StatusCanonicalCode.OK - assert span.name == "test_celery_functional.fn_exception" + assert span.name == "run/test_celery_functional.fn_exception" assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "RETRY" assert ( @@ -332,7 +338,7 @@ def run(self): span = spans[0] assert span.status.is_ok is True - assert span.name == "test_celery_functional.BaseTask" + assert span.name == "run/test_celery_functional.BaseTask" assert ( span.attributes.get("celery.task_name") == "test_celery_functional.BaseTask" @@ -364,7 +370,7 @@ def run(self): span = spans[0] assert span.status.is_ok is False - assert span.name == "test_celery_functional.BaseTask" + assert span.name == "run/test_celery_functional.BaseTask" assert ( span.attributes.get("celery.task_name") == "test_celery_functional.BaseTask" @@ -401,7 +407,7 @@ def run(self): assert span.status.is_ok is True assert span.status.canonical_code == StatusCanonicalCode.OK - assert span.name == "test_celery_functional.BaseTask" + assert span.name == "run/test_celery_functional.BaseTask" assert span.attributes.get("celery.action") == "run" assert span.attributes.get("celery.state") == "FAILURE" assert span.attributes.get("messaging.message_id") == result.task_id @@ -423,7 +429,7 @@ def add(x, y): span = spans[0] assert span.status.is_ok is True - assert span.name == "test_celery_functional.add" + assert span.name == "run/test_celery_functional.add" assert ( span.attributes.get("celery.task_name") == "test_celery_functional.add" ) @@ -471,7 +477,7 @@ class CelerySubClass(CelerySuperClass): async_span, async_run_span, run_span = spans assert run_span.status.is_ok is True - assert run_span.name == "test_celery_functional.CelerySubClass" + assert run_span.name == "run/test_celery_functional.CelerySubClass" assert ( run_span.attributes.get("celery.task_name") == "test_celery_functional.CelerySubClass" @@ -481,7 +487,7 @@ class CelerySubClass(CelerySuperClass): assert run_span.attributes.get("messaging.message_id") == result.task_id assert async_run_span.status.is_ok is True - assert async_run_span.name == "test_celery_functional.CelerySubClass" + assert async_run_span.name == "run/test_celery_functional.CelerySubClass" assert ( async_run_span.attributes.get("celery.task_name") == "test_celery_functional.CelerySubClass" @@ -493,7 +499,9 @@ class CelerySubClass(CelerySuperClass): ) assert async_span.status.is_ok is True - assert async_span.name == "test_celery_functional.CelerySubClass" + assert ( + async_span.name == "apply_async/test_celery_functional.CelerySubClass" + ) assert ( async_span.attributes.get("celery.task_name") == "test_celery_functional.CelerySubClass" diff --git a/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py b/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py index 4116f4a19e5..5be0be9f0ec 100644 --- a/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py +++ b/tests/opentelemetry-docker-tests/tests/mysql/test_mysql_functional.py @@ -75,15 +75,13 @@ def validate_spans(self): self.assertEqual(db_span.attributes["net.peer.port"], MYSQL_PORT) def test_execute(self): - """Should create a child span for execute - """ + """Should create a child span for execute""" with self._tracer.start_as_current_span("rootSpan"): self._cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") self.validate_spans() def test_execute_with_connection_context_manager(self): - """Should create a child span for execute with connection context - """ + """Should create a child span for execute with connection context""" with self._tracer.start_as_current_span("rootSpan"): with self._connection as conn: cursor = conn.cursor() @@ -91,16 +89,14 @@ def test_execute_with_connection_context_manager(self): self.validate_spans() def test_execute_with_cursor_context_manager(self): - """Should create a child span for execute with cursor context - """ + """Should create a child span for execute with cursor context""" with self._tracer.start_as_current_span("rootSpan"): with self._connection.cursor() as cursor: cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") self.validate_spans() def test_executemany(self): - """Should create a child span for executemany - """ + """Should create a child span for executemany""" with self._tracer.start_as_current_span("rootSpan"): data = (("1",), ("2",), ("3",)) stmt = "INSERT INTO test (id) VALUES (%s)" @@ -108,8 +104,7 @@ def test_executemany(self): self.validate_spans() def test_callproc(self): - """Should create a child span for callproc - """ + """Should create a child span for callproc""" with self._tracer.start_as_current_span("rootSpan"), self.assertRaises( Exception ): diff --git a/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py b/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py index 9eb209636d9..e7a0d39b51e 100644 --- a/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py +++ b/tests/opentelemetry-docker-tests/tests/postgres/test_aiopg_functional.py @@ -85,8 +85,7 @@ def validate_spans(self): self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT) def test_execute(self): - """Should create a child span for execute method - """ + """Should create a child span for execute method""" with self._tracer.start_as_current_span("rootSpan"): async_call( self._cursor.execute( @@ -96,8 +95,7 @@ def test_execute(self): self.validate_spans() def test_executemany(self): - """Should create a child span for executemany - """ + """Should create a child span for executemany""" with pytest.raises(psycopg2.ProgrammingError): with self._tracer.start_as_current_span("rootSpan"): data = (("1",), ("2",), ("3",)) @@ -106,8 +104,7 @@ def test_executemany(self): self.validate_spans() def test_callproc(self): - """Should create a child span for callproc - """ + """Should create a child span for callproc""" with self._tracer.start_as_current_span("rootSpan"), self.assertRaises( Exception ): @@ -169,8 +166,7 @@ def validate_spans(self): self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT) def test_execute(self): - """Should create a child span for execute method - """ + """Should create a child span for execute method""" with self._tracer.start_as_current_span("rootSpan"): async_call( self._cursor.execute( @@ -180,8 +176,7 @@ def test_execute(self): self.validate_spans() def test_executemany(self): - """Should create a child span for executemany - """ + """Should create a child span for executemany""" with pytest.raises(psycopg2.ProgrammingError): with self._tracer.start_as_current_span("rootSpan"): data = (("1",), ("2",), ("3",)) @@ -190,8 +185,7 @@ def test_executemany(self): self.validate_spans() def test_callproc(self): - """Should create a child span for callproc - """ + """Should create a child span for callproc""" with self._tracer.start_as_current_span("rootSpan"), self.assertRaises( Exception ): diff --git a/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py b/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py index 8a703b00944..27391647818 100644 --- a/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py +++ b/tests/opentelemetry-docker-tests/tests/postgres/test_psycopg_functional.py @@ -77,8 +77,7 @@ def validate_spans(self): self.assertEqual(child_span.attributes["net.peer.port"], POSTGRES_PORT) def test_execute(self): - """Should create a child span for execute method - """ + """Should create a child span for execute method""" with self._tracer.start_as_current_span("rootSpan"): self._cursor.execute( "CREATE TABLE IF NOT EXISTS test (id integer)" @@ -86,8 +85,7 @@ def test_execute(self): self.validate_spans() def test_execute_with_connection_context_manager(self): - """Should create a child span for execute with connection context - """ + """Should create a child span for execute with connection context""" with self._tracer.start_as_current_span("rootSpan"): with self._connection as conn: cursor = conn.cursor() @@ -95,8 +93,7 @@ def test_execute_with_connection_context_manager(self): self.validate_spans() def test_execute_with_cursor_context_manager(self): - """Should create a child span for execute with cursor context - """ + """Should create a child span for execute with cursor context""" with self._tracer.start_as_current_span("rootSpan"): with self._connection.cursor() as cursor: cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") @@ -104,8 +101,7 @@ def test_execute_with_cursor_context_manager(self): self.assertTrue(cursor.closed) def test_executemany(self): - """Should create a child span for executemany - """ + """Should create a child span for executemany""" with self._tracer.start_as_current_span("rootSpan"): data = (("1",), ("2",), ("3",)) stmt = "INSERT INTO test (id) VALUES (%s)" @@ -113,8 +109,7 @@ def test_executemany(self): self.validate_spans() def test_callproc(self): - """Should create a child span for callproc - """ + """Should create a child span for callproc""" with self._tracer.start_as_current_span("rootSpan"), self.assertRaises( Exception ): diff --git a/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py b/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py index 8c52ad06564..acb60178d06 100644 --- a/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py +++ b/tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py @@ -64,8 +64,7 @@ def validate_spans(self): ) def test_insert(self): - """Should create a child span for insert - """ + """Should create a child span for insert""" with self._tracer.start_as_current_span("rootSpan"): self._collection.insert_one( {"name": "testName", "value": "testValue"} @@ -73,8 +72,7 @@ def test_insert(self): self.validate_spans() def test_update(self): - """Should create a child span for update - """ + """Should create a child span for update""" with self._tracer.start_as_current_span("rootSpan"): self._collection.update_one( {"name": "testName"}, {"$set": {"value": "someOtherValue"}} @@ -82,15 +80,13 @@ def test_update(self): self.validate_spans() def test_find(self): - """Should create a child span for find - """ + """Should create a child span for find""" with self._tracer.start_as_current_span("rootSpan"): self._collection.find_one() self.validate_spans() def test_delete(self): - """Should create a child span for delete - """ + """Should create a child span for delete""" with self._tracer.start_as_current_span("rootSpan"): self._collection.delete_one({"name": "testName"}) self.validate_spans() diff --git a/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py b/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py index 7b0cb5b0c03..c5c4d4f4497 100644 --- a/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py +++ b/tests/opentelemetry-docker-tests/tests/pymysql/test_pymysql_functional.py @@ -72,23 +72,20 @@ def validate_spans(self): self.assertEqual(db_span.attributes["net.peer.port"], MYSQL_PORT) def test_execute(self): - """Should create a child span for execute - """ + """Should create a child span for execute""" with self._tracer.start_as_current_span("rootSpan"): self._cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") self.validate_spans() def test_execute_with_cursor_context_manager(self): - """Should create a child span for execute with cursor context - """ + """Should create a child span for execute with cursor context""" with self._tracer.start_as_current_span("rootSpan"): with self._connection.cursor() as cursor: cursor.execute("CREATE TABLE IF NOT EXISTS test (id INT)") self.validate_spans() def test_executemany(self): - """Should create a child span for executemany - """ + """Should create a child span for executemany""" with self._tracer.start_as_current_span("rootSpan"): data = (("1",), ("2",), ("3",)) stmt = "INSERT INTO test (id) VALUES (%s)" @@ -96,8 +93,7 @@ def test_executemany(self): self.validate_spans() def test_callproc(self): - """Should create a child span for callproc - """ + """Should create a child span for callproc""" with self._tracer.start_as_current_span("rootSpan"), self.assertRaises( Exception ):