Skip to content

Commit 86a4fe5

Browse files
committed
elasticsearch: don't produce spans if native elasticsearch support is enabled
If elasticsearch is found with native OTel support enabled just call the wrapped function without creating our own spans. Fix #2393
1 parent 460fc33 commit 86a4fe5

File tree

4 files changed

+43
-5
lines changed

4 files changed

+43
-5
lines changed

instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ def _wrap_perform_request(
197197
):
198198
# pylint: disable=R0912,R0914
199199
def wrapper(wrapped, _, args, kwargs):
200+
# if wrapped elasticsearch has native OTel instrumentation just call the wrapped function
201+
otel_span = kwargs.get("otel_span")
202+
if otel_span and otel_span.otel_span:
203+
return wrapped(*args, **kwargs)
204+
200205
method = url = None
201206
try:
202207
method, url, *_ = args
@@ -249,6 +254,11 @@ def normalize_kwargs(k, v):
249254
v = str(v)
250255
elif isinstance(v, elastic_transport.HttpHeaders):
251256
v = dict(v)
257+
elif isinstance(
258+
v, elastic_transport.OpenTelemetrySpan
259+
):
260+
# the transport Span is always a dummy one
261+
v = None
252262
return (k, v)
253263

254264
hook_kwargs = dict(

instrumentation/opentelemetry-instrumentation-elasticsearch/test-requirements-2.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
asgiref==3.7.2
22
attrs==23.2.0
33
Deprecated==1.2.14
4-
elasticsearch==8.12.1
5-
elasticsearch-dsl==8.12.0
6-
elastic-transport==8.12.0
4+
elasticsearch==8.13.1
5+
elasticsearch-dsl==8.13.1
6+
elastic-transport==8.13.0
77
importlib-metadata==6.11.0
88
iniconfig==2.0.0
99
packaging==23.2

instrumentation/opentelemetry-instrumentation-elasticsearch/tests/test_elasticsearch.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import elasticsearch.exceptions
2424
from elasticsearch import Elasticsearch
2525
from elasticsearch_dsl import Search
26+
from pytest import mark
2627

2728
import opentelemetry.instrumentation.elasticsearch
2829
from opentelemetry import trace
@@ -70,6 +71,9 @@ def get_elasticsearch_client(*args, **kwargs):
7071

7172

7273
@mock.patch(helpers.perform_request_mock_path)
74+
@mock.patch.dict(
75+
os.environ, dict(OTEL_PYTHON_INSTRUMENTATION_ELASTICSEARCH_ENABLED="false")
76+
)
7377
class TestElasticsearchIntegration(TestBase):
7478
search_attributes = {
7579
SpanAttributes.DB_SYSTEM: "elasticsearch",
@@ -110,7 +114,6 @@ def test_instrumentor(self, request_mock):
110114
span = spans_list[0]
111115

112116
# Check version and name in span's instrumentation info
113-
# self.assertEqualSpanInstrumentationInfo(span, opentelemetry.instrumentation.elasticsearch)
114117
self.assertEqualSpanInstrumentationInfo(
115118
span, opentelemetry.instrumentation.elasticsearch
116119
)
@@ -475,6 +478,7 @@ def request_hook(span, method, url, kwargs):
475478
"headers": {
476479
"accept": "application/vnd.elasticsearch+json; compatible-with=8"
477480
},
481+
"otel_span": None,
478482
}
479483
elif major_version == 7:
480484
expected_kwargs = {
@@ -607,3 +611,27 @@ def test_bulk(self, request_mock):
607611
self.assertEqualSpanInstrumentationInfo(
608612
span, opentelemetry.instrumentation.elasticsearch
609613
)
614+
615+
@mark.skipif(major_version < 8, reason="Native otel since elasticsearch 8")
616+
@mock.patch.dict(
617+
os.environ,
618+
dict(OTEL_PYTHON_INSTRUMENTATION_ELASTICSEARCH_ENABLED="true"),
619+
)
620+
def test_instrumentation_is_disabled_if_native_support_enabled(
621+
self, request_mock
622+
):
623+
request_mock.return_value = helpers.mock_response("{}")
624+
625+
es = get_elasticsearch_client(hosts=["http://localhost:9200"])
626+
es.index(
627+
index="sw",
628+
id=1,
629+
**normalize_arguments(body={"name": "adam"}, doc_type="_doc"),
630+
)
631+
632+
spans_list = self.get_finished_spans()
633+
self.assertEqual(len(spans_list), 1)
634+
span = spans_list[0]
635+
636+
# Check that name in span's instrumentation info is not from this instrumentation
637+
self.assertEqual(span.instrumentation_info.name, "elasticsearch-api")

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ envlist =
9292
; below mean these dependencies are being used:
9393
; 0: elasticsearch-dsl==6.4.0 elasticsearch==6.8.2
9494
; 1: elasticsearch-dsl==7.4.1 elasticsearch==7.17.9
95-
; 2: elasticsearch-dsl>=8.0,<8.13 elasticsearch>=8.0,<8.13
95+
; 2: elasticsearch-dsl==8.13.1 elasticsearch==8.13.1
9696
py3{8,9,10,11}-test-instrumentation-elasticsearch-{0,1,2}
9797
pypy3-test-instrumentation-elasticsearch-{0,1,2}
9898
lint-instrumentation-elasticsearch

0 commit comments

Comments
 (0)