I would like to quickly monitor some hosts using commands like ps,dstat etc using ansible-playbook. The ansible
command itself perfectly does what I want, for instance I'd use:
ansible -m shell -a "ps -eo pcpu,user,args | sort -r -k1 | head -n5"
and it nicely prints all std output for every host like this:
localhost | success | rc=0 >> 0.0 root /sbin/init 0.0 root [kthreadd] 0.0 root [ksoftirqd/0] 0.0 root [migration/0] otherhost | success | rc=0 >> 0.0 root /sbin/init 0.0 root [kthreadd] 0.0 root [ksoftirqd/0] 0.0 root [migration/0]
However this requires me to keep a bunch of shell scripts around for every task which is not very 'ansible' so I put this in a playbook:
--- - hosts: all gather_facts: no tasks: - shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5
and run it with -vv
, but the output baiscally shows the dictionary content and newlines are not printed as such so this results in an unreadable mess like this:
changed: [localhost] => {"changed": true, "cmd": "ps -eo pcpu,user,args | sort -r -k1 head -n5 ", "delta": "0:00:00.015337", "end": "2013-12-13 10:57:25.680708", "rc": 0, "start": "2013-12-13 10:57:25.665371", "stderr": "", "stdout": "47.3 xxx Xvnc4 :24 -desktop xxx:24 (xxx) -auth /home/xxx/.Xauthority -geometry 1920x1200\n ....
I also tried adding register: var
and the a 'debug' task to show {{ var.stdout }}
but the result is of course the same.
Is there a way to get nicely formatted output from a command's stdout/stderr when run via a playbook? I can think of a number of possible ways (format output using sed? redirect output to file on the host then get that file back and echo it to the screen?), but with my limited knowledge of the shell/ansible it would take me a day to just try it out.
To capture the output, you need to specify your own variable into which the output will be saved. To achieve this, we use the 'register' parameter to record the output to a variable. Then use the 'debug' module to display the variable's content to standard out.
In Ansible, you can run any shell command on your Ansible hosts, the hosts you will be configuring with Ansible. These shell commands may have outputs. By default, the output is ignored. If you want to store the output in a variable and use it later, then you can use the Ansible register module.
Change the default callback for standard output When you run an Ansible playbook from the command line, you get messages printed to standard output (stdout). Ansible can only have a single callback responsible for handling stdout.
The debug
module could really use some love, but at the moment the best you can do is use this:
- hosts: all gather_facts: no tasks: - shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5 register: ps - debug: var=ps.stdout_lines
It gives an output like this:
ok: [host1] => { "ps.stdout_lines": [ "%CPU USER COMMAND", " 1.0 root /usr/bin/python", " 0.6 root sshd: root@notty ", " 0.2 root java", " 0.0 root sort -r -k1" ] } ok: [host2] => { "ps.stdout_lines": [ "%CPU USER COMMAND", " 4.0 root /usr/bin/python", " 0.6 root sshd: root@notty ", " 0.1 root java", " 0.0 root sort -r -k1" ] }
This is a start may be :
- hosts: all gather_facts: no tasks: - shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5 register: ps - local_action: command echo item with_items: ps.stdout_lines
NOTE: Docs regarding ps.stdout_lines
are covered here: ('Register Variables' chapter).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With