One of my ansible tasks imports an Oracle database using impdp.

This generates a lot of output to the console so I have set no_log: True.

However, when this fails I want to see the log!

How can I make this particular task log to a file and not to the console?

  • You're using the command module? – Xiong Chiamiov Jun 3 '17 at 16:10
  • One idea [more of a hack] would be to write the logs to some external file, and then having a task after it which makes use of failed_when condition, and remove the log file, if the prev. task was succesful :) – Dawny33 Jun 4 '17 at 14:46
  • Why can you see the console output during successful runs anyway? I've not seen a configuration for, nor did I think it was possible to, show stdout during a successful task execution, it should just come up [ ok: host name ]. However when an error is detected the output gets dumped to the ansible control console (and any ansible logs defined) would you mind sharing the configuration which gives you the large stdout during a regular successful run? – hvindin Jun 4 '17 at 15:00
  • @hvindin Put in -vvv after the ansible-playbook command for getting verbose logs. – Dawny33 Jun 5 '17 at 6:02
  • 1
    Registering a variable does seem the best logical move, see my comment on your answer for my opinions about what to do with the outputs from ansible triggered commands. – hvindin Jun 6 '17 at 13:44

[Converting my comment to an answer]

One way to do it would be to write the logs to some external file, and then having a task after it which makes use of failed_when condition, and remove the log file, if the previous task was successful.

Something like this should help you.

 - name: Run Py script
      command: <>.py  > <>.log
      become: yes
      register: PyScript
      ignore_errors: True

    - name: PyScript on success
      command: rm <>.log
      when: PyScript|succeeded

Note: This might not be the best way to handle your problem. But, this was a hack which helped me do my logging and monitoring.

  • 2
    I'd go one further and say you could keep your command writing to stdout/stderr then just dump them out as a response to a failure. So, as an example in your above example if you did want to halt execution in the event of a failure then using a fail task to just output the stdout and stderr registered in PyScript when the rc != 0 would seem a more holistic solution. If you use ansibles inbuilt mechanisms then if you have ansible logging set up on a control server, as an example, then that control server would log the failure in the ansible log. Which I think would be the correct place for it – hvindin Jun 6 '17 at 13:43

I think that all you need to do is to register the output of every command you need (store it in a variable) and then simply dump the variable in a file. That way you can review it later.

tasks:
  - name: Dump all vars
    action: template src=templates/dumpall.j2 dest=/tmp/ansible.all

Then in dumpall.j2:

Module Variables ("vars"):
--------------------------------
{{ vars | to_nice_json }} 

Environment Variables ("environment"):
--------------------------------
{{ environment | to_nice_json }} 

GROUP NAMES Variables ("group_names"):
--------------------------------
{{ group_names | to_nice_json }}

GROUPS Variables ("groups"):
--------------------------------
{{ groups | to_nice_json }}

HOST Variables ("hostvars"):
--------------------------------
{{ hostvars | to_nice_json }} 

The example I'm using is from here

What I do when I've a command to execute and wish to get the log only in case of failure is as follow (prefixed by a shell comamnd like /bin/sh -c '...' in case the initiator doesn't use a system call or execute the command directly without shell):

command 2&>1 > command-log.txt || cat command-log.txt

This will redirect error and standard output to a file and display the content of the file in case of failure only. If the command is very verbose and you don't wish to keep the log when it's ok you can go with:

command 2&>1 > command-log.txt && rm command-log.txt || cat command-log.txt

Quote for && and || usage from sh manpage:

The symbol && (||) causes the list following to be executed only if the preceding pipeline returns a zero (non zero) value.

That's probably not the most idiomatic way to do it with ansible but has the advantage of being very portable with any configuration management system giving the ability to display command stdout.

Assuming ansible properly throws errors to stderr you can capture the output of errors in any program to a file using output redirection:

some command 2> error.log

However I don't think this is the case.

Instead you will likely want to refer to this guide to decide when errors will occur http://docs.ansible.com/ansible/playbooks_error_handling.html and then grep your output for strings that indicate an error before outputting to a file

ie.

ansible-playbook my-playbook | grep 'error' > error.log

I think what you're looking for might be too simply redirect stdout and street to file.

Typically , some-command &> logfile.log

or some variant....

  • Which is only a partial answer, OP wants to see the log in case if error. – Tensibai Jun 4 '17 at 10:13
  • I don't this is even a partial answer to this question. It is fine for a shell script, but useless for coding in ansible. – chicks Jun 4 '17 at 12:01
  • @chicks I think it could be a valid workaround on a 'shell' method approach within ansible (which I don't know much) – Tensibai Jun 6 '17 at 14:13

Tee will be a very simple tool for logging, you can refer the following command.

eric@eric-MacBookPro:~$ ansible -m ping all | tee > /tmp/ansible.log
eric@eric-MacBookPro:~$ cat /tmp/ansible.log 
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
  • 2
    1. This affects the entire run, not just one task. 2. There's no point to piping through tee if you're going to redirect its stdout to a file; that's not how you use the command. 3. If you were using tee properly, it would still output all the spam to the console, which OP doesn't want. – Xiong Chiamiov Jun 3 '17 at 16:13

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.