|--utils
in the logging config dict in the app dir BOTH the app and utils logger include an identical sentry handler. Now here is where it gets interesting. In file utils.crasher I have:
import logging
logger = getLogger(__name__)
def crash_boy():
1 + '123'
except Exception as e:
logger.exception('Oh gosh we messed up big time here')
raise e
and in app.main
@bp.route('/crash')
def crash():
return crash_boy()
except Exception as e:
logger.exception('OH GREAT')
return 'WE HAD A CRASH BOIZ'
The utils logger DOES include a traceback but the app logger will only log the string (‘OH GREAT’) with no stack trace.
After thorough testing our app logger will ONLY log an exceptions stack trace in an uncaught exception of an except block like so:
# 1/0 here would log an error and line number in sentry UI but no stack trace
except Exception as e:
logger.exception('Probably did 1/0') # No stack trace in web UI
1 + '1' #will include a stack trace in web UI
So it seems sentry CAN include a traceback via the app logger but only in uncaught exceptions inside an except block.
Hey Eric,
You’ll need to explicitly include the stack trace when logging, using the extra kwarg.
logger.exception('Probably did 1/0', extra={'stack': True})
additionally manually doing sentry.captureException()
does report the error to sentry so there is inconsistent behavior between logger.exception('Probably did 1/0', extra={'stack': True})
and captureException
in addition to the inconsistent behavior of the exception logger depending on which module it is invoked in.
The exception on the logger is attached by python logging. We just pick it up. About why it’s necessary in one place and not in another I cannot tell you. I have seen such things before when gevent was used.
Which Python version do you use and do you use any concurrency modules? (gevent, eventlet etc.)
@erik-farmer yeah. In that case I’m not surprised this happens. I believe it happens if a context switch happens upon error handling. I have seen this before and the best workaround I have is to do this:
except Exception:
exc_info = sys.exc_info()
logger.error('message here', exc_info=exc_info)
It still does not solve it in all situations but lowers the risk of the traceback going away.