import os import datetime import time import logging import datadog import sys logging.basicConfig(level=logging.INFO, stream=sys.stdout) logging.getLogger("requests").setLevel(logging.WARNING) logging.getLogger("dd").setLevel(logging.WARNING) logger = logging.getLogger(__name__) """ Originally written by 'Jharrod LaFon' #https://github.com/jlafon/ansible-profile/blob/master/callback_plugins/profile_tasks.py """ class CallbackModule(object): """ Ansible plugin get the time of each task and total time to run the complete playbook """ def __init__(self): self.stats = {} self.current_task = None self.playbook_name = None self.datadog_api_key = os.getenv('DATADOG_API_KEY') self.datadog_api_initialized = False if self.datadog_api_key: datadog.initialize(api_key=self.datadog_api_key, app_key=None) self.datadog_api_initialized = True def clean_tag_value(self, value): return value.replace(" | ", ".").replace(" ", "-").lower() def playbook_on_play_start(self, pattern): self.playbook_name, _ = os.path.splitext( os.path.basename(self.play.playbook.filename) ) def playbook_on_task_start(self, name, is_conditional): """ Logs the start of each task """ if self.current_task is not None: # Record the running time of the last executed task self.stats[self.current_task] = (time.time(), time.time() - self.stats[self.current_task]) # Record the start time of the current task self.current_task = name self.stats[self.current_task] = time.time() def playbook_on_stats(self, stats): """ Prints the timing of each task and total time to run the complete playbook """ # Record the timing of the very last task, we use it here, because we # don't have stop task function by default if self.current_task is not None: self.stats[self.current_task] = (time.time(), time.time() - self.stats[self.current_task]) # Sort the tasks by their running time results = sorted(self.stats.items(), key=lambda value: value[1][1], reverse=True) # Total time to run the complete playbook total_seconds = sum([x[1][1] for x in self.stats.items()]) # send the metric to datadog if self.datadog_api_initialized: datadog_tasks_metrics = [] for name, points in results: datadog_tasks_metrics.append({'metric': 'edx.ansible.task_duration', 'date_happened': points[0], 'points': points[1], 'tags': ['task:{0}'.format(self.clean_tag_value(name)), 'playbook:{0}'.format(self.clean_tag_value(self.playbook_name)) ] } ) try: datadog.api.Metric.send(datadog_tasks_metrics) datadog.api.Metric.send(metric="edx.ansible.playbook_duration", date_happened=time.time(), points=total_seconds, tags=["playbook:{0}".format(self.clean_tag_value(self.playbook_name))] ) except Exception as ex: logger.error(ex.message) # Log the time of each task for name, elapsed in results[:10]: logger.info( "{0:-<80}{1:->8}".format( '{0} '.format(name), ' {0:.02f}s'.format(elapsed[1]), ) ) logger.info("\nPlaybook {0} finished: {1}, {2} total tasks. {3} elapsed. \n".format( self.playbook_name, time.asctime(), len(self.stats.items()), datetime.timedelta(seconds=(int(total_seconds))) ) )