We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
unixy callback fails with warning when using 'non strings' in debug's msg
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
Name of the module, plugin, task or feature
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path
-->
`unixy` callback plugin

##### ANSIBLE VERSION
ansible 2.6.0
  config file = //ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.14 (default, Dec 14 2017, 15:51:29) [GCC 6.4.0]

##### CONFIGURATION
ANSIBLE_COW_SELECTION(//ansible.cfg) = random
ANSIBLE_COW_WHITELIST(//ansible.cfg) = ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes']
ANSIBLE_NOCOWS(//ansible.cfg) = False
CACHE_PLUGIN(//ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(//ansible.cfg) = /fact_cache
CACHE_PLUGIN_TIMEOUT(//ansible.cfg) = 86400
DEFAULT_CALLBACK_WHITELIST(//ansible.cfg) = ['unixy']
DEFAULT_GATHERING(//ansible.cfg) = explicit
DEFAULT_GATHER_TIMEOUT(//ansible.cfg) = 10
DEFAULT_STDOUT_CALLBACK(//ansible.cfg) = unixy
DEFAULT_TIMEOUT(//ansible.cfg) = 10
DISPLAY_SKIPPED_HOSTS(//ansible.cfg) = False
HOST_KEY_CHECKING(//ansible.cfg) = False
SHOW_CUSTOM_STATS(//ansible.cfg) = True

##### OS / ENVIRONMENT
CentOS 7.4

##### SUMMARY
Looks like `unixy` cannot handle debug module with multiline msg
```
 [WARNING]: Failure using method (v2_runner_on_ok) in callback plugin (<ansible.plugins.callback.unixy.CallbackModule object at 0x7f4b37080c50>): cannot concatenate 'str' and 'list' objects
```

##### STEPS TO REPRODUCE
Enable `unixy` callback plugin in `ansible.cfg`

```
callback_whitelist = unixy
stdout_callback = unixy
show_custom_stats = true
display_skipped_hosts = false
```

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- debug:
    msg:
      - "Hello"
      - "World"
```

##### EXPECTED RESULTS
No warning and the full debug msg output displayed on console output

##### ACTUAL RESULTS
Output does not get printied. Just a warning. Verbose `-vvvv` output below
```
debug...
 [WARNING]: Failure using method (v2_runner_on_ok) in callback plugin (<ansible.plugins.callback.unixy.CallbackModule object at 0x7f6d7257fc50>): cannot concatenate 'str' and 'list' objects

Callback Exception:
  File "/usr/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py", line 375, in send_callback
    method(*new_args, **kwargs)
   File "/usr/lib/python2.7/site-packages/ansible/plugins/callback/unixy.py", line 125, in v2_runner_on_ok
    task_result = self._process_result_output(result, msg)
   File "/usr/lib/python2.7/site-packages/ansible/plugins/callback/unixy.py", line 78, in _process_result_output
    task_result += " | msg: " + result._result.get('msg')

META: ran handlers
META: ran handlers
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/ansible/plugins/callback/unixy.py`
Content:
```
1 # Copyright: (c) 2017, Allyson Bowles <@akatch>
2 # Copyright: (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
3 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4 
5 # Make coding more python3-ish
6 from __future__ import (absolute_import, division, print_function)
7 __metaclass__ = type
8 
9 DOCUMENTATION = '''
10     callback: unixy
11     type: stdout
12     author: Allyson Bowles <@akatch>
13     short_description: condensed Ansible output
14     version_added: 2.5
15     description:
16       - Consolidated Ansible output in the style of LINUX/UNIX startup logs.
17     extends_documentation_fragment:
18       - default_callback
19     requirements:
20       - set as stdout in configuration
21 '''
22 
23 from ansible.plugins.callback import CallbackBase
24 from ansible.utils.color import colorize, hostcolor
25 from ansible import constants as C
26 from os.path import basename
27 
28 
29 class CallbackModule(CallbackBase):
30 
31     '''
32     Design goals:
33     - Print consolidated output that looks like a *NIX startup log
34     - Defaults should avoid displaying unnecessary information wherever possible
35 
36     TODOs:
37     - Only display task names if the task runs on at least one host
38     - Add option to display all hostnames on a single line in the appropriate result color (failures may have a separate line)
39     - Consolidate stats display
40     - Display whether run is in --check mode
41     - Don't show play name if no hosts found
42     '''
43 
44     CALLBACK_VERSION = 2.0
45     CALLBACK_TYPE = 'stdout'
46     CALLBACK_NAME = 'unixy'
47 
48     def _run_is_verbose(self, result):
49         return ((self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result)
50 
51     def _get_task_display_name(self, task):
52         self.task_display_name = None
53         display_name = task.get_name().strip().split(" : ")
54 
55         task_display_name = display_name[-1]
56         if task_display_name.startswith("include"):
57             return
58         else:
59             self.task_display_name = task_display_name
60 
61     def _preprocess_result(self, result):
62         self.delegated_vars = result._result.get('_ansible_delegated_vars', None)
63         self._handle_exception(result._result)
64         self._handle_warnings(result._result)
65 
66     def _process_result_output(self, result, msg):
67         task_host = result._host.get_name()
68         task_result = "%s %s" % (task_host, msg)
69 
70         if self._run_is_verbose(result):
71             task_result = "%s %s: %s" % (task_host, msg, self._dump_results(result._result, indent=4))
72 
73         if self.delegated_vars:
74             task_delegate_host = self.delegated_vars['ansible_host']
75             task_result = "%s -> %s %s" % (task_host, task_delegate_host, msg)
76 
77         if result._result.get('msg') and result._result.get('msg') != "All items completed":
78             task_result += " | msg: " + result._result.get('msg')
79 
80         if result._result.get('stdout'):
81             task_result += " | stdout: " + result._result.get('stdout')
82 
83         if result._result.get('stderr'):
84             task_result += " | stderr: " + result._result.get('stderr')
85 
86         return task_result
87 
88     def v2_playbook_on_task_start(self, task, is_conditional):
89         self._get_task_display_name(task)
90         if self.task_display_name is not None:
91             self._display.display("%s..." % self.task_display_name)
92 
93     def v2_playbook_on_handler_task_start(self, task):
94         self._get_task_display_name(task)
95         if self.task_display_name is not None:
96             self._display.display("%s (via handler)... " % self.task_display_name)
97 
98     def v2_playbook_on_play_start(self, play):
99         # TODO display name of play and list of play hosts
100         # TODO don't display play name if no hosts in play
101         name = play.get_name().strip()
102         if name:
103             msg = u"\n- %s -" % name
104         else:
105             msg = u"---"
106 
107         self._display.display(msg)
108 
109     def v2_runner_on_failed(self, result, ignore_errors=False):
110         self._preprocess_result(result)
111         display_color = C.COLOR_ERROR
112         msg = "failed"
113 
114         task_result = self._process_result_output(result, msg)
115         self._display.display("  " + task_result, display_color)
116 
117     def v2_runner_on_ok(self, result, msg="ok", display_color=C.COLOR_OK):
118         self._preprocess_result(result)
119 
120         result_was_changed = ('changed' in result._result and result._result['changed'])
121         if result_was_changed:
122             msg = "done"
123             display_color = C.COLOR_CHANGED
124 
125         task_result = self._process_result_output(result, msg)
126         self._display.display("  " + task_result, display_color)
127 
128     def v2_runner_item_on_failed(self, result):
129         self.v2_runner_on_failed(result)
130 
131     def v2_runner_on_unreachable(self, result):
132         msg = "unreachable"
133         display_color = C.COLOR_UNREACHABLE
134         task_result = self._process_result_output(result, msg)
135 
136         self._display.display("  " + task_result, display_color)
137 
138     def v2_on_file_diff(self, result):
139         if result._task.loop and 'results' in result._result:
140             for res in result._result['results']:
141                 if 'diff' in res and res['diff'] and res.get('changed', False):
142                     diff = self._get_diff(res['diff'])
143                     if diff:
144                         self._display.display(diff)
145         elif 'diff' in result._result and result._result['diff'] and result._result.get('changed', False):
146             diff = self._get_diff(result._result['diff'])
147             if diff:
148                 self._display.display(diff)
149 
150     def v2_playbook_on_stats(self, stats):
151         self._display.display("\n- Play recap -", screen_only=True)
152 
153         hosts = sorted(stats.processed.keys())
154         for h in hosts:
155             # TODO how else can we display these?
156             t = stats.summarize(h)
157 
158             self._display.display(u"  %s : %s %s %s %s" % (
159                 hostcolor(h, t),
160                 colorize(u'ok', t['ok'], C.COLOR_OK),
161                 colorize(u'changed', t['changed'], C.COLOR_CHANGED),
162                 colorize(u'unreachable', t['unreachable'], C.COLOR_UNREACHABLE),
163                 colorize(u'failed', t['failures'], C.COLOR_ERROR)),
164                 screen_only=True
165             )
166 
167             self._display.display(u"  %s : %s %s %s %s" % (
168                 hostcolor(h, t, False),
169                 colorize(u'ok', t['ok'], None),
170                 colorize(u'changed', t['changed'], None),
171                 colorize(u'unreachable', t['unreachable'], None),
172                 colorize(u'failed', t['failures'], None)),
173                 log_only=True
174             )
175 
176     def v2_playbook_on_no_hosts_matched(self):
177         self._display.display("  No hosts found!", color=C.COLOR_DEBUG)
178 
179     def v2_playbook_on_no_hosts_remaining(self):
180         self._display.display("  Ran out of hosts!", color=C.COLOR_ERROR)
181 
182     def v2_playbook_on_start(self, playbook):
183         # TODO display whether this run is happening in check mode
184         self._display.display("Executing playbook %s" % basename(playbook._file_name))
185 
186         if self._display.verbosity > 3:
187             if self._options is not None:
188                 for option in dir(self._options):
189                     if option.startswith('_') or option in ['read_file', 'ensure_value', 'read_module']:
190                         continue
191                     val = getattr(self._options, option)
192                     if val:
193                         self._display.vvvv('%s: %s' % (option, val))
194 
195     def v2_runner_retry(self, result):
196         msg = "  Retrying... (%d of %d)" % (result._result['attempts'], result._result['retries'])
197         if (self._display.verbosity > 2 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result:
198             msg += "Result was: %s" % self._dump_results(result._result)
199         self._display.display(msg, color=C.COLOR_DEBUG)
200
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lib/ansible/plugins/callback/unixy.py b/lib/ansible/plugins/callback/unixy.py
--- a/lib/ansible/plugins/callback/unixy.py
+++ b/lib/ansible/plugins/callback/unixy.py
@@ -20,10 +20,12 @@
       - set as stdout in configuration
 '''
 
+from os.path import basename
+
+from ansible import constants as C
+from ansible.module_utils._text import to_text
 from ansible.plugins.callback import CallbackBase
 from ansible.utils.color import colorize, hostcolor
-from ansible import constants as C
-from os.path import basename
 
 
 class CallbackModule(CallbackBase):
@@ -75,7 +77,7 @@
             task_result = "%s -> %s %s" % (task_host, task_delegate_host, msg)
 
         if result._result.get('msg') and result._result.get('msg') != "All items completed":
-            task_result += " | msg: " + result._result.get('msg')
+            task_result += " | msg: " + to_text(result._result.get('msg'))
 
         if result._result.get('stdout'):
             task_result += " | stdout: " + result._result.get('stdout')

{"golden_diff": "diff --git a/lib/ansible/plugins/callback/unixy.py b/lib/ansible/plugins/callback/unixy.py\n--- a/lib/ansible/plugins/callback/unixy.py\n+++ b/lib/ansible/plugins/callback/unixy.py\n@@ -20,10 +20,12 @@\n       - set as stdout in configuration\n '''\n \n+from os.path import basename\n+\n+from ansible import constants as C\n+from ansible.module_utils._text import to_text\n from ansible.plugins.callback import CallbackBase\n from ansible.utils.color import colorize, hostcolor\n-from ansible import constants as C\n-from os.path import basename\n \n \n class CallbackModule(CallbackBase):\n@@ -75,7 +77,7 @@\n             task_result = \"%s -> %s %s\" % (task_host, task_delegate_host, msg)\n \n         if result._result.get('msg') and result._result.get('msg') != \"All items completed\":\n-            task_result += \" | msg: \" + result._result.get('msg')\n+            task_result += \" | msg: \" + to_text(result._result.get('msg'))\n \n         if result._result.get('stdout'):\n             task_result += \" | stdout: \" + result._result.get('stdout')\n", "issue": "unixy callback fails with warning when using 'non strings' in debug's msg\n<!---\r\nVerify first that your issue/request is not already reported on GitHub.\r\nAlso test if the latest release, and devel branch are affected too.\r\n-->\r\n\r\n##### ISSUE TYPE\r\n<!--- Pick one below and delete the rest -->\r\n - Bug Report\r\n\r\n##### COMPONENT NAME\r\n<!---\r\nName of the module, plugin, task or feature\r\nDo not include extra details here, e.g. \"vyos_command\" not \"the network module vyos_command\" or the full path\r\n-->\r\n`unixy` callback plugin\r\n\r\n##### ANSIBLE VERSION\r\nansible 2.6.0\r\n  config file = //ansible.cfg\r\n  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /usr/lib/python2.7/site-packages/ansible\r\n  executable location = /usr/bin/ansible\r\n  python version = 2.7.14 (default, Dec 14 2017, 15:51:29) [GCC 6.4.0]\r\n\r\n##### CONFIGURATION\r\nANSIBLE_COW_SELECTION(//ansible.cfg) = random\r\nANSIBLE_COW_WHITELIST(//ansible.cfg) = ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes']\r\nANSIBLE_NOCOWS(//ansible.cfg) = False\r\nCACHE_PLUGIN(//ansible.cfg) = jsonfile\r\nCACHE_PLUGIN_CONNECTION(//ansible.cfg) = /fact_cache\r\nCACHE_PLUGIN_TIMEOUT(//ansible.cfg) = 86400\r\nDEFAULT_CALLBACK_WHITELIST(//ansible.cfg) = ['unixy']\r\nDEFAULT_GATHERING(//ansible.cfg) = explicit\r\nDEFAULT_GATHER_TIMEOUT(//ansible.cfg) = 10\r\nDEFAULT_STDOUT_CALLBACK(//ansible.cfg) = unixy\r\nDEFAULT_TIMEOUT(//ansible.cfg) = 10\r\nDISPLAY_SKIPPED_HOSTS(//ansible.cfg) = False\r\nHOST_KEY_CHECKING(//ansible.cfg) = False\r\nSHOW_CUSTOM_STATS(//ansible.cfg) = True\r\n\r\n##### OS / ENVIRONMENT\r\nCentOS 7.4\r\n\r\n##### SUMMARY\r\nLooks like `unixy` cannot handle debug module with multiline msg\r\n```\r\n [WARNING]: Failure using method (v2_runner_on_ok) in callback plugin (<ansible.plugins.callback.unixy.CallbackModule object at 0x7f4b37080c50>): cannot concatenate 'str' and 'list' objects\r\n```\r\n\r\n##### STEPS TO REPRODUCE\r\nEnable `unixy` callback plugin in `ansible.cfg`\r\n\r\n```\r\ncallback_whitelist = unixy\r\nstdout_callback = unixy\r\nshow_custom_stats = true\r\ndisplay_skipped_hosts = false\r\n```\r\n\r\n<!--- Paste example playbooks or commands between quotes below -->\r\n```yaml\r\n- debug:\r\n    msg:\r\n      - \"Hello\"\r\n      - \"World\"\r\n```\r\n\r\n##### EXPECTED RESULTS\r\nNo warning and the full debug msg output displayed on console output\r\n\r\n##### ACTUAL RESULTS\r\nOutput does not get printied. Just a warning. Verbose `-vvvv` output below\r\n```\r\ndebug...\r\n [WARNING]: Failure using method (v2_runner_on_ok) in callback plugin (<ansible.plugins.callback.unixy.CallbackModule object at 0x7f6d7257fc50>): cannot concatenate 'str' and 'list' objects\r\n\r\nCallback Exception:\r\n  File \"/usr/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py\", line 375, in send_callback\r\n    method(*new_args, **kwargs)\r\n   File \"/usr/lib/python2.7/site-packages/ansible/plugins/callback/unixy.py\", line 125, in v2_runner_on_ok\r\n    task_result = self._process_result_output(result, msg)\r\n   File \"/usr/lib/python2.7/site-packages/ansible/plugins/callback/unixy.py\", line 78, in _process_result_output\r\n    task_result += \" | msg: \" + result._result.get('msg')\r\n\r\nMETA: ran handlers\r\nMETA: ran handlers\r\n```\r\n\n", "before_files": [{"content": "# Copyright: (c) 2017, Allyson Bowles <@akatch>\n# Copyright: (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\n# Make coding more python3-ish\nfrom __future__ import (absolute_import, division, print_function)\n__metaclass__ = type\n\nDOCUMENTATION = '''\n    callback: unixy\n    type: stdout\n    author: Allyson Bowles <@akatch>\n    short_description: condensed Ansible output\n    version_added: 2.5\n    description:\n      - Consolidated Ansible output in the style of LINUX/UNIX startup logs.\n    extends_documentation_fragment:\n      - default_callback\n    requirements:\n      - set as stdout in configuration\n'''\n\nfrom ansible.plugins.callback import CallbackBase\nfrom ansible.utils.color import colorize, hostcolor\nfrom ansible import constants as C\nfrom os.path import basename\n\n\nclass CallbackModule(CallbackBase):\n\n    '''\n    Design goals:\n    - Print consolidated output that looks like a *NIX startup log\n    - Defaults should avoid displaying unnecessary information wherever possible\n\n    TODOs:\n    - Only display task names if the task runs on at least one host\n    - Add option to display all hostnames on a single line in the appropriate result color (failures may have a separate line)\n    - Consolidate stats display\n    - Display whether run is in --check mode\n    - Don't show play name if no hosts found\n    '''\n\n    CALLBACK_VERSION = 2.0\n    CALLBACK_TYPE = 'stdout'\n    CALLBACK_NAME = 'unixy'\n\n    def _run_is_verbose(self, result):\n        return ((self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result)\n\n    def _get_task_display_name(self, task):\n        self.task_display_name = None\n        display_name = task.get_name().strip().split(\" : \")\n\n        task_display_name = display_name[-1]\n        if task_display_name.startswith(\"include\"):\n            return\n        else:\n            self.task_display_name = task_display_name\n\n    def _preprocess_result(self, result):\n        self.delegated_vars = result._result.get('_ansible_delegated_vars', None)\n        self._handle_exception(result._result)\n        self._handle_warnings(result._result)\n\n    def _process_result_output(self, result, msg):\n        task_host = result._host.get_name()\n        task_result = \"%s %s\" % (task_host, msg)\n\n        if self._run_is_verbose(result):\n            task_result = \"%s %s: %s\" % (task_host, msg, self._dump_results(result._result, indent=4))\n\n        if self.delegated_vars:\n            task_delegate_host = self.delegated_vars['ansible_host']\n            task_result = \"%s -> %s %s\" % (task_host, task_delegate_host, msg)\n\n        if result._result.get('msg') and result._result.get('msg') != \"All items completed\":\n            task_result += \" | msg: \" + result._result.get('msg')\n\n        if result._result.get('stdout'):\n            task_result += \" | stdout: \" + result._result.get('stdout')\n\n        if result._result.get('stderr'):\n            task_result += \" | stderr: \" + result._result.get('stderr')\n\n        return task_result\n\n    def v2_playbook_on_task_start(self, task, is_conditional):\n        self._get_task_display_name(task)\n        if self.task_display_name is not None:\n            self._display.display(\"%s...\" % self.task_display_name)\n\n    def v2_playbook_on_handler_task_start(self, task):\n        self._get_task_display_name(task)\n        if self.task_display_name is not None:\n            self._display.display(\"%s (via handler)... \" % self.task_display_name)\n\n    def v2_playbook_on_play_start(self, play):\n        # TODO display name of play and list of play hosts\n        # TODO don't display play name if no hosts in play\n        name = play.get_name().strip()\n        if name:\n            msg = u\"\\n- %s -\" % name\n        else:\n            msg = u\"---\"\n\n        self._display.display(msg)\n\n    def v2_runner_on_failed(self, result, ignore_errors=False):\n        self._preprocess_result(result)\n        display_color = C.COLOR_ERROR\n        msg = \"failed\"\n\n        task_result = self._process_result_output(result, msg)\n        self._display.display(\"  \" + task_result, display_color)\n\n    def v2_runner_on_ok(self, result, msg=\"ok\", display_color=C.COLOR_OK):\n        self._preprocess_result(result)\n\n        result_was_changed = ('changed' in result._result and result._result['changed'])\n        if result_was_changed:\n            msg = \"done\"\n            display_color = C.COLOR_CHANGED\n\n        task_result = self._process_result_output(result, msg)\n        self._display.display(\"  \" + task_result, display_color)\n\n    def v2_runner_item_on_failed(self, result):\n        self.v2_runner_on_failed(result)\n\n    def v2_runner_on_unreachable(self, result):\n        msg = \"unreachable\"\n        display_color = C.COLOR_UNREACHABLE\n        task_result = self._process_result_output(result, msg)\n\n        self._display.display(\"  \" + task_result, display_color)\n\n    def v2_on_file_diff(self, result):\n        if result._task.loop and 'results' in result._result:\n            for res in result._result['results']:\n                if 'diff' in res and res['diff'] and res.get('changed', False):\n                    diff = self._get_diff(res['diff'])\n                    if diff:\n                        self._display.display(diff)\n        elif 'diff' in result._result and result._result['diff'] and result._result.get('changed', False):\n            diff = self._get_diff(result._result['diff'])\n            if diff:\n                self._display.display(diff)\n\n    def v2_playbook_on_stats(self, stats):\n        self._display.display(\"\\n- Play recap -\", screen_only=True)\n\n        hosts = sorted(stats.processed.keys())\n        for h in hosts:\n            # TODO how else can we display these?\n            t = stats.summarize(h)\n\n            self._display.display(u\"  %s : %s %s %s %s\" % (\n                hostcolor(h, t),\n                colorize(u'ok', t['ok'], C.COLOR_OK),\n                colorize(u'changed', t['changed'], C.COLOR_CHANGED),\n                colorize(u'unreachable', t['unreachable'], C.COLOR_UNREACHABLE),\n                colorize(u'failed', t['failures'], C.COLOR_ERROR)),\n                screen_only=True\n            )\n\n            self._display.display(u\"  %s : %s %s %s %s\" % (\n                hostcolor(h, t, False),\n                colorize(u'ok', t['ok'], None),\n                colorize(u'changed', t['changed'], None),\n                colorize(u'unreachable', t['unreachable'], None),\n                colorize(u'failed', t['failures'], None)),\n                log_only=True\n            )\n\n    def v2_playbook_on_no_hosts_matched(self):\n        self._display.display(\"  No hosts found!\", color=C.COLOR_DEBUG)\n\n    def v2_playbook_on_no_hosts_remaining(self):\n        self._display.display(\"  Ran out of hosts!\", color=C.COLOR_ERROR)\n\n    def v2_playbook_on_start(self, playbook):\n        # TODO display whether this run is happening in check mode\n        self._display.display(\"Executing playbook %s\" % basename(playbook._file_name))\n\n        if self._display.verbosity > 3:\n            if self._options is not None:\n                for option in dir(self._options):\n                    if option.startswith('_') or option in ['read_file', 'ensure_value', 'read_module']:\n                        continue\n                    val = getattr(self._options, option)\n                    if val:\n                        self._display.vvvv('%s: %s' % (option, val))\n\n    def v2_runner_retry(self, result):\n        msg = \"  Retrying... (%d of %d)\" % (result._result['attempts'], result._result['retries'])\n        if (self._display.verbosity > 2 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result:\n            msg += \"Result was: %s\" % self._dump_results(result._result)\n        self._display.display(msg, color=C.COLOR_DEBUG)\n", "path": "lib/ansible/plugins/callback/unixy.py"}], "after_files": [{"content": "# Copyright: (c) 2017, Allyson Bowles <@akatch>\n# Copyright: (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\n# Make coding more python3-ish\nfrom __future__ import (absolute_import, division, print_function)\n__metaclass__ = type\n\nDOCUMENTATION = '''\n    callback: unixy\n    type: stdout\n    author: Allyson Bowles <@akatch>\n    short_description: condensed Ansible output\n    version_added: 2.5\n    description:\n      - Consolidated Ansible output in the style of LINUX/UNIX startup logs.\n    extends_documentation_fragment:\n      - default_callback\n    requirements:\n      - set as stdout in configuration\n'''\n\nfrom os.path import basename\n\nfrom ansible import constants as C\nfrom ansible.module_utils._text import to_text\nfrom ansible.plugins.callback import CallbackBase\nfrom ansible.utils.color import colorize, hostcolor\n\n\nclass CallbackModule(CallbackBase):\n\n    '''\n    Design goals:\n    - Print consolidated output that looks like a *NIX startup log\n    - Defaults should avoid displaying unnecessary information wherever possible\n\n    TODOs:\n    - Only display task names if the task runs on at least one host\n    - Add option to display all hostnames on a single line in the appropriate result color (failures may have a separate line)\n    - Consolidate stats display\n    - Display whether run is in --check mode\n    - Don't show play name if no hosts found\n    '''\n\n    CALLBACK_VERSION = 2.0\n    CALLBACK_TYPE = 'stdout'\n    CALLBACK_NAME = 'unixy'\n\n    def _run_is_verbose(self, result):\n        return ((self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result)\n\n    def _get_task_display_name(self, task):\n        self.task_display_name = None\n        display_name = task.get_name().strip().split(\" : \")\n\n        task_display_name = display_name[-1]\n        if task_display_name.startswith(\"include\"):\n            return\n        else:\n            self.task_display_name = task_display_name\n\n    def _preprocess_result(self, result):\n        self.delegated_vars = result._result.get('_ansible_delegated_vars', None)\n        self._handle_exception(result._result)\n        self._handle_warnings(result._result)\n\n    def _process_result_output(self, result, msg):\n        task_host = result._host.get_name()\n        task_result = \"%s %s\" % (task_host, msg)\n\n        if self._run_is_verbose(result):\n            task_result = \"%s %s: %s\" % (task_host, msg, self._dump_results(result._result, indent=4))\n\n        if self.delegated_vars:\n            task_delegate_host = self.delegated_vars['ansible_host']\n            task_result = \"%s -> %s %s\" % (task_host, task_delegate_host, msg)\n\n        if result._result.get('msg') and result._result.get('msg') != \"All items completed\":\n            task_result += \" | msg: \" + to_text(result._result.get('msg'))\n\n        if result._result.get('stdout'):\n            task_result += \" | stdout: \" + result._result.get('stdout')\n\n        if result._result.get('stderr'):\n            task_result += \" | stderr: \" + result._result.get('stderr')\n\n        return task_result\n\n    def v2_playbook_on_task_start(self, task, is_conditional):\n        self._get_task_display_name(task)\n        if self.task_display_name is not None:\n            self._display.display(\"%s...\" % self.task_display_name)\n\n    def v2_playbook_on_handler_task_start(self, task):\n        self._get_task_display_name(task)\n        if self.task_display_name is not None:\n            self._display.display(\"%s (via handler)... \" % self.task_display_name)\n\n    def v2_playbook_on_play_start(self, play):\n        # TODO display name of play and list of play hosts\n        # TODO don't display play name if no hosts in play\n        name = play.get_name().strip()\n        if name:\n            msg = u\"\\n- %s -\" % name\n        else:\n            msg = u\"---\"\n\n        self._display.display(msg)\n\n    def v2_runner_on_failed(self, result, ignore_errors=False):\n        self._preprocess_result(result)\n        display_color = C.COLOR_ERROR\n        msg = \"failed\"\n\n        task_result = self._process_result_output(result, msg)\n        self._display.display(\"  \" + task_result, display_color)\n\n    def v2_runner_on_ok(self, result, msg=\"ok\", display_color=C.COLOR_OK):\n        self._preprocess_result(result)\n\n        result_was_changed = ('changed' in result._result and result._result['changed'])\n        if result_was_changed:\n            msg = \"done\"\n            display_color = C.COLOR_CHANGED\n\n        task_result = self._process_result_output(result, msg)\n        self._display.display(\"  \" + task_result, display_color)\n\n    def v2_runner_item_on_failed(self, result):\n        self.v2_runner_on_failed(result)\n\n    def v2_runner_on_unreachable(self, result):\n        msg = \"unreachable\"\n        display_color = C.COLOR_UNREACHABLE\n        task_result = self._process_result_output(result, msg)\n\n        self._display.display(\"  \" + task_result, display_color)\n\n    def v2_on_file_diff(self, result):\n        if result._task.loop and 'results' in result._result:\n            for res in result._result['results']:\n                if 'diff' in res and res['diff'] and res.get('changed', False):\n                    diff = self._get_diff(res['diff'])\n                    if diff:\n                        self._display.display(diff)\n        elif 'diff' in result._result and result._result['diff'] and result._result.get('changed', False):\n            diff = self._get_diff(result._result['diff'])\n            if diff:\n                self._display.display(diff)\n\n    def v2_playbook_on_stats(self, stats):\n        self._display.display(\"\\n- Play recap -\", screen_only=True)\n\n        hosts = sorted(stats.processed.keys())\n        for h in hosts:\n            # TODO how else can we display these?\n            t = stats.summarize(h)\n\n            self._display.display(u\"  %s : %s %s %s %s\" % (\n                hostcolor(h, t),\n                colorize(u'ok', t['ok'], C.COLOR_OK),\n                colorize(u'changed', t['changed'], C.COLOR_CHANGED),\n                colorize(u'unreachable', t['unreachable'], C.COLOR_UNREACHABLE),\n                colorize(u'failed', t['failures'], C.COLOR_ERROR)),\n                screen_only=True\n            )\n\n            self._display.display(u\"  %s : %s %s %s %s\" % (\n                hostcolor(h, t, False),\n                colorize(u'ok', t['ok'], None),\n                colorize(u'changed', t['changed'], None),\n                colorize(u'unreachable', t['unreachable'], None),\n                colorize(u'failed', t['failures'], None)),\n                log_only=True\n            )\n\n    def v2_playbook_on_no_hosts_matched(self):\n        self._display.display(\"  No hosts found!\", color=C.COLOR_DEBUG)\n\n    def v2_playbook_on_no_hosts_remaining(self):\n        self._display.display(\"  Ran out of hosts!\", color=C.COLOR_ERROR)\n\n    def v2_playbook_on_start(self, playbook):\n        # TODO display whether this run is happening in check mode\n        self._display.display(\"Executing playbook %s\" % basename(playbook._file_name))\n\n        if self._display.verbosity > 3:\n            if self._options is not None:\n                for option in dir(self._options):\n                    if option.startswith('_') or option in ['read_file', 'ensure_value', 'read_module']:\n                        continue\n                    val = getattr(self._options, option)\n                    if val:\n                        self._display.vvvv('%s: %s' % (option, val))\n\n    def v2_runner_retry(self, result):\n        msg = \"  Retrying... (%d of %d)\" % (result._result['attempts'], result._result['retries'])\n        if (self._display.verbosity > 2 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result:\n            msg += \"Result was: %s\" % self._dump_results(result._result)\n        self._display.display(msg, color=C.COLOR_DEBUG)\n", "path": "lib/ansible/plugins/callback/unixy.py"}]}