Skip to content

Commit 1ca6e36

Browse files
authored
document how to drop events in processing (#585)
also, exit early if any processor returns a falsy value, and log why the event was dropped.
1 parent fff08b3 commit 1ca6e36

File tree

4 files changed

+39
-2
lines changed

4 files changed

+39
-2
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
[Check the diff](https://github.com/elastic/apm-agent-python/compare/v5.1.2...master)
5+
6+
### Bugfixes
7+
* drop events immediately if a processor returns a falsy value (#585)
8+
39
## v5.1.2
410
[Check the diff](https://github.com/elastic/apm-agent-python/compare/v5.1.1...v5.1.2)
511

docs/sanitizing-data.asciidoc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ Sometimes it is necessary to sanitize the data sent to Elastic APM,
55
e.g. remove sensitive data.
66

77
To do this with the Elastic APM module, you create a processor.
8-
A processor is a function that takes a `client` instance as well as an event (an error or a transaction),
8+
A processor is a function that takes a `client` instance as well as an event (an error, a transaction, a span, or a metricset),
99
and returns the modified event.
1010

11+
To completely drop an event, your processor should return `False` (or any other "falsy" value) instead of the event.
12+
1113
This is an example of a processor that removes the exception stacktrace from an error:
1214

1315
[source,python]
@@ -23,7 +25,8 @@ def my_processor(client, event):
2325
----
2426

2527
You can use the `@for_events` decorator to limit for which event type the processor should be called.
26-
Possible choices are `ERROR`, `TRANSACTION`, and `SPAN`, all of which are defined in `elasticapm.conf.constants`.
28+
Possible choices are `ERROR`, `TRANSACTION`, `SPAN` and `METRICSET`,
29+
all of which are defined in `elasticapm.conf.constants`.
2730

2831
To use this processor, update your `ELASTIC_APM` settings like this:
2932

elasticapm/base.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,15 @@ def queue(self, event_type, data, flush=False):
230230
for processor in self.processors:
231231
if not hasattr(processor, "event_types") or event_type in processor.event_types:
232232
data = processor(self, data)
233+
if not data:
234+
self.logger.debug(
235+
"Dropped event of type %s due to processor %s.%s",
236+
event_type,
237+
getattr(processor, "__module__"),
238+
getattr(processor, "__name__"),
239+
)
240+
data = None # normalize all "falsy" values to None
241+
break
233242
if flush and is_master_process():
234243
# don't flush in uWSGI master process to avoid ending up in an unpredictable threading state
235244
flush = False

tests/processors/tests.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
from __future__ import absolute_import
3434

35+
import logging
36+
3537
import mock
3638
import pytest
3739

@@ -289,3 +291,20 @@ def foo(client, event):
289291
return True
290292

291293
assert foo.event_types == {"error", "transaction"}
294+
295+
296+
def test_drop_events_in_processor(sending_elasticapm_client, caplog):
297+
def dropping_processor(client, event):
298+
return None
299+
300+
shouldnt_be_called_processor = mock.Mock()
301+
302+
sending_elasticapm_client.processors = [dropping_processor, shouldnt_be_called_processor]
303+
with caplog.at_level(logging.DEBUG):
304+
sending_elasticapm_client.queue(SPAN, {"some": "data"})
305+
sending_elasticapm_client.close()
306+
assert shouldnt_be_called_processor.call_count == 0
307+
assert len(sending_elasticapm_client.httpserver.requests) == 0
308+
record = caplog.records[0]
309+
assert record.message == "Dropped event of type span due to processor tests.processors.tests.dropping_processor"
310+
assert record.levelname == "DEBUG"

0 commit comments

Comments
 (0)