_frames.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. # This file is dual licensed under the terms of the Apache License, Version
  2. # 2.0, and the MIT License. See the LICENSE file in the root of this
  3. # repository for complete details.
  4. from __future__ import absolute_import, division, print_function
  5. import sys
  6. import traceback
  7. from six.moves import cStringIO as StringIO
  8. def _format_exception(exc_info):
  9. """
  10. Prettyprint an `exc_info` tuple.
  11. Shamelessly stolen from stdlib's logging module.
  12. """
  13. sio = StringIO()
  14. traceback.print_exception(exc_info[0], exc_info[1], exc_info[2], None, sio)
  15. s = sio.getvalue()
  16. sio.close()
  17. if s[-1:] == "\n":
  18. s = s[:-1]
  19. return s
  20. def _find_first_app_frame_and_name(additional_ignores=None):
  21. """
  22. Remove all intra-structlog calls and return the relevant app frame.
  23. :param additional_ignores: Additional names with which the first frame must
  24. not start.
  25. :type additional_ignores: `list` of `str` or `None`
  26. :rtype: tuple of (frame, name)
  27. """
  28. ignores = ["structlog"] + (additional_ignores or [])
  29. f = sys._getframe()
  30. name = f.f_globals.get("__name__") or "?"
  31. while any(name.startswith(i) for i in ignores):
  32. if f.f_back is None:
  33. name = "?"
  34. break
  35. f = f.f_back
  36. name = f.f_globals.get("__name__") or "?"
  37. return f, name
  38. def _format_stack(frame):
  39. """
  40. Pretty-print the stack of `frame` like logging would.
  41. """
  42. sio = StringIO()
  43. sio.write('Stack (most recent call last):\n')
  44. traceback.print_stack(frame, file=sio)
  45. sinfo = sio.getvalue()
  46. if sinfo[-1] == '\n':
  47. sinfo = sinfo[:-1]
  48. sio.close()
  49. return sinfo