debug.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.utils.debug
  4. ~~~~~~~~~~~~~~~~~~
  5. Utilities for debugging memory usage.
  6. """
  7. from __future__ import absolute_import
  8. import os
  9. from .compat import format_d
  10. try:
  11. from psutil import Process
  12. except ImportError:
  13. Process = None # noqa
  14. _process = None
  15. _mem_sample = []
  16. def sample_mem():
  17. """Sample RSS memory usage.
  18. Statistics can then be output by calling :func:`memdump`.
  19. """
  20. _mem_sample.append(mem_rss())
  21. def memdump(samples=10):
  22. """Dump memory statistics.
  23. Will print a sample of all RSS memory samples added by
  24. calling :func:`sample_mem`, and in addition print
  25. used RSS memory after :func:`gc.collect`.
  26. """
  27. if ps() is None:
  28. print('- rss: (psutil not installed).')
  29. return
  30. if filter(None, _mem_sample):
  31. print('- rss (sample):')
  32. for mem in sample(_mem_sample, samples):
  33. print('- > %s,' % mem)
  34. _mem_sample[:] = []
  35. import gc
  36. gc.collect()
  37. print('- rss (end): %s.' % (mem_rss()))
  38. def sample(x, n, k=0):
  39. """Given a list `x` a sample of length ``n`` of that list is returned.
  40. E.g. if `n` is 10, and `x` has 100 items, a list of every 10th
  41. item is returned.
  42. ``k`` can be used as offset.
  43. """
  44. j = len(x) // n
  45. for _ in xrange(n):
  46. yield x[k]
  47. k += j
  48. def mem_rss():
  49. """Returns RSS memory usage as a humanized string."""
  50. p = ps()
  51. if p is not None:
  52. return '%sMB' % (format_d(p.get_memory_info().rss // 1024), )
  53. def ps():
  54. """Returns the global :class:`psutil.Process` instance,
  55. or :const:`None` if :mod:`psutil` is not installed."""
  56. global _process
  57. if _process is None and Process is not None:
  58. _process = Process(os.getpid())
  59. return _process