Skip to content

Commit 1f4c363

Browse files
authored
Fix logging integrations for DroppedSpan spans (#602)
* Fix logging integrations for DroppedSpan spans * Add id=None to DroppedSpan for consistency * Add id to __slots__
1 parent 2dcbbfb commit 1f4c363

File tree

3 files changed

+41
-16
lines changed

3 files changed

+41
-16
lines changed

elasticapm/handlers/structlog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@ def structlog_processor(logger, method_name, event_dict):
5656
if transaction and transaction.trace_parent:
5757
event_dict["trace.id"] = transaction.trace_parent.trace_id
5858
span = execution_context.get_span()
59-
if span:
59+
if span and span.id:
6060
event_dict["span.id"] = span.id
6161
return event_dict

elasticapm/traces.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,12 @@ def __str__(self):
446446

447447

448448
class DroppedSpan(BaseSpan):
449-
__slots__ = ("leaf", "parent")
449+
__slots__ = ("leaf", "parent", "id")
450450

451451
def __init__(self, parent, leaf=False):
452452
self.parent = parent
453453
self.leaf = leaf
454+
self.id = None
454455
super(DroppedSpan, self).__init__()
455456

456457
def end(self, skip_frames=0, duration=None):

tests/handlers/logging/logging_tests.py

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,8 @@ def test_arbitrary_object(logger):
252252
assert event["log"]["param_message"] == "['a', 'list', 'of', 'strings']"
253253

254254

255-
def test_logging_filter_no_span():
256-
requests_store = Tracer(lambda: [], lambda: [], lambda *args: None, Config(), None)
257-
transaction = requests_store.begin_transaction("test")
255+
def test_logging_filter_no_span(elasticapm_client):
256+
transaction = elasticapm_client.begin_transaction("test")
258257
f = LoggingFilter()
259258
record = logging.LogRecord(__name__, logging.DEBUG, __file__, 252, "dummy_msg", [], None)
260259
f.filter(record)
@@ -264,19 +263,18 @@ def test_logging_filter_no_span():
264263
assert record.elasticapm_labels
265264

266265

267-
def test_structlog_processor_no_span():
268-
requests_store = Tracer(lambda: [], lambda: [], lambda *args: None, Config(), None)
269-
transaction = requests_store.begin_transaction("test")
266+
def test_structlog_processor_no_span(elasticapm_client):
267+
transaction = elasticapm_client.begin_transaction("test")
270268
event_dict = {}
271269
new_dict = structlog_processor(None, None, event_dict)
272270
assert new_dict["transaction.id"] == transaction.id
273271
assert new_dict["trace.id"] == transaction.trace_parent.trace_id
274272
assert "span.id" not in new_dict
275273

276274

277-
def test_logging_filter_span():
278-
requests_store = Tracer(lambda: [], lambda: [], lambda *args: None, Config(), None)
279-
transaction = requests_store.begin_transaction("test")
275+
@pytest.mark.parametrize("elasticapm_client", [{"transaction_max_spans": 5}], indirect=True)
276+
def test_logging_filter_span(elasticapm_client):
277+
transaction = elasticapm_client.begin_transaction("test")
280278
with capture_span("test") as span:
281279
f = LoggingFilter()
282280
record = logging.LogRecord(__name__, logging.DEBUG, __file__, 252, "dummy_msg", [], None)
@@ -286,26 +284,52 @@ def test_logging_filter_span():
286284
assert record.elasticapm_span_id == span.id
287285
assert record.elasticapm_labels
288286

287+
# Capture too many spans so we start dropping
288+
for i in range(10):
289+
with capture_span("drop"):
290+
pass
289291

290-
def test_structlog_processor_span():
291-
requests_store = Tracer(lambda: [], lambda: [], lambda *args: None, Config(), None)
292-
transaction = requests_store.begin_transaction("test")
292+
# Test logging with DroppedSpan
293+
with capture_span("drop") as span:
294+
record = logging.LogRecord(__name__, logging.DEBUG, __file__, 252, "dummy_msg2", [], None)
295+
f.filter(record)
296+
assert record.elasticapm_transaction_id == transaction.id
297+
assert record.elasticapm_trace_id == transaction.trace_parent.trace_id
298+
assert record.elasticapm_span_id is None
299+
assert record.elasticapm_labels
300+
301+
302+
@pytest.mark.parametrize("elasticapm_client", [{"transaction_max_spans": 5}], indirect=True)
303+
def test_structlog_processor_span(elasticapm_client):
304+
transaction = elasticapm_client.begin_transaction("test")
293305
with capture_span("test") as span:
294306
event_dict = {}
295307
new_dict = structlog_processor(None, None, event_dict)
296308
assert new_dict["transaction.id"] == transaction.id
297309
assert new_dict["trace.id"] == transaction.trace_parent.trace_id
298310
assert new_dict["span.id"] == span.id
299311

312+
# Capture too many spans so we start dropping
313+
for i in range(10):
314+
with capture_span("drop"):
315+
pass
316+
317+
# Test logging with DroppedSpan
318+
with capture_span("drop") as span:
319+
event_dict = {}
320+
new_dict = structlog_processor(None, None, event_dict)
321+
assert new_dict["transaction.id"] == transaction.id
322+
assert new_dict["trace.id"] == transaction.trace_parent.trace_id
323+
assert "span.id" not in new_dict
324+
300325

301326
@pytest.mark.skipif(not compat.PY3, reason="Log record factories are only 3.2+")
302327
def test_automatic_log_record_factory_install(elasticapm_client):
303328
"""
304329
Use the elasticapm_client fixture to load the client, which in turn installs
305330
the log_record_factory. Check to make sure it happened.
306331
"""
307-
requests_store = Tracer(lambda: [], lambda: [], lambda *args: None, Config(), None)
308-
transaction = requests_store.begin_transaction("test")
332+
transaction = elasticapm_client.begin_transaction("test")
309333
with capture_span("test") as span:
310334
record_factory = logging.getLogRecordFactory()
311335
record = record_factory(__name__, logging.DEBUG, __file__, 252, "dummy_msg", [], None)

0 commit comments

Comments
 (0)