From 41530c583cf0f0bff2f4806338022e2119de6f3d Mon Sep 17 00:00:00 2001 From: Ronny Date: Wed, 17 Dec 2025 09:27:31 +0000 Subject: [PATCH] add callback plugin --- ansible.cfg | 16 +++++++- callback_plugins/task_logger.py | 68 +++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 callback_plugins/task_logger.py diff --git a/ansible.cfg b/ansible.cfg index 6ca1c84..c867673 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -16,6 +16,20 @@ ansible_interpreter_python = auto_silent # # become_user = root # # become_ask_pass = False +# Callback Plugin aktivieren +callback_whitelist = task_logger +callbacks_enabled = task_logger + +# Farben aktivieren +force_color = True + +# Bessere Fehlerausgabe +display_skipped_hosts = False +display_ok_hosts = False + +# Verbosity für mehr Details (optional) +# verbosity = 1 + [ssh_connection] pipelining = True -control_path = /tmp/ansible-ssh-%%h-%%p-%%r \ No newline at end of file +control_path = /tmp/ansible-ssh-%%h-%%p-%%r diff --git a/callback_plugins/task_logger.py b/callback_plugins/task_logger.py new file mode 100644 index 0000000..8116cb0 --- /dev/null +++ b/callback_plugins/task_logger.py @@ -0,0 +1,68 @@ +from ansible.plugins.callback import CallbackBase +from ansible.utils.color import colorize_message, hostcolor +from datetime import datetime + +class CallbackModule(CallbackBase): + CALLBACK_VERSION = 2.0 + CALLBACK_NAME = 'task_logger' + CALLBACK_TYPE = 'stdout' + CALLBACK_NEEDS_WHITELIST = False + + def __init__(self): + super(CallbackModule, self).__init__() + self.task_count = 0 + self.start_time = datetime.now() + + def v2_playbook_on_start(self, playbook): + self._display.display("\n" + "="*80, color='blue') + self._display.display("PLAYBOOK STARTED", color='blue') + self._display.display("="*80 + "\n", color='blue') + + def v2_playbook_on_play_start(self, play): + self._display.display("\n" + "-"*80, color='cyan') + self._display.display(f"PLAY: {play.name}", color='cyan') + self._display.display("-"*80 + "\n", color='cyan') + + def v2_runner_on_start(self, host, task): + self.task_count += 1 + task_name = task.name or "unnamed task" + self._display.display( + f"[{self.task_count}] TASK: {task_name}", + color='blue' + ) + + def v2_runner_on_ok(self, result, **kwargs): + self._display.display(f" ✓ OK\n", color='green') + + def v2_runner_on_failed(self, result, ignore_errors=False, **kwargs): + task_name = result.task_name or "unnamed task" + self._display.display( + f" ✗ FAILED: {task_name}\n", + color='red' + ) + + def v2_runner_on_skipped(self, result, **kwargs): + self._display.display(f" ⊘ SKIPPED\n", color='yellow') + + def v2_runner_on_unreachable(self, result): + self._display.display( + f" ✗ UNREACHABLE\n", + color='red' + ) + + def v2_playbook_on_stats(self, stats): + self._display.display("\n" + "="*80, color='blue') + self._display.display("PLAYBOOK FINISHED", color='blue') + self._display.display("="*80, color='blue') + + # Statistiken anzeigen + hosts = sorted(stats.processed.keys()) + for host in hosts: + summary = stats.summarize(host) + self._display.display( + f"\n{host}: ok={summary['ok']} changed={summary['changed']} " + f"failed={summary['failures']} skipped={summary['skipped']} " + f"unreachable={summary['unreachable']}", + color='cyan' + ) + self._display.display("\n") \ No newline at end of file