Open
Description
Describe the bug:
Using opentelemetry bridge crashes with TypeError: 'NoneType' object does not support item assignment
exception when number of spans in transaction is higher than ELASTIC_APM_TRANSACTION_MAX_SPANS
File ~/.pyenv/versions/3.11.11/envs/test/lib/python3.11/site-packages/elasticapm/contrib/opentelemetry/trace.py:169, in Tracer.start_span(self, name, context, kind, attributes, links, start_time, record_exception, set_status_on_exception)
167 span.set_attributes(attributes)
168 spankind = get_span_kind(kind)
--> 169 elastic_span.context["otel_spankind"] = spankind
171 return span
.
Debugger shows that elastic_span
inside is DroppedSpan
. Increasing nr of ELASTIC_APM_TRANSACTION_MAX_SPANS
"fixes" problem as shown in code below.
To Reproduce
from elasticapm.contrib.opentelemetry import trace
from elasticapm import Client, capture_span
import os
# Reduce number of spans required to reproduce the issue
ELASTIC_APM_TRANSACTION_MAX_SPANS = 10
STEPS_ABOVE = ELASTIC_APM_TRANSACTION_MAX_SPANS + 1
STEPS_BELLOW = ELASTIC_APM_TRANSACTION_MAX_SPANS - 1
os.environ["ELASTIC_APM_TRANSACTION_MAX_SPANS"] = str(ELASTIC_APM_TRANSACTION_MAX_SPANS)
apm_client = Client()
tracer = trace.get_tracer(__name__)
# Simulate deep nested spans
def capture_span_elasticapm(steps=10):
if steps == 0:
return
with capture_span():
capture_span_elasticapm(steps-1)
def capture_span_opentelemetry(steps=10):
if steps == 0:
return
with tracer.start_as_current_span("test"):
capture_span_opentelemetry(steps-1)
# TEST
# Works - Expected
transaction = apm_client.begin_transaction('processors')
capture_span_elasticapm(STEPS_BELLOW)
apm_client.end_transaction('myapp.billing_process')
# Works - Expected
transaction = apm_client.begin_transaction('processors')
capture_span_opentelemetry(STEPS_BELLOW)
apm_client.end_transaction('myapp.billing_process')
# Works - Expected
transaction = apm_client.begin_transaction('processors')
capture_span_elasticapm(STEPS_ABOVE)
apm_client.end_transaction('myapp.billing_process')
# Crashes - Unexpected
# TypeError: 'NoneType' object does not support item assignment
transaction = apm_client.begin_transaction('processors')
capture_span_opentelemetry(STEPS_ABOVE)
apm_client.end_transaction('myapp.billing_process')
Environment (please complete the following information)
- OS: [e.g. Linux] Linux Mint 22.1 Cinnamon
- Python version:
3.11.11
- Framework and version [e.g. Django 2.1]: N/A
- APM Server version: N/A
- Agent version:
elastic-apm==6.23.0