I'm trying to catch a bug in my code, that is very hard to reproduce. I can detect it, but I'd need a bit more context to reliably reproduce it.
I think the data that is reported to sentry on exception (call stack, values of local variables) will be very useful to track it. Is there any way to trigger such an event? I don't want to interrupt my program, so I can't raise an exception here. I've tried capture_event() and capture_message() but none of them captures the data I need.
you can use random_logger.error("foo", exc_info=True) to capture an event that contains a callstack with variables
Thanks @untitaker, that's almost what I need. The thing is that my logging integration is LoggingIntegration(level=None, event_level=None), also I wouldn't really like any message to appear in the console when the bug will be encountered.
Any way to work around it?
OK, I think I've figured out from the logging EventHandler how to do what I want - the code is not pretty, but works:
from sentry_sdk.utils import capture_internal_exceptions, current_stacktrace
client_options = sentry_sdk.client.get_options()
event = {}
with capture_internal_exceptions():
event["threads"] = {
"values": [
{
"stacktrace": current_stacktrace(client_options["with_locals"]),
"crashed": False,
"current": True,
}
]
}
event["level"] = "error"
event["logentry"] = {"message": "message I want to send"}
sentry_sdk.capture_event(event)
I think this could be inside some utility function, but it is good enough for me.
One question though - the last frame of the stacktrace points at "stacktrace": current_stacktrace(client_options["with_locals"]),, which makes sense, but I'd like to remove it. I've figured out that I can remove the last element from event['threads']['values'][0]['stacktrace']['frames'], and my stacktrace looks much better. The question is if event['threads']['values'][0] is guaranteed to be the current thread, or it may change when multiple threads are used?
The question is if event['threads']['values'][0] is guaranteed to be the current thread, or it may change when multiple threads are used?
you have defined this thread array within your own code to contain only one element, so it is stable.
I would however create a separate logger and register EventHandler as a handler on it. Then you can use that logger with exc_info=True to log exceptions to Sentry without enabling all of the integration
you have defined this thread array within your own code to contain only one element, so it is stable.
Oh, right - I've copied this code from integrations/logging.py and missed the fact that values is not the output of the current_stacktrace() function 🤦♂️
Thanks!
Found this when googeling, EXCATLY what i needed.
Perfected it a little bit by popping the last element of the stack and added a proper name to the message if possible:
from sentry_sdk.utils import capture_internal_exceptions, current_stacktrace
import sys
import sentry_sdk
def send_stacktrace_to_sentry():
client_options = sentry_sdk.client.get_options()
event = {}
with capture_internal_exceptions():
stacktrace = current_stacktrace(client_options["with_locals"])
stacktrace["frames"].pop()
event["threads"] = {
"values": [
{
"stacktrace": stacktrace,
"crashed": False,
"current": True,
}
]
}
event["level"] = "error"
event["logentry"] = {"message": sys.exc_info()[1] or "No Exception Found"}
sentry_sdk.capture_event(event)