diff --git a/.ci/.matrix_framework.yml b/.ci/.matrix_framework.yml index b86e51d01..1ece9a68a 100644 --- a/.ci/.matrix_framework.yml +++ b/.ci/.matrix_framework.yml @@ -12,7 +12,6 @@ FRAMEWORK: - flask-3.0 - jinja2-3 - opentelemetry-newest - - opentracing-newest - twisted-newest - celery-5-flask-2 - celery-5-django-4 diff --git a/.ci/.matrix_framework_fips.yml b/.ci/.matrix_framework_fips.yml index 6bbc9cd3e..0c733de80 100644 --- a/.ci/.matrix_framework_fips.yml +++ b/.ci/.matrix_framework_fips.yml @@ -6,7 +6,6 @@ FRAMEWORK: - flask-3.0 - jinja2-3 - opentelemetry-newest - - opentracing-newest - twisted-newest - celery-5-flask-2 - celery-5-django-5 diff --git a/.ci/.matrix_framework_full.yml b/.ci/.matrix_framework_full.yml index 54fc7f19a..b1fbeaa58 100644 --- a/.ci/.matrix_framework_full.yml +++ b/.ci/.matrix_framework_full.yml @@ -30,8 +30,6 @@ FRAMEWORK: - celery-5-django-4 - celery-5-django-5 - opentelemetry-newest - - opentracing-newest - - opentracing-2.0 - twisted-newest - twisted-18 - twisted-17 diff --git a/elasticapm/contrib/opentracing/__init__.py b/elasticapm/contrib/opentracing/__init__.py deleted file mode 100644 index 71619ea20..000000000 --- a/elasticapm/contrib/opentracing/__init__.py +++ /dev/null @@ -1,43 +0,0 @@ -# BSD 3-Clause License -# -# Copyright (c) 2019, Elasticsearch BV -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import warnings - -from .span import OTSpan # noqa: F401 -from .tracer import Tracer # noqa: F401 - -warnings.warn( - ( - "The OpenTracing bridge is deprecated and will be removed in the next major release. " - "Please migrate to the OpenTelemetry bridge." - ), - DeprecationWarning, -) diff --git a/elasticapm/contrib/opentracing/span.py b/elasticapm/contrib/opentracing/span.py deleted file mode 100644 index 6bc00fec5..000000000 --- a/elasticapm/contrib/opentracing/span.py +++ /dev/null @@ -1,136 +0,0 @@ -# BSD 3-Clause License -# -# Copyright (c) 2019, Elasticsearch BV -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from opentracing.span import Span as OTSpanBase -from opentracing.span import SpanContext as OTSpanContextBase - -from elasticapm import traces -from elasticapm.utils import get_url_dict -from elasticapm.utils.logging import get_logger - -try: - # opentracing-python 2.1+ - from opentracing import logs as ot_logs - from opentracing import tags -except ImportError: - # opentracing-python <2.1 - from opentracing.ext import tags - - ot_logs = None - - -logger = get_logger("elasticapm.contrib.opentracing") - - -class OTSpan(OTSpanBase): - def __init__(self, tracer, context, elastic_apm_ref) -> None: - super(OTSpan, self).__init__(tracer, context) - self.elastic_apm_ref = elastic_apm_ref - self.is_transaction = isinstance(elastic_apm_ref, traces.Transaction) - self.is_dropped = isinstance(elastic_apm_ref, traces.DroppedSpan) - if not context.span: - context.span = self - - def log_kv(self, key_values, timestamp=None): - exc_type, exc_val, exc_tb = None, None, None - if "python.exception.type" in key_values: - exc_type = key_values["python.exception.type"] - exc_val = key_values.get("python.exception.val") - exc_tb = key_values.get("python.exception.tb") - elif ot_logs and key_values.get(ot_logs.EVENT) == tags.ERROR: - exc_type = key_values[ot_logs.ERROR_KIND] - exc_val = key_values.get(ot_logs.ERROR_OBJECT) - exc_tb = key_values.get(ot_logs.STACK) - else: - logger.debug("Can't handle non-exception type opentracing logs") - if exc_type: - agent = self.tracer._agent - agent.capture_exception(exc_info=(exc_type, exc_val, exc_tb)) - return self - - def set_operation_name(self, operation_name): - self.elastic_apm_ref.name = operation_name - return self - - def set_tag(self, key, value): - if self.is_transaction: - if key == "type": - self.elastic_apm_ref.transaction_type = value - elif key == "result": - self.elastic_apm_ref.result = value - elif key == tags.HTTP_STATUS_CODE: - self.elastic_apm_ref.result = "HTTP {}xx".format(str(value)[0]) - traces.set_context({"status_code": value}, "response") - elif key == "user.id": - traces.set_user_context(user_id=value) - elif key == "user.username": - traces.set_user_context(username=value) - elif key == "user.email": - traces.set_user_context(email=value) - elif key == tags.HTTP_URL: - traces.set_context({"url": get_url_dict(value)}, "request") - elif key == tags.HTTP_METHOD: - traces.set_context({"method": value}, "request") - elif key == tags.COMPONENT: - traces.set_context({"framework": {"name": value}}, "service") - else: - self.elastic_apm_ref.label(**{key: value}) - elif not self.is_dropped: - if key.startswith("db."): - span_context = self.elastic_apm_ref.context or {} - if "db" not in span_context: - span_context["db"] = {} - if key == tags.DATABASE_STATEMENT: - span_context["db"]["statement"] = value - elif key == tags.DATABASE_USER: - span_context["db"]["user"] = value - elif key == tags.DATABASE_TYPE: - span_context["db"]["type"] = value - self.elastic_apm_ref.type = "db." + value - else: - self.elastic_apm_ref.label(**{key: value}) - self.elastic_apm_ref.context = span_context - elif key == tags.SPAN_KIND: - self.elastic_apm_ref.type = value - else: - self.elastic_apm_ref.label(**{key: value}) - return self - - def finish(self, finish_time=None) -> None: - if self.is_transaction: - self.tracer._agent.end_transaction() - elif not self.is_dropped: - self.elastic_apm_ref.transaction.end_span() - - -class OTSpanContext(OTSpanContextBase): - def __init__(self, trace_parent, span=None) -> None: - self.trace_parent = trace_parent - self.span = span diff --git a/elasticapm/contrib/opentracing/tracer.py b/elasticapm/contrib/opentracing/tracer.py deleted file mode 100644 index d331735f6..000000000 --- a/elasticapm/contrib/opentracing/tracer.py +++ /dev/null @@ -1,131 +0,0 @@ -# BSD 3-Clause License -# -# Copyright (c) 2019, Elasticsearch BV -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import warnings - -from opentracing import Format, InvalidCarrierException, SpanContextCorruptedException, UnsupportedFormatException -from opentracing.scope_managers import ThreadLocalScopeManager -from opentracing.tracer import ReferenceType -from opentracing.tracer import Tracer as TracerBase - -import elasticapm -from elasticapm import get_client, instrument, traces -from elasticapm.conf import constants -from elasticapm.contrib.opentracing.span import OTSpan, OTSpanContext -from elasticapm.utils import disttracing - - -class Tracer(TracerBase): - def __init__(self, client_instance=None, config=None, scope_manager=None) -> None: - self._agent = client_instance or get_client() or elasticapm.Client(config=config) - if scope_manager and not isinstance(scope_manager, ThreadLocalScopeManager): - warnings.warn( - "Currently, the Elastic APM opentracing bridge only supports the ThreadLocalScopeManager. " - "Usage of other scope managers will lead to unpredictable results." - ) - self._scope_manager = scope_manager or ThreadLocalScopeManager() - if self._agent.config.instrument and self._agent.config.enabled: - instrument() - - def start_active_span( - self, - operation_name, - child_of=None, - references=None, - tags=None, - start_time=None, - ignore_active_span=False, - finish_on_close=True, - ): - ot_span = self.start_span( - operation_name, - child_of=child_of, - references=references, - tags=tags, - start_time=start_time, - ignore_active_span=ignore_active_span, - ) - scope = self._scope_manager.activate(ot_span, finish_on_close) - return scope - - def start_span( - self, operation_name=None, child_of=None, references=None, tags=None, start_time=None, ignore_active_span=False - ): - if isinstance(child_of, OTSpanContext): - parent_context = child_of - elif isinstance(child_of, OTSpan): - parent_context = child_of.context - elif references and references[0].type == ReferenceType.CHILD_OF: - parent_context = references[0].referenced_context - else: - parent_context = None - transaction = traces.execution_context.get_transaction() - if not transaction: - trace_parent = parent_context.trace_parent if parent_context else None - transaction = self._agent.begin_transaction("custom", trace_parent=trace_parent) - transaction.name = operation_name - span_context = OTSpanContext(trace_parent=transaction.trace_parent) - ot_span = OTSpan(self, span_context, transaction) - else: - # to allow setting an explicit parent span, we check if the parent_context is set - # and if it is a span. In all other cases, the parent is found implicitly through the - # execution context. - parent_span_id = ( - parent_context.span.elastic_apm_ref.id - if parent_context and parent_context.span and not parent_context.span.is_transaction - else None - ) - span = transaction._begin_span(operation_name, None, parent_span_id=parent_span_id) - trace_parent = parent_context.trace_parent if parent_context else transaction.trace_parent - span_context = OTSpanContext(trace_parent=trace_parent.copy_from(span_id=span.id)) - ot_span = OTSpan(self, span_context, span) - if tags: - for k, v in tags.items(): - ot_span.set_tag(k, v) - return ot_span - - def extract(self, format, carrier): - if format in (Format.HTTP_HEADERS, Format.TEXT_MAP): - trace_parent = disttracing.TraceParent.from_headers(carrier) - if not trace_parent: - raise SpanContextCorruptedException("could not extract span context from carrier") - return OTSpanContext(trace_parent=trace_parent) - raise UnsupportedFormatException - - def inject(self, span_context, format, carrier): - if format in (Format.HTTP_HEADERS, Format.TEXT_MAP): - if not isinstance(carrier, dict): - raise InvalidCarrierException("carrier for {} format should be dict-like".format(format)) - val = span_context.trace_parent.to_ascii() - carrier[constants.TRACEPARENT_HEADER_NAME] = val - if self._agent.config.use_elastic_traceparent_header: - carrier[constants.TRACEPARENT_LEGACY_HEADER_NAME] = val - return - raise UnsupportedFormatException diff --git a/setup.cfg b/setup.cfg index 5a29c245f..fc4d8be79 100644 --- a/setup.cfg +++ b/setup.cfg @@ -56,8 +56,6 @@ tornado = tornado starlette = starlette -opentracing = - opentracing>=2.0.0 sanic = sanic opentelemetry = @@ -82,7 +80,6 @@ markers = gevent eventlet celery - opentracing cassandra psycopg2 mongodb diff --git a/tests/contrib/opentracing/__init__.py b/tests/contrib/opentracing/__init__.py deleted file mode 100644 index 7e2b340e6..000000000 --- a/tests/contrib/opentracing/__init__.py +++ /dev/null @@ -1,29 +0,0 @@ -# BSD 3-Clause License -# -# Copyright (c) 2019, Elasticsearch BV -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tests/contrib/opentracing/tests.py b/tests/contrib/opentracing/tests.py deleted file mode 100644 index 50970c269..000000000 --- a/tests/contrib/opentracing/tests.py +++ /dev/null @@ -1,313 +0,0 @@ -# BSD 3-Clause License -# -# Copyright (c) 2019, Elasticsearch BV -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from datetime import timedelta - -import pytest # isort:skip - -opentracing = pytest.importorskip("opentracing") # isort:skip - -import sys - -import mock -from opentracing import Format - -import elasticapm -from elasticapm.conf import constants -from elasticapm.contrib.opentracing import Tracer -from elasticapm.contrib.opentracing.span import OTSpanContext -from elasticapm.utils.disttracing import TraceParent - -pytestmark = pytest.mark.opentracing - - -try: - from opentracing import logs as ot_logs - from opentracing import tags -except ImportError: - ot_logs = None - - -@pytest.fixture() -def tracer(elasticapm_client): - yield Tracer(client_instance=elasticapm_client) - elasticapm.uninstrument() - - -def test_tracer_with_instantiated_client(elasticapm_client): - tracer = Tracer(client_instance=elasticapm_client) - assert tracer._agent is elasticapm_client - - -def test_tracer_with_config(): - config = {"METRICS_INTERVAL": "0s", "SERVER_URL": "https://example.com/test"} - tracer = Tracer(config=config) - try: - assert tracer._agent.config.metrics_interval == timedelta(seconds=0) - assert tracer._agent.config.server_url == "https://example.com/test" - finally: - tracer._agent.close() - - -def test_tracer_instrument(elasticapm_client): - with mock.patch("elasticapm.contrib.opentracing.tracer.instrument") as mock_instrument: - elasticapm_client.config.instrument = False - Tracer(client_instance=elasticapm_client) - assert mock_instrument.call_count == 0 - - elasticapm_client.config.instrument = True - Tracer(client_instance=elasticapm_client) - assert mock_instrument.call_count == 1 - - -def test_ot_transaction_started(tracer): - with tracer.start_active_span("test") as ot_scope: - ot_scope.span.set_tag("result", "OK") - client = tracer._agent - transaction = client.events[constants.TRANSACTION][0] - assert transaction["type"] == "custom" - assert transaction["name"] == "test" - assert transaction["result"] == "OK" - - -def test_ot_span(tracer): - with tracer.start_active_span("test") as ot_scope_transaction: - with tracer.start_active_span("testspan") as ot_scope_span: - ot_scope_span.span.set_tag("span.kind", "custom") - with tracer.start_active_span("testspan2") as ot_scope_span2: - with tracer.start_active_span("testspan3", child_of=ot_scope_span.span) as ot_scope_span3: - pass - client = tracer._agent - transaction = client.events[constants.TRANSACTION][0] - span1 = client.events[constants.SPAN][2] - span2 = client.events[constants.SPAN][1] - span3 = client.events[constants.SPAN][0] - assert span1["transaction_id"] == span1["parent_id"] == transaction["id"] - assert span1["name"] == "testspan" - - assert span2["transaction_id"] == transaction["id"] - assert span2["parent_id"] == span1["id"] - assert span2["name"] == "testspan2" - - # check that span3 has span1 as parent - assert span3["transaction_id"] == transaction["id"] - assert span3["parent_id"] == span1["id"] - assert span3["name"] == "testspan3" - - -def test_transaction_tags(tracer): - with tracer.start_active_span("test") as ot_scope: - ot_scope.span.set_tag("type", "foo") - ot_scope.span.set_tag("http.status_code", 200) - ot_scope.span.set_tag("http.url", "http://example.com/foo") - ot_scope.span.set_tag("http.method", "GET") - ot_scope.span.set_tag("user.id", 1) - ot_scope.span.set_tag("user.email", "foo@example.com") - ot_scope.span.set_tag("user.username", "foo") - ot_scope.span.set_tag("component", "Django") - ot_scope.span.set_tag("something.else", "foo") - client = tracer._agent - transaction = client.events[constants.TRANSACTION][0] - - assert transaction["type"] == "foo" - assert transaction["result"] == "HTTP 2xx" - assert transaction["context"]["response"]["status_code"] == 200 - assert transaction["context"]["request"]["url"]["full"] == "http://example.com/foo" - assert transaction["context"]["request"]["method"] == "GET" - assert transaction["context"]["user"] == {"id": 1, "email": "foo@example.com", "username": "foo"} - assert transaction["context"]["service"]["framework"]["name"] == "Django" - assert transaction["context"]["tags"] == {"something_else": "foo"} - - -def test_span_tags(tracer): - with tracer.start_active_span("transaction") as ot_scope_t: - with tracer.start_active_span("span") as ot_scope_s: - s = ot_scope_s.span - s.set_tag("db.type", "sql") - s.set_tag("db.statement", "SELECT * FROM foo") - s.set_tag("db.user", "bar") - s.set_tag("db.instance", "baz") - with tracer.start_active_span("span") as ot_scope_s: - s = ot_scope_s.span - s.set_tag("span.kind", "foo") - s.set_tag("something.else", "bar") - client = tracer._agent - span1 = client.events[constants.SPAN][0] - span2 = client.events[constants.SPAN][1] - - assert span1["context"]["db"] == {"type": "sql", "user": "bar", "statement": "SELECT * FROM foo"} - assert span1["type"] == "db.sql" - assert span1["context"]["tags"] == {"db_instance": "baz"} - - assert span2["type"] == "foo" - assert span2["context"]["tags"] == {"something_else": "bar"} - - -@pytest.mark.parametrize("elasticapm_client", [{"transaction_max_spans": 1}], indirect=True) -def test_dropped_spans(tracer): - assert tracer._agent.config.transaction_max_spans == 1 - with tracer.start_active_span("transaction") as ot_scope_t: - with tracer.start_active_span("span") as ot_scope_s: - s = ot_scope_s.span - s.set_tag("db.type", "sql") - with tracer.start_active_span("span") as ot_scope_s: - s = ot_scope_s.span - s.set_tag("db.type", "sql") - client = tracer._agent - spans = client.events[constants.SPAN] - assert len(spans) == 1 - - -def test_error_log(tracer): - with tracer.start_active_span("transaction") as tx_scope: - try: - raise ValueError("oops") - except ValueError: - exc_type, exc_val, exc_tb = sys.exc_info()[:3] - tx_scope.span.log_kv( - {"python.exception.type": exc_type, "python.exception.val": exc_val, "python.exception.tb": exc_tb} - ) - client = tracer._agent - error = client.events[constants.ERROR][0] - - assert error["exception"]["message"] == "ValueError: oops" - - -@pytest.mark.skipif(ot_logs is None, reason="New key names in opentracing-python 2.1") -def test_error_log_ot_21(tracer): - with tracer.start_active_span("transaction") as tx_scope: - try: - raise ValueError("oops") - except ValueError: - exc_type, exc_val, exc_tb = sys.exc_info()[:3] - tx_scope.span.log_kv( - { - ot_logs.EVENT: tags.ERROR, - ot_logs.ERROR_KIND: exc_type, - ot_logs.ERROR_OBJECT: exc_val, - ot_logs.STACK: exc_tb, - } - ) - client = tracer._agent - error = client.events[constants.ERROR][0] - - assert error["exception"]["message"] == "ValueError: oops" - - -def test_error_log_automatic_in_span_context_manager(tracer): - scope = tracer.start_active_span("transaction") - with pytest.raises(ValueError): - with scope.span: - raise ValueError("oops") - - client = tracer._agent - error = client.events[constants.ERROR][0] - - assert error["exception"]["message"] == "ValueError: oops" - - -def test_span_set_bagge_item_noop(tracer): - scope = tracer.start_active_span("transaction") - assert scope.span.set_baggage_item("key", "val") == scope.span - - -def test_tracer_extract_http(tracer): - span_context = tracer.extract( - Format.HTTP_HEADERS, {"elastic-apm-traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"} - ) - - assert span_context.trace_parent.version == 0 - assert span_context.trace_parent.trace_id == "0af7651916cd43dd8448eb211c80319c" - assert span_context.trace_parent.span_id == "b7ad6b7169203331" - - -def test_tracer_extract_map(tracer): - span_context = tracer.extract( - Format.TEXT_MAP, {"elastic-apm-traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"} - ) - - assert span_context.trace_parent.version == 0 - assert span_context.trace_parent.trace_id == "0af7651916cd43dd8448eb211c80319c" - assert span_context.trace_parent.span_id == "b7ad6b7169203331" - - -def test_tracer_extract_binary(tracer): - with pytest.raises(opentracing.UnsupportedFormatException): - tracer.extract(Format.BINARY, b"foo") - - -def test_tracer_extract_corrupted(tracer): - with pytest.raises(opentracing.SpanContextCorruptedException): - tracer.extract(Format.HTTP_HEADERS, {"nothing-to": "see-here"}) - - -@pytest.mark.parametrize( - "elasticapm_client", - [ - pytest.param({"use_elastic_traceparent_header": True}, id="use_elastic_traceparent_header-True"), - pytest.param({"use_elastic_traceparent_header": False}, id="use_elastic_traceparent_header-False"), - ], - indirect=True, -) -def test_tracer_inject_http(tracer): - span_context = OTSpanContext( - trace_parent=TraceParent.from_string("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01") - ) - carrier = {} - tracer.inject(span_context, Format.HTTP_HEADERS, carrier) - assert carrier[constants.TRACEPARENT_HEADER_NAME] == b"00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01" - if tracer._agent.config.use_elastic_traceparent_header: - assert carrier[constants.TRACEPARENT_LEGACY_HEADER_NAME] == carrier[constants.TRACEPARENT_HEADER_NAME] - - -@pytest.mark.parametrize( - "elasticapm_client", - [ - pytest.param({"use_elastic_traceparent_header": True}, id="use_elastic_traceparent_header-True"), - pytest.param({"use_elastic_traceparent_header": False}, id="use_elastic_traceparent_header-False"), - ], - indirect=True, -) -def test_tracer_inject_map(tracer): - span_context = OTSpanContext( - trace_parent=TraceParent.from_string("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01") - ) - carrier = {} - tracer.inject(span_context, Format.TEXT_MAP, carrier) - assert carrier[constants.TRACEPARENT_HEADER_NAME] == b"00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01" - if tracer._agent.config.use_elastic_traceparent_header: - assert carrier[constants.TRACEPARENT_LEGACY_HEADER_NAME] == carrier[constants.TRACEPARENT_HEADER_NAME] - - -def test_tracer_inject_binary(tracer): - span_context = OTSpanContext( - trace_parent=TraceParent.from_string("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01") - ) - with pytest.raises(opentracing.UnsupportedFormatException): - tracer.inject(span_context, Format.BINARY, {}) diff --git a/tests/requirements/reqs-opentracing-2.0.txt b/tests/requirements/reqs-opentracing-2.0.txt deleted file mode 100644 index de859ccbb..000000000 --- a/tests/requirements/reqs-opentracing-2.0.txt +++ /dev/null @@ -1,2 +0,0 @@ -opentracing>=2.0.0,<2.1.0 --r reqs-base.txt diff --git a/tests/requirements/reqs-opentracing-newest.txt b/tests/requirements/reqs-opentracing-newest.txt deleted file mode 100644 index b82c2d976..000000000 --- a/tests/requirements/reqs-opentracing-newest.txt +++ /dev/null @@ -1,2 +0,0 @@ -opentracing>=2.1.0 --r reqs-base.txt diff --git a/tests/scripts/envs/opentracing.sh b/tests/scripts/envs/opentracing.sh deleted file mode 100644 index 243c0ee96..000000000 --- a/tests/scripts/envs/opentracing.sh +++ /dev/null @@ -1 +0,0 @@ -export PYTEST_MARKER="-m opentracing"