octplane / ansible_stdout_compact_logger

Ansible Stdout Compact Logger

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

loop_control.label will not be considered

rsguhr opened this issue · comments

The default behavior of Ansible is that you see the entire content of a loop element. This can be a lot and impractical. You can use loop_control.label to change what should be displayed. But dump_loop_items ignores the option and dumps the entire loop element.

Example:

---
- hosts: all
  connection: local
  gather_facts: false

  tasks:
    - set_fact:
        myvar: "{{ item }}"
      loop: 
        - name: aaa
        - name: bbb
        - name: ccc
      loop_control:
        extended: true
        extended_allitems: false
        label: "({{ ansible_loop.index }}/{{ ansible_loop.length }}) {{ item.name }}"

Plain Ansible output:

ansible-playbook test.yml -i localhost,

PLAY [all] *********************************************************************

TASK [set_fact] ****************************************************************
ok: [localhost] => (item=(1/3) aaa)
ok: [localhost] => (item=(2/3) bbb)
ok: [localhost] => (item=(3/3) ccc)

anstomlog (w/ dump_loop_items) output

ansible-playbook test.yml -i localhost,
[03:36:25] set_fact
localhost | SUCCESS - item={'ansible_facts': {'myvar': {'name': 'aaa'}}, 'item': {'name': 'aaa'}, 'ansible_loop': {'index': 1, 'index0': 0, 'first': True, 'last': False, 'length': 3, 'revindex': 3, 'revindex0': 2, 'nextitem': {'name': 'bbb'}}} | 30ms
localhost | SUCCESS - item={'ansible_facts': {'myvar': {'name': 'bbb'}}, 'item': {'name': 'bbb'}, 'ansible_loop': {'index': 2, 'index0': 1, 'first': False, 'last': False, 'length': 3, 'revindex': 2, 'revindex0': 1, 'nextitem': {'name': 'ccc'}, 'previtem': {'name': 'aaa'}}} | 30ms
localhost | SUCCESS - item={'ansible_facts': {'myvar': {'name': 'ccc'}}, 'item': {'name': 'ccc'}, 'ansible_loop': {'index': 3, 'index0': 2, 'first': False, 'last': True, 'length': 3, 'revindex': 1, 'revindex0': 0, 'previtem': {'name': 'bbb'}}} | 30ms

This will do the trick,

--- a/callbacks/anstomlog.py
+++ b/callbacks/anstomlog.py
@@ -365,25 +365,27 @@ class CallbackModule(CallbackBase):
                 and result._task.loop \
                 and 'results' in result._result:
             # remove invocation unless specifically wanting it
-            for item in abridged_result['results']:
+            for idx, item in enumerate(abridged_result['results']):
                 msg, color = self._changed_or_not(item, host_string)
-                del item['ansible_loop_var']
-                del item['failed']
-                del item['changed']
-                item_msg = "%s - item=%s" % (msg, item)
-                self._emit_line("%s | %s" %
-                                (item_msg, duration), color=color)
-        else:
-            for key in ['failed', 'changed']:
-                if key in abridged_result:
-                    del abridged_result[key]
-
-            self._emit_line("↳  %s | %s" %
-                            (msg, duration), color=color)
-            if ((self._display.verbosity > 0
-                    or verbose)
-                    and no_verbose_override):
-                self._emit_line(deep_serialize(abridged_result), color=color)
+                item.pop('ansible_loop_var', None)
+                item.pop('failed', None)
+                item.pop('changed', None)
+                if '_ansible_item_label' in result._result['results'][idx]:
+                    item_msg = f"%s - %s" % (msg, result._result['results'][idx]['_ansible_item_label'])
+                else:
+                    item_msg = "%s - item=%s" % (msg, item)
+                self._emit_line(item_msg, color=color)
+
+        for key in ['failed', 'changed']:
+            if key in abridged_result:
+                del abridged_result[key]
+
+        self._emit_line("↳  %s | %s" %
+                        (msg, duration), color=color)
+        if ((self._display.verbosity > 0
+                or verbose)
+                and no_verbose_override):
+            self._emit_line(deep_serialize(abridged_result), color=color)

         self._clean_results(result._result, result._task.action)
         self._handle_warnings(result._result)
@@ -396,7 +398,10 @@ class CallbackModule(CallbackBase):

     @staticmethod
     def _changed_or_not(result, host_string):
-        if result.get('changed', False):
+        if result.get('skipped', False):
+            msg = "%s | SKIPPED" % host_string
+            color = C.COLOR_SKIP
+        elif result.get('changed', False):
             msg = "%s | CHANGED" % host_string
             color = C.COLOR_CHANGED
         else:

Indeed, your original answer fixed the loop_control.label problem.

Your newer edited answer also adjusts the slightly misleading time measurement for elements in a loop.

[15:20:00] certbot : Obtain or renew certificates
$host | CHANGED - {'name': '$domain', 'http_listen_port': 12364} | 1m17s
$host | CHANGED - {'name': '$domain', 'http_listen_port': 12364} | 1m17s
$host | CHANGED - {'name': '$domain', 'http_listen_port': 12364} | 1m17s
[15:21:18] certbot : Force renew (new certificates only)
[15:17:04] certbot : Obtain or renew certificates
$host | CHANGED - {'name': '$domain', 'http_listen_port': 12364}
$host | CHANGED - {'name': '$domain', 'http_listen_port': 12364}
$host | CHANGED - {'name': '$domain', 'http_listen_port': 12364}
↳ $host | CHANGED | 1m6s
[15:18:11] certbot : Force renew (new certificates only)

@rsguhr - Just update comment with fixes for skipped loop items.