/resources/processes.py

https://gitlab.com/meetly/dd-agent · Python · 95 lines · 73 code · 18 blank · 4 comment · 11 complexity · fc3eef1cd9d3acce6b78fb365139f994 MD5 · raw file

  1. # stdlib
  2. from collections import namedtuple
  3. # project
  4. from resources import (
  5. agg,
  6. ResourcePlugin,
  7. SnapshotDescriptor,
  8. SnapshotField,
  9. )
  10. from utils.subprocess_output import get_subprocess_output
  11. class Processes(ResourcePlugin):
  12. RESOURCE_KEY = "processes"
  13. FLUSH_INTERVAL = 1 # in minutes
  14. def describe_snapshot(self):
  15. return SnapshotDescriptor(
  16. 1,
  17. SnapshotField("user", 'str', aggregator=agg.append, temporal_aggregator=agg.append),
  18. SnapshotField("pct_cpu", 'float'),
  19. SnapshotField("pct_mem", 'float'),
  20. SnapshotField("vsz", 'int'),
  21. SnapshotField("rss", 'int'),
  22. SnapshotField("family", 'str', aggregator=None, temporal_aggregator=None,
  23. group_on=True, temporal_group_on=True),
  24. SnapshotField("ps_count", 'int'))
  25. def _get_proc_list(self):
  26. # Get output from ps
  27. try:
  28. process_exclude_args = self.config.get('exclude_process_args', False)
  29. if process_exclude_args:
  30. ps_arg = 'aux'
  31. else:
  32. ps_arg = 'auxww'
  33. output, _, _ = get_subprocess_output(['ps', ps_arg], self.log)
  34. processLines = output.splitlines() # Also removes a trailing empty line
  35. except Exception:
  36. self.log.exception('Cannot get process list')
  37. raise
  38. del processLines[0] # Removes the headers
  39. processes = []
  40. for line in processLines:
  41. line = line.split(None, 10)
  42. processes.append(map(lambda s: s.strip(), line))
  43. return processes
  44. @staticmethod
  45. def group_by_family(o):
  46. return o[5]
  47. @staticmethod
  48. def filter_by_usage(o):
  49. # keep everything over 1% (cpu or ram)
  50. return o[0] > 1 or o[1] > 1
  51. def _parse_proc_list(self, processes):
  52. def _compute_family(command):
  53. if command.startswith('['):
  54. return 'kernel'
  55. else:
  56. return (command.split()[0]).split('/')[-1]
  57. PSLine = namedtuple("PSLine", "user,pid,pct_cpu,pct_mem,vsz,rss,tty,stat,started,time,command")
  58. self.start_snapshot()
  59. for line in processes:
  60. try:
  61. psl = PSLine(*line)
  62. self.add_to_snapshot([psl.user,
  63. float(psl.pct_cpu),
  64. float(psl.pct_mem),
  65. int(psl.vsz),
  66. int(psl.rss),
  67. _compute_family(psl.command),
  68. 1])
  69. except Exception:
  70. pass
  71. self.end_snapshot(group_by=self.group_by_family)
  72. def flush_snapshots(self, snapshot_group):
  73. self._flush_snapshots(snapshot_group=snapshot_group,
  74. group_by=self.group_by_family,
  75. filter_by=self.filter_by_usage)
  76. def check(self):
  77. self._parse_proc_list(self._get_proc_list())