sentry-python
sentry-python copied to clipboard
Add a way of ignoring/filtering child spans
Problem Statement
I currently run a celery task*, with some custom spans that divide a long running processing task. This processing task itself does a bunch of HTTP requests, subprocess invocations and other things that cause enabled integrations to create child spans. However, this task does so many requests that these child spans easily go over the maximum amount of spans (or transaction size) and get cut. This means not only the child spans are cut but also some of the later custom spans. In this particular task I do not care much about the child spans and would rather ignore them inside of the custom spans so that the custom spans do not get cut (but keep the integrations enabled for elsewhere in the app).
I do not really see a (non-nasty) way of accomplishing this with the current API. Perhaps by pushing a scope and setting the span of it to some custom Span subclass that ignores start_child?
*For an example see (but not really important to the issue): https://github.com/crocs-muni/sec-certs/blob/de4af2f9c68797ba5031c315602cab185ce04acc/sec_certs_page/cc/tasks.py#L86-L101
Solution Brainstorm
Something like start_span taking an argument to ignore child spans? Or a setting on the scope level to stop span creation?
Came up with this workaround. When used as a context manager that is entered after the start_span one it suppresses further child spans.
from contextlib import contextmanager
from sentry_sdk import push_scope
from sentry_sdk.tracing import Span
class NoChildSpan(Span):
def start_child(self, **kwargs):
return super().start_child(sampled=False, **kwargs)
@contextmanager
def suppress_child_spans():
with push_scope() as scope:
scope.span = NoChildSpan()
try:
yield
finally:
pass
thx @J08nY, we're gonna start a milestone with several performance API improvements / decorators and I'll make sure to include this use case there!
Hey @J08nY, have you tried using a before_send_transaction to filter the child spans you wish to ignore? You can use before_send_transaction to directly modify the transaction event object before it gets sent to Sentry, so using before_send_transaction might be the easiest solution.
Hmm, I am okay with my (albeit hacky) solution right now as it prevents the creation of unwanted child spans altogether and I think has better performance than allowing the creation of all of the spans and then filtering them before sending.
Fair enough, @J08nY – we will look into how to best create an API which would support preventing the child spans from being created in the first place