diff --git a/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py b/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py new file mode 100644 index 0000000000000000000000000000000000000000..7e8cf052375086a5b8b435f066963c7f02464870 --- /dev/null +++ b/geant/gap_ansible/plugins/callback_plugins/filtering_syslog.py @@ -0,0 +1,70 @@ +# callback_plugins/filtering_syslog.py +import syslog +import uuid +from datetime import datetime +from ansible.plugins.callback import CallbackBase +from ansible.utils.display import Display + +display = Display() + +class CallbackModule(CallbackBase): + """ + Logs all task results to syslog with timestamp and run ID. + One line per result. Only prints tasks tagged with 'print_action'. + Always prints and logs playbook summary. + """ + + CALLBACK_VERSION = 2.0 + CALLBACK_TYPE = 'stdout' + CALLBACK_NAME = 'filtering_syslog' + + def __init__(self): + super().__init__() + syslog.openlog(ident="ansible", logoption=syslog.LOG_PID, facility=syslog.LOG_USER) + self.run_id = str(uuid.uuid4())[:8] # Shorten for readability + + def _log_to_syslog(self, message: str): + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + syslog.syslog(syslog.LOG_INFO, f"[{timestamp}] [run_id:{self.run_id}] {message}") + + def _should_print(self, task): + return hasattr(task, "tags") and "print_action" in task.tags + + def _pretty_print(self, result, status): + task_name = result.task_name or result._task.get_name() + host = result._host.get_name() + + display.banner(f"TASK [{task_name}]") + display.display(f"{host} | {status}", color="green" if status == "ok" else "red") + display.display(self._dump_results(result._result)) + + def v2_runner_on_ok(self, result): + task = result.task_name or result._task.get_name() + host = result._host.get_name() + self._log_to_syslog(f"{host} | OK | Task: {task}") + if self._should_print(result._task): + self._pretty_print(result, "ok") + + def v2_runner_on_failed(self, result, ignore_errors=False): + task = result.task_name or result._task.get_name() + host = result._host.get_name() + self._log_to_syslog(f"{host} | FAILED | Task: {task}") + if self._should_print(result._task): + self._pretty_print(result, "failed") + + def v2_runner_on_skipped(self, result): + task = result.task_name or result._task.get_name() + host = result._host.get_name() + self._log_to_syslog(f"{host} | SKIPPED | Task: {task}") + if self._should_print(result._task): + self._pretty_print(result, "skipped") + + def v2_playbook_on_stats(self, stats): + summary = {} + for host in stats.processed.keys(): + s = stats.summarize(host) + summary_line = f"{host} | SUMMARY | ok={s['ok']} changed={s['changed']} unreachable={s['unreachable']} failed={s['failures']} skipped={s['skipped']}" + self._log_to_syslog(summary_line) + display.display(summary_line) + + display.banner("PLAYBOOK SUMMARY")