Instantly share code, notes, and snippets.

Embed
What would you like to do?
# This gist is compatible with Ansible 1.x .
# For Ansible 2.x , please check out:
# - https://gist.github.com/dmsimard/cd706de198c85a8255f6
# - https://github.com/n0ts/ansible-human_log
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
FIELDS = ['cmd', 'command', 'start', 'end', 'delta', 'msg', 'stdout', 'stderr']
def human_log(res):
if type(res) == type(dict()):
for field in FIELDS:
if field in res.keys():
# use default encoding, check out sys.setdefaultencoding
print u'\n{0}:\n{1}'.format(field, res[field])
# or use specific encoding, e.g. utf-8
#print '\n{0}:\n{1}'.format(field, res[field].encode('utf-8'))
class CallbackModule(object):
def on_any(self, *args, **kwargs):
pass
def runner_on_failed(self, host, res, ignore_errors=False):
human_log(res)
def runner_on_ok(self, host, res):
human_log(res)
def runner_on_error(self, host, msg):
pass
def runner_on_skipped(self, host, item=None):
pass
def runner_on_unreachable(self, host, res):
human_log(res)
def runner_on_no_hosts(self):
pass
def runner_on_async_poll(self, host, res, jid, clock):
human_log(res)
def runner_on_async_ok(self, host, res, jid):
human_log(res)
def runner_on_async_failed(self, host, res, jid):
human_log(res)
def playbook_on_start(self):
pass
def playbook_on_notify(self, host, handler):
pass
def playbook_on_no_hosts_matched(self):
pass
def playbook_on_no_hosts_remaining(self):
pass
def playbook_on_task_start(self, name, is_conditional):
pass
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
pass
def playbook_on_setup(self):
pass
def playbook_on_import_for_host(self, host, imported_file):
pass
def playbook_on_not_import_for_host(self, host, missing_file):
pass
def playbook_on_play_start(self, pattern):
pass
def playbook_on_stats(self, stats):
pass
@steinim

This comment has been minimized.

steinim commented Aug 12, 2014

Very useful :)

I had a problem with outputting non-ascii characters. Have a look at my fork to see how I solved it: https://gist.github.com/steinim/e3ded0068d97682acb7e

@clamm

This comment has been minimized.

clamm commented Sep 16, 2014

Is it possible to keep the color coding in the console for the formatted output? (e.g. red for failed)

@petems

This comment has been minimized.

petems commented Dec 10, 2014

Hi @clifano, I'm getting:

>> UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\xa9’ in position 43991: ordinal not in range(128)

I tried using the

rint '\n{0}:\n{1}'.format(field, res[field].encode('utf-8'))

fix but it doesnt work with python 2.6

@semifocused

This comment has been minimized.

semifocused commented Feb 7, 2015

Nice! It would be helpful to be able to use it cleanly. Would you consider adding a license? Maybe something like:

# Licensed under the Apache License, Version 2.0.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0

Entirely up to you, of course.

@davidneudorfer

This comment has been minimized.

davidneudorfer commented Mar 12, 2015

Anyone else having an issue with double output in the callback plugin? https://gist.github.com/davidneudorfer/676855077351ebb17cef#file-gistfile1-txt

@crysalis

This comment has been minimized.

crysalis commented Mar 26, 2015

Yea
i having double output too

osx 10.9
ansible 1.8.4

@ibebian

This comment has been minimized.

ibebian commented Apr 21, 2015

+1 on the license.

++1 on retaining colored output on the pretty print, especially if the original out from -v can be suppressed.

Thanks a ton for sharing this, very nifty!

@SamKirsch10

This comment has been minimized.

SamKirsch10 commented Jun 8, 2015

Is there a way to only apply this to a specific playbook in the cfg file or otherwise? i don't want this output on another playbook I have

@msabramo

This comment has been minimized.

msabramo commented Jun 29, 2015

Very useful. Thanks! :+1 on clarifying what the license is.

@cliffano

This comment has been minimized.

Owner

cliffano commented Jul 25, 2015

@SamKirsch10 Why not specify the config file when you want to run the specific playbook?
Instead of placing the config file in current, home, or /etc/ansible directory, you can place it somewhere else, and then specify ANSIBLE_CONFIG env var when you want to run certain playbook. http://docs.ansible.com/ansible/intro_configuration.html

@cliffano

This comment has been minimized.

Owner

cliffano commented Jul 25, 2015

@msabramo @ibebian @semifocused Would GPL3 be suitable for your use? https://github.com/ansible/ansible/blob/devel/COPYING
I prefer to keep license consistent with whatever core has, but I'm happy to listen to any feedback you might have.

@doubinyang

This comment has been minimized.

doubinyang commented Jul 30, 2015

very userful.

@drazul

This comment has been minimized.

drazul commented Nov 19, 2015

This is a great plugin!

I add the feature to save same strings on ansible log. You can update with my gist if you want (there isn't pull request for gist).

My forked gist:
https://gist.github.com/drazul/144587760c41094a48d1

@dmsimard

This comment has been minimized.

dmsimard commented Nov 24, 2015

I forked a version that is compatible with Ansible 2 and also gives special treatment to the "results" field that is used by the yum and dnf modules.

It's here: https://gist.github.com/dmsimard/cd706de198c85a8255f6

Before:
changed: [localhost] => {"changed": true, "invocation": {"module_args": {"name": "python-openstackclient", "state": "present"}, "module_name": "dnf"}, "results": ["Installed: python-openstackclient-1.0.3-3.fc23.noarch", "Installed: python-unittest2-0.8.0-3.fc23.noarch", "Installed: python-keyring-5.0-2.fc23.noarch", "Installed: python-neutronclient-2.4.0-2.fc23.noarch", "Installed: python-keystoneclient-1:1.3.0-2.fc23.noarch", "Installed: python-jsonpointer-1.9-2.fc23.noarch", "Installed: python-warlock-1.0.1-3.fc23.noarch", "Installed: python-oslo-i18n-1.5.0-4.fc23.noarch", "Installed: python-novaclient-1:2.23.0-2.fc23.noarch", "Installed: python-fixtures-0.3.14-4.fc23.noarch", "Installed: python-testtools-1.8.0-2.fc23.noarch", "Installed: python-oslo-serialization-1.4.0-2.fc23.noarch", "Installed: python-iso8601-0.1.10-5.fc23.noarch", "Installed: python-oslo-utils-1.4.0-2.fc23.noarch", "Installed: python-msgpack-0.4.6-3.fc23.x86_64", "Installed: python-mimeparse-0.1.4-5.fc23.noarch", "Installed: python-webob-1.4.1-2.fc23.noarch", "Installed: python-jsonpatch-1.2-6.fc23.noarch", "Installed: python-cinderclient-1.2.1-1.fc23.noarch", "Installed: python-extras-0.0.3-7.fc23.noarch", "Installed: python-httplib2-0.9.1-2.fc23.noarch", "Installed: python-jsonschema-2.4.0-2.fc23.noarch", "Installed: python-glanceclient-1:0.17.0-3.fc23.noarch", "Installed: python-netifaces-0.10.4-2.fc23.x86_64"]}

=====

After:
results:
Installed: python-openstackclient-1.0.3-3.fc23.noarch
Installed: python-unittest2-0.8.0-3.fc23.noarch
Installed: python-keyring-5.0-2.fc23.noarch
Installed: python-neutronclient-2.4.0-2.fc23.noarch
Installed: python-keystoneclient-1:1.3.0-2.fc23.noarch
Installed: python-jsonpointer-1.9-2.fc23.noarch
Installed: python-warlock-1.0.1-3.fc23.noarch
Installed: python-oslo-i18n-1.5.0-4.fc23.noarch
Installed: python-novaclient-1:2.23.0-2.fc23.noarch
Installed: python-fixtures-0.3.14-4.fc23.noarch
Installed: python-testtools-1.8.0-2.fc23.noarch
Installed: python-oslo-serialization-1.4.0-2.fc23.noarch
Installed: python-iso8601-0.1.10-5.fc23.noarch
Installed: python-oslo-utils-1.4.0-2.fc23.noarch
Installed: python-msgpack-0.4.6-3.fc23.x86_64
Installed: python-mimeparse-0.1.4-5.fc23.noarch
Installed: python-webob-1.4.1-2.fc23.noarch
Installed: python-jsonpatch-1.2-6.fc23.noarch
Installed: python-cinderclient-1.2.1-1.fc23.noarch
Installed: python-extras-0.0.3-7.fc23.noarch
Installed: python-httplib2-0.9.1-2.fc23.noarch
Installed: python-jsonschema-2.4.0-2.fc23.noarch
Installed: python-glanceclient-1:0.17.0-3.fc23.noarch
Installed: python-netifaces-0.10.4-2.fc23.x86_64
@n0ts

This comment has been minimized.

n0ts commented Jan 19, 2016

Hi, I support ansible 2.0 human_log.py.
https://github.com/n0ts/ansible-human_log

Thanks.

@alexlawrence

This comment has been minimized.

alexlawrence commented Mar 3, 2016

I´m always getting the following error:

[WARNING]: Error when using <bound method CallbackModule.v2_runner_on_ok of
</Users/alexlawrence/projects/efa/sixsteps/sources/ansible/callback_plugins/human_log.CallbackModule object at 0x10dfcbd90>>: 'ascii' codec can't encode character u'\u03bc'
in position 696: ordinal not in range(128)

Tried both of the mentioned Version 2 compatible versions. Why is that?

@cliffano

This comment has been minimized.

Owner

cliffano commented Mar 3, 2016

Thanks @dmsimard and @nots , I'll update the gist and blog post with links to your forks.

@drazul Yea, too bad gist doesn't have more features. I thought a repo would be overkill for one simple file.

@snevs

This comment has been minimized.

snevs commented Mar 30, 2016

Hi,

For me, it doesn't work at all:

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

TASK: [shell ls -l /home/testuser1] ********************************************
<192.168.1.11> ESTABLISH CONNECTION FOR USER: testuser1
<192.168.1.11> REMOTE_MODULE command ls -l /home/testuser1 #USE_SHELL
<192.168.1.11> EXEC ssh -C -tt -vvv -o ControlMaster=auto -o ControlPersist=60s -o ControlPath="/home/testuser1/.ansible/cp/ansible-ssh-%h-%p-%r" -o Port=22 -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=60 192.168.1.11 /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1459331257.64-268749318559137 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1459331257.64-268749318559137 && echo $HOME/.ansible/tmp/ansible-tmp-1459331257.64-268749318559137'
<192.168.1.11> PUT /tmp/tmpEHSdFS TO /home/testuser1/.ansible/tmp/ansible-tmp-1459331257.64-268749318559137/command
<192.168.1.11> EXEC ssh -C -tt -vvv -o ControlMaster=auto -o ControlPersist=60s -o ControlPath="/home/testuser1/.ansible/cp/ansible-ssh-%h-%p-%r" -o Port=22 -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=60 192.168.1.11 /bin/sh -c 'LANG=C LC_CTYPE=C /usr/bin/python /home/testuser1/.ansible/tmp/ansible-tmp-1459331257.64-268749318559137/command; rm -rf /home/testuser1/.ansible/tmp/ansible-tmp-1459331257.64-268749318559137/ >/dev/null 2>&1'
changed: [192.168.1.11] => {"changed": true, "cmd": "ls -l /home/testuser1", "delta": "0:00:00.007463", "end": "2016-03-30 09:48:50.682502", "rc": 0, "start": "2016-03-30 09:48:50.675039", "stderr": "", "stdout": "total 0", "warnings": []}

TASK: [shell pwd] *************************************************************
<192.168.1.11> ESTABLISH CONNECTION FOR USER: testuser1
<192.168.1.11> REMOTE_MODULE command pwd #USE_SHELL
<192.168.1.11> EXEC ssh -C -tt -vvv -o ControlMaster=auto -o ControlPersist=60s -o ControlPath="/home/testuser1/.ansible/cp/ansible-ssh-%h-%p-%r" -o Port=22 -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=60 192.168.1.11 /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1459331279.72-7524347037387 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1459331279.72-7524347037387 && echo $HOME/.ansible/tmp/ansible-tmp-1459331279.72-7524347037387'
<192.168.1.11> PUT /tmp/tmpJNMLJj TO /home/testuser1/.ansible/tmp/ansible-tmp-1459331279.72-7524347037387/command
<192.168.1.11> EXEC ssh -C -tt -vvv -o ControlMaster=auto -o ControlPersist=60s -o ControlPath="/home/testuser1/.ansible/cp/ansible-ssh-%h-%p-%r" -o Port=22 -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=60 192.168.1.11 /bin/sh -c 'LANG=C LC_CTYPE=C /usr/bin/python /home/testuser1/.ansible/tmp/ansible-tmp-1459331279.72-7524347037387/command; rm -rf /home/testuser1/.ansible/tmp/ansible-tmp-1459331279.72-7524347037387/ >/dev/null 2>&1'
changed: [192.168.1.11] => {"changed": true, "cmd": "pwd", "delta": "0:00:00.004878", "end": "2016-03-30 09:48:51.042734", "rc": 0, "start": "2016-03-30 09:48:51.037856", "stderr": "", "stdout": "/home/testuser1", "warnings": []}

TASK: [shell uname -r] ********************************************************
<192.168.1.11> ESTABLISH CONNECTION FOR USER: testuser1
<192.168.1.11> REMOTE_MODULE command uname -r #USE_SHELL
<192.168.1.11> EXEC ssh -C -tt -vvv -o ControlMaster=auto -o ControlPersist=60s -o ControlPath="/home/testuser1/.ansible/cp/ansible-ssh-%h-%p-%r" -o Port=22 -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=60 192.168.1.11 /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1459331280.07-169513232619370 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1459331280.07-169513232619370 && echo $HOME/.ansible/tmp/ansible-tmp-1459331280.07-169513232619370'
<192.168.1.11> PUT /tmp/tmp0ENH6t TO /home/testuser1/.ansible/tmp/ansible-tmp-1459331280.07-169513232619370/command
<192.168.1.11> EXEC ssh -C -tt -vvv -o ControlMaster=auto -o ControlPersist=60s -o ControlPath="/home/testuser1/.ansible/cp/ansible-ssh-%h-%p-%r" -o Port=22 -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=60 192.168.1.11 /bin/sh -c 'LANG=C LC_CTYPE=C /usr/bin/python /home/testuser1/.ansible/tmp/ansible-tmp-1459331280.07-169513232619370/command; rm -rf /home/testuser1/.ansible/tmp/ansible-tmp-1459331280.07-169513232619370/ >/dev/null 2>&1'
changed: [192.168.1.11] => {"changed": true, "cmd": "uname -r", "delta": "0:00:00.006859", "end": "2016-03-30 09:48:51.417846", "rc": 0, "start": "2016-03-30 09:48:51.410987", "stderr": "", "stdout": "2.6.39-400.250.2.el6uek.x86_64", "warnings": []}

PLAY RECAP ********************************************************************
192.168.1.11 : ok=3 changed=3 unreachable=0 failed=0

@ltoscano-rh

This comment has been minimized.

ltoscano-rh commented May 10, 2016

It was raised in the past, but after updating it to support 2.0, why not pushing it to ansible (probably ansible-modules-extra)? It would be nice to have it available by default!

@Toub

This comment has been minimized.

Toub commented Jul 23, 2016

+1 for pushing it to ansible

@stevenlee87

This comment has been minimized.

stevenlee87 commented Aug 12, 2016

ansible 2.1.1.0 don't support
[WARNING]: Failure using method (v2_runner_on_ok) in callback plugin (</usr/share/ansible_plugins/callback_plugins/human_log.CallbackModule object at 0x7fbf1d78f910>): runner_on_ok() takes
exactly 3 arguments (2 given)

@snevs

This comment has been minimized.

snevs commented Oct 4, 2016

How to get rid of the double output? example: http://hastebin.com/obejuximun

@marcelloromani

This comment has been minimized.

marcelloromani commented Oct 25, 2016

@snevs: I tried this with ansible 1.9 and the only way I could have double output was by using -v flags.
So omit them and the double output is gone :)

@welchwilmerck

This comment has been minimized.

welchwilmerck commented Oct 31, 2016

Re: double output. It's just how plugins work - see https://gist.github.com/dmsimard/cd706de198c85a8255f6#gistcomment-1908752

@DanyC97

This comment has been minimized.

DanyC97 commented Nov 3, 2016

i have same issue like @stevenlee87 . Does it work for anyone running v 2.1+ ?

@jpic

This comment has been minimized.

jpic commented Nov 7, 2016

Such an output plugin was merged in Ansible and has been released in 2.2.

To enable it, just export ANSIBLE_STDOUT_CALLBACK=debug environment variable.

ansible/ansible#16839

@DanyC97: this version should work with 2.1, otherwise try something like this: https://github.com/openshift/openshift-ansible/blob/master/callback_plugins/default.py

@mikeifomin

This comment has been minimized.

mikeifomin commented Feb 2, 2017

@jpic big thanks to you!

@DanyC97

This comment has been minimized.

DanyC97 commented Feb 7, 2017

@jpic thank you !

@yashjaiswal

This comment has been minimized.

yashjaiswal commented Jun 27, 2017

@cliffano Using this, I get clean output but the output is not stored in ansible.log
Is there a way around that I use this callback, and also store logs in ansible.log, without having to print the output twice?

@nickallevato

This comment has been minimized.

nickallevato commented Aug 18, 2017

thank you for this!

@eromoe

This comment has been minimized.

eromoe commented Nov 7, 2017

May I ask how to use this ???

ansible -m ping all -vvvv has error on my machine, but the log is too long, I have no idea how to pretty print it.

@cronnelly

This comment has been minimized.

cronnelly commented Nov 8, 2017

@jpic Many thanks!

@rhibiscusc

This comment has been minimized.

rhibiscusc commented Dec 19, 2017

@alexlawrence do you have the error ( 'ascii' codec can't encode character u'\u03bc'
in position 696: ordinal not in range(128)) resolved? if so, would you please share the fix.

@shanedroid

This comment has been minimized.

shanedroid commented Feb 20, 2018

echoing the tanks here to @jpic - I had forked a version of this same plugin downstream from someone else only to find that with the version of ansible I am currently using 2.4.3.0 it was not even needed!

ansible/ansible#27078 (comment)
https://github.com/ansible/ansible/blob/v2.4.3.0-1/lib/ansible/plugins/callback/debug.py

@mahaboob

This comment has been minimized.

mahaboob commented May 21, 2018

Hi, i am new to Ansible. Can you please list the steps how to use it.
I have a playbook and i need to hook up this callback plugin to my playbook to create a log files.

any advise will be highly appreciated!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment