/bin/cat << EOF > $ANSIBLE_PLUGIN_LOCATION/log_parse.py import os import time import json import ansible baseModule = object ANSIBLE_VERSION = 1 if hasattr(ansible, 'plugins') and hasattr(ansible.plugins, 'callback'): baseModule = ansible.plugins.callback.CallbackBase ANSIBLE_VERSION = 2 class CallbackModule(baseModule): """ logs playbook results, per host, in /var/log/ansible/hosts """ log_path = '/var/log/ansible/hosts' fd_list = {} def __init__(self): if ANSIBLE_VERSION > 1: super(CallbackModule, self).__init__() if not os.path.exists(self.log_path): os.makedirs(self.log_path) else: for filename in os.listdir(self.log_path): filepath = os.path.join(self.log_path, filename) if os.path.exists(filepath) and os.path.isfile(filepath): os.unlink(filepath) def writeLog(self, host, category, content): if not self.fd_list.has_key(category): self.fd_list[category] = open( os.path.join(self.log_path, '%s_%s' % (host, category)), "a" ) self.fd_list[category].write(content + '\n') def log(self, host, category, data, ignore_errors=False): if host == "localhost": host = "127.0.0.1" # keep compatibility if type(data) == dict: if '_ansible_verbose_override' in data: # avoid logging extraneous data return data = data.copy() content = json.dumps(data) if ignore_errors: category = '%s_IGNORED' % category self.writeLog(host, category, content) def _stats(self, stats): for key in self.fd_list: self.fd_list[key].close() def runner_on_failed(self, host, res, ignore_errors=False): self.log(host, 'FAILED', res, ignore_errors) def runner_on_ok(self, host, res): self.log(host, 'OK', res) def runner_on_skipped(self, host, item=None): pass def runner_on_unreachable(self, host, res): self.log(host, 'UNREACHABLE', res) def runner_on_async_failed(self, host, res, jid): self.log(host, 'ASYNC_FAILED', res) def playbook_on_import_for_host(self, host, imported_file): self.log(host, 'IMPORTED', imported_file) def playbook_on_not_import_for_host(self, host, missing_file): self.log(host, 'NOTIMPORTED', missing_file) def playbook_on_stats(self, stats): self._stats(stats) EOF