TripleO Ansible project repository. Contains playbooks for use with TripleO OpenStack deployments.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

122 lines
3.9 KiB

  1. __metaclass__ = type
  2. import time
  3. from ansible import constants as C
  4. from ansible.plugins.callback.profile_tasks import secondsToStr
  5. from ansible.plugins.callback.profile_tasks import timestamp
  6. from ansible.plugins.callback.profile_tasks import CallbackModule as PT
  7. from datetime import datetime
  8. DOCUMENTATION = '''
  9. callback: tripleo_profile_tasks
  10. type: aggregate
  11. short_description: adds time information to tasks
  12. version_added: "2.9"
  13. description:
  14. - Based on upstream profile_tasks but formatted for tripleo_dense
  15. requirements:
  16. - whitelisting in configuration - see examples section below for details.
  17. options:
  18. output_limit:
  19. description: Number of tasks to display in the summary
  20. default: 20
  21. env:
  22. - name: PROFILE_TASKS_TASK_OUTPUT_LIMIT
  23. ini:
  24. - section: callback_profile_tasks
  25. key: task_output_limit
  26. sort_order:
  27. description: Adjust the sorting output of summary tasks
  28. choices: ['descending', 'ascending', 'none']
  29. default: 'descending'
  30. env:
  31. - name: PROFILE_TASKS_SORT_ORDER
  32. ini:
  33. - section: callback_profile_tasks
  34. key: sort_order
  35. '''
  36. class CallbackModule(PT):
  37. CALLBACK_VERSION = 2.0
  38. CALLBACK_TYPE = 'aggregate'
  39. CALLBACK_NAME = 'tripleo_profile_tasks'
  40. CALLBACK_NEEDS_WHITELIST = True
  41. def __init__(self):
  42. self.start_time = time.time()
  43. super(CallbackModule, self).__init__()
  44. def _output(self, msg, color=None):
  45. timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
  46. if isinstance(msg, list):
  47. output = ' | '.join([timestamp] + msg)
  48. else:
  49. output = timestamp + ' | ' + msg
  50. self._display.display(output, color=color)
  51. def _output_previous_timings(self, uuid):
  52. # no previous timing because uuid was null
  53. if not uuid:
  54. return
  55. line = [
  56. uuid,
  57. u'{:>10}'.format('TIMING'),
  58. self.stats[uuid].get('name', 'NONAME'),
  59. secondsToStr(time.time() - self.start_time),
  60. u'{0:.02f}s'.format(self.stats[uuid].get('time', '-1'))
  61. ]
  62. self._output(line, C.COLOR_DEBUG)
  63. def _record_task(self, task):
  64. timestamp(self)
  65. self._output_previous_timings(self.current)
  66. self.current = task._uuid
  67. self.stats[self.current] = {'time': time.time(),
  68. 'name': task.get_name()}
  69. if self._display.verbosity >= 2:
  70. self.stats[self.current]['path'] = task.get_path()
  71. def playbook_on_stats(self, stats):
  72. timestamp(self)
  73. self.current = None
  74. results = self.stats.items()
  75. # Sort the tasks by the specified sort
  76. if self.sort_order is not None:
  77. results = sorted(
  78. self.stats.items(),
  79. key=lambda x: x[1]['time'],
  80. reverse=self.sort_order,
  81. )
  82. results = results[:self.task_output_limit]
  83. self._output('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
  84. ' Summary Information '
  85. '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
  86. self._output(
  87. '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
  88. ' Elapsed Time: {} '
  89. '~~~~~~~~~~~~~~~~~~~~~~~~~~~~'.format(
  90. secondsToStr(time.time() - self.start_time)))
  91. header = [
  92. '{:>36}'.format('UUID'),
  93. '{:>10}'.format('Info'),
  94. '{}'.format('Task Name'),
  95. '{:>10}'.format('Run Time'),
  96. ]
  97. self._output(' | '.join(header))
  98. for uuid, result in results:
  99. line = [
  100. uuid,
  101. u'{:>10}'.format('SUMMARY'),
  102. result['name'],
  103. u'{0:.02f}s'.format(result['time'])
  104. ]
  105. self._output(' | '.join(line))
  106. self._output('~' * 89)