12

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?

chicks
  • 1,911
  • 1
  • 13
  • 29
opticyclic
  • 489
  • 2
  • 4
  • 12

7 Answers7

4

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

13dimitar
  • 757
  • 4
  • 12
4

[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.

Dawny33
  • 2,816
  • 3
  • 24
  • 62
3

I solved this by adding

ignore_errors: true
register: results

to the no_log-task. This makes ansible continue to the next task, even when the task fails. Then for the next task define a debug task, which always fails and outputs the registered variable, but only runs when the previous task failed:

- name: Error output
  debug:
     var: results
  failed_when: true
  when:
     results is failed

So even with no_log: true, this will make ansible display the output of the failed task. This solution is not logging it to a file as requested but fullfils your need to 'see the log when failed' , and of course, you can redirect or use tee to output the full ansible output to a file, which will, with this solution also contain the the log of the failed task.

2

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.

Tensibai
  • 11,416
  • 2
  • 37
  • 63
0

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

yosefrow
  • 101
  • 1
-2

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"
}
Dawny33
  • 2,816
  • 3
  • 24
  • 62
-2

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....

sparq
  • 1