How do I get logs/details of ansible-playbook modu

2020-05-11 03:28发布

问题:

Say I execute the following.

$ cat test.sh
#!/bin/bash
echo Hello World
exit 0

$ cat Hello.yml
---

- hosts: MyTestHost
  tasks:
  - name: Hello yourself
    script: test.sh


$ ansible-playbook  Hello.yml

PLAY [MyTestHost] ****************************************************************

GATHERING FACTS ***************************************************************
ok: [MyTestHost]

TASK: [Hello yourself] ********************************************************
ok: [MyTestHost]

PLAY RECAP ********************************************************************
MyTestHost                    : ok=2    changed=0    unreachable=0    failed=0

$

I know for sure that it was successful.

Where/how do I see the "Hello World" echo'ed/printed by my script on the remote host (MyTestHost)? Or the return/exit code of script?

My research shows me it would be possible to write a plugin to intercept module execution callbacks or something on those lines and write a log file. I would prefer to not waste my time with that.

E.g. something like the stdout in below (note that I'm running ansible and not ansible-playbook):

$ ansible plabb54 -i /project/plab/svn/plab-maintenance/ansible/plab_hosts.txt -m script -a ./test.sh
plabb54 | success >> {
    "rc": 0,
    "stderr": "",
    "stdout": "Hello World\n"
}

$

回答1:

If you pass the -v flag to ansible-playbook on the command line, you'll see the stdout and stderr for each task executed:

$ ansible-playbook -v playbook.yaml

Ansible also has built-in support for logging. Add the following lines to your ansible configuration file:

[defaults] 
log_path=/path/to/logfile

Ansible will look in several places for the config file:

  • ansible.cfg in the current directory where you ran ansible-playbook
  • ~/.ansible.cfg
  • /etc/ansible/ansible.cfg


回答2:

The playbook script task will generate stdout just like the non-playbook command, it just needs to be saved to a variable using register. Once we've got that, the debug module can print to the playbook output stream.

tasks:
- name: Hello yourself
  script: test.sh
  register: hello

- name: Debug hello
  debug: var=hello

- name: Debug hello.stdout as part of a string
  debug: "msg=The script's stdout was `{{ hello.stdout }}`."

Output should look something like this:

TASK: [Hello yourself] ******************************************************** 
changed: [MyTestHost]

TASK: [Debug hello] *********************************************************** 
ok: [MyTestHost] => {
    "hello": {
        "changed": true, 
        "invocation": {
            "module_args": "test.sh", 
            "module_name": "script"
        }, 
        "rc": 0, 
        "stderr": "", 
        "stdout": "Hello World\r\n", 
        "stdout_lines": [
            "Hello World"
        ]
    }
}

TASK: [Debug hello.stdout as part of a string] ******************************** 
ok: [MyTestHost] => {
    "msg": "The script's stdout was `Hello World\r\n`."
}


回答3:

There is also other way to generate log file.

Before running ansible-playbook run the following commands to enable logging:

  • Specify the location for the log file.

    export ANSIBLE_LOG_PATH=~/ansible.log

  • Enable Debug

    export ANSIBLE_DEBUG=True

  • To check that generated log file.

    less $ANSIBLE_LOG_PATH



回答4:

Using callback plugins, you can have the stdout of your commands output in readable form with the play: gist: human_log.py

Edit for example output:

 _____________________________________
< TASK: common | install apt packages >
 -------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


changed: [10.76.71.167] => (item=htop,vim-tiny,curl,git,unzip,update-motd,ssh-askpass,gcc,python-dev,libxml2,libxml2-dev,libxslt-dev,python-lxml,python-pip)

stdout:
Reading package lists...
Building dependency tree...
Reading state information...
libxslt1-dev is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 24 not upgraded.


stderr:

start:
2015-03-27 17:12:22.132237

end:
2015-03-27 17:12:22.136859


回答5:

Offical plugins

You can use the output callback plugins. For example, starting in Ansible 2.4, you can use the debug output callback plugin:

# In ansible.cfg:
[defaults]
stdout_callback = debug

(Altervatively, run export ANSIBLE_STDOUT_CALLBACK=debug before running your playbook)

Important: you must run ansible-playbook with the -v (--verbose) option to see the effect. With stdout_callback = debug set, the output should now look something like this:

TASK [Say Hello] ********************************
changed: [192.168.1.2] => {
    "changed": true,
    "rc": 0
}

STDOUT:


Hello!



STDERR:

Shared connection to 192.168.1.2 closed.

There are other modules besides the debug module if you want the output to be formatted differently. There's json, yaml, unixy, dense, minimal, etc. (full list).

For example, with stdout_callback = yaml, the output will look something like this:

TASK [Say Hello] **********************************
changed: [192.168.1.2] => changed=true 
  rc: 0
  stderr: |-
    Shared connection to 192.168.1.2 closed.
  stderr_lines:
  - Shared connection to 192.168.1.2 closed.
  stdout: |2-

    Hello!
  stdout_lines: <omitted>

Third-party plugins

If none of the official plugins are satisfactory, you can try the human_log plugin. There are a few versions:

  • https://github.com/n0ts/ansible-human_log

  • https://gist.github.com/cliffano/9868180



回答6:

Ansible command-line help, such as ansible-playbook --help shows how to increase output verbosity by setting the verbose mode (-v) to more verbosity (-vvv) or to connection debugging verbosity (-vvvv). This should give you some of the details you're after in stdout, which you can then be logged.