Answers: <p>[Converting my comment to an answer]</p>
  
  <p>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.</p>
  
  <p>Something like this should help you.</p>
  
  <pre><code> - name: Run Py script
        command: &lt;&gt;.py  &gt; &lt;&gt;.log
        become: yes
        register: PyScript
        ignore_errors: True
  
      - name: PyScript on success
        command: rm &lt;&gt;.log
        when: PyScript|succeeded
  </code></pre>
  
  <p>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.</p>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-06T13:43:02.083Z
Answers: 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
Answers: hvindin
Answers: CC BY-SA 3.0
Answers: 2017-06-06T10:29:14.870Z
Answers: 2017-06-06T10:36:39.897Z
Answers: 2017-06-06T10:36:39.897Z
Answers: Dawny33
Answers: <p>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. </p>
  
  <pre><code>tasks:
    - name: Dump all vars
      action: template src=templates/dumpall.j2 dest=/tmp/ansible.all
  </code></pre>
  
  <p>Then in dumpall.j2:</p>
  
  <pre><code>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 }} 
  </code></pre>
  
  <p>The example I'm using is from <a href="https://coderwall.com/p/13lh6w/dump-all-variables" rel="nofollow noreferrer">here</a></p>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-05T07:20:17.617Z
Answers: 2017-06-05T07:27:49.990Z
Answers: 2017-06-05T07:27:49.990Z
Answers: 13dimitar
Answers: <p>I solved this by adding </p>
  
  <pre><code>ignore_errors: true
  register: results
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>- name: Error output
    debug:
       var: results
    failed_when: true
    when:
       results is failed
  </code></pre>
  
  <p>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.</p>
  
Answers: CC BY-SA 4.0
Answers: 2019-04-29T10:15:00.350Z
Answers: 2019-04-29T10:15:00.350Z
Answers: Robin Roevens
Answers: <p>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 <code>/bin/sh -c '...'</code> in case the initiator doesn't use a <code>system</code> call or execute the command directly without shell):</p>
  <pre><code>command 2&gt;&amp;1 &gt; command-log.txt || cat command-log.txt
  </code></pre>
  <p>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:</p>
  <pre><code>command 2&gt;&amp;1 &gt; command-log.txt &amp;&amp; rm command-log.txt || cat command-log.txt
  </code></pre>
  <p>Quote for <code>&amp;&amp;</code> and <code>||</code> usage from <a href="http://heirloom.sourceforge.net/sh/sh.1.html" rel="nofollow noreferrer">sh manpage</a>:</p>
  <blockquote>
  <p>The symbol &amp;&amp; (||) causes the list following to be executed only if
  the preceding pipeline returns a zero (non zero) value.</p>
  </blockquote>
  <p>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.</p>
  
Answers: CC BY-SA 4.0
Answers: 2020-07-29T18:27:02.440Z
Answers: I love this answer but I think the > and the & are swapped. Do you mean 'command 2>&1...' rather than 'command 2>&1...'?
Answers: Justin Wrobel
Answers: CC BY-SA 4.0
Answers: 2020-07-30T06:52:12.227Z
Answers: You're right, I probably typed it quickly at that time. Thanks for the heads up
Answers: Tensibai
Answers: CC BY-SA 4.0
Answers: 2020-07-31T18:35:21.227Z
Answers: Sadly, I wasn't able to get this to work within Ansible.
Answers: Justin Wrobel
Answers: CC BY-SA 4.0
Answers: 2017-06-06T14:25:58.197Z
Answers: 2020-07-30T06:52:40.987Z
Answers: 2020-07-30T06:52:40.987Z
Answers: Tensibai
Answers: <p>Assuming ansible properly throws errors to stderr you can capture the output of errors in any program to a file using output redirection:</p>
  
  <p><code>some command 2&gt; error.log</code></p>
  
  <p>However I don't think this is the case.</p>
  
  <p>Instead you will likely want to refer to this guide to decide when errors will occur <a href="http://docs.ansible.com/ansible/playbooks_error_handling.html" rel="nofollow noreferrer">http://docs.ansible.com/ansible/playbooks_error_handling.html</a> and then grep your output for strings that indicate an error before outputting to a file</p>
  
  <p>ie. </p>
  
  <p><code>ansible-playbook my-playbook | grep 'error' &gt; error.log</code></p>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-04T18:41:19.060Z
Answers: 2017-06-04T18:41:19.060Z
Answers: yosefrow
Answers: <p>Tee will be a very simple tool for logging, you can refer the following command.</p>
  
  <pre><code>eric@eric-MacBookPro:~$ ansible -m ping all | tee &gt; /tmp/ansible.log
  eric@eric-MacBookPro:~$ cat /tmp/ansible.log 
  localhost | SUCCESS =&gt; {
      "changed": false,
      "ping": "pong"
  }
  </code></pre>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-03T16:13:11.063Z
Answers: 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.
Answers: Xiong Chiamiov
Answers: CC BY-SA 3.0
Answers: 2017-06-03T02:23:22.113Z
Answers: 2017-06-04T14:59:00.820Z
Answers: 2017-06-04T14:59:00.820Z
Answers: Eric Zhang
Answers: <p>I think what you're looking for might be too simply redirect stdout and street to file.</p>
  
  <p>Typically ,     some-command  &amp;>  logfile.log </p>
  
  <p>or some variant....</p>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-04T10:13:51.357Z
Answers: Which is only a partial answer, OP wants to see the log in case if error.
Answers: Tensibai
Answers: CC BY-SA 3.0
Answers: 2017-06-04T12:01:52.833Z
Answers: I don't this is even a partial answer to this question.  It is fine for a shell script, but useless for coding in [tag:ansible].
Answers: chicks
Answers: CC BY-SA 3.0
Answers: 2017-06-06T14:13:23.523Z
Answers: @chicks I think it could be a valid workaround on a 'shell' method approach within ansible (which I don't know much)
Answers: Tensibai
Answers: CC BY-SA 3.0
Answers: 2017-06-04T04:45:59.363Z
Answers: 2017-06-04T04:45:59.363Z
Answers: sparq
Body: <p>One of my ansible tasks imports an Oracle database using <code>impdp</code>.</p>
  
  <p>This generates a <em>lot</em> of output to the console so I have set <code>no_log: True</code>.</p>
  
  <p>However, when this fails I want to see the log!</p>
  
  <p>How can I make this particular task log to a file and not to the console?</p>
  
Comments: CC BY-SA 3.0
Comments: 2017-06-03T16:10:30.197Z
Comments: You're using the command module?
Comments: Xiong Chiamiov
Comments: CC BY-SA 3.0
Comments: 2017-06-04T14:46:47.423Z
Comments: 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 :)
Comments: Dawny33
Comments: CC BY-SA 3.0
Comments: 2017-06-04T15:00:39.240Z
Comments: 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?
Comments: hvindin
Comments: CC BY-SA 3.0
Comments: 2017-06-05T06:02:53.133Z
Comments: @hvindin Put in `-vvv` after the `ansible-playbook` command for getting verbose logs.
Comments: Dawny33
Comments: CC BY-SA 3.0
Comments: 2017-06-05T19:52:18.860Z
Comments: Have you considered using less v's? Each one makes it all the more verbose.  Or perhaps running without verbose mode on at all, if a step fails ansible should print the entire stout/stderr/rc/etc. That causes the failure without any verbose logging.
Comments: hvindin
Comments: CC BY-SA 3.0
Comments: 2017-06-06T10:29:38.760Z
Comments: @hvindin Have expanded my comment to an [answer](https://devops.stackexchange.com/a/1304/46).  Does that help?
Comments: Dawny33
Comments: CC BY-SA 3.0
Comments: 2017-06-06T13:44:17.133Z
Comments: 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.
Comments: hvindin
Tags: <ansible><logging>
Title: How Do I Log Task Output To A File?
UserDisplayName: opticyclic
ThreadText: # How Do I Log Task Output To A File?
  
  (Asked by: username_0 on 2017-06-02)
  
  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?
  
  **Tags:** ansible, logging
  
  > **Comments:**
  > **username_1**: You're using the command module?  
  > **username_2**: 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 :)  
  > **username_3**: 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?  
  > **username_2**: @username_3 Put in `-vvv` after the `ansible-playbook` command for getting verbose logs.  
  > **username_3**: Have you considered using less v's? Each one makes it all the more verbose.  Or perhaps running without verbose mode on at all, if a step fails ansible should print the entire stout/stderr/rc/etc. That causes the failure without any verbose logging.  
  > **username_2**: @username_3 Have expanded my comment to an [answer](https://devops.stackexchange.com/a/1304/46).  Does that help?  
  > **username_3**: 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.  
  
  ---
  
  ## 7 answers
  
  ### Answer by username_2 on 2017-06-06. Score: 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.
  
  > **Comments:**
  > **username_3**: 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  
  
  ---
  
  ### Answer by username_4 on 2017-06-05. Score: 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](https://coderwall.com/p/13lh6w/dump-all-variables)
  
  
  ---
  
  ### Answer by username_5 on 2019-04-29. Score: 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.
  
  
  ---
  
  ### Answer by username_6 on 2017-06-06. Score: 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](http://heirloom.sourceforge.net/sh/sh.1.html):
  
  > 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.
  
  > **Comments:**
  > **username_7**: I love this answer but I think the > and the & are swapped. Do you mean 'command 2>&1...' rather than 'command 2>&1...'?  
  > **username_6**: You're right, I probably typed it quickly at that time. Thanks for the heads up  
  > **username_7**: Sadly, I wasn't able to get this to work within Ansible.  
  
  ---
  
  ### Answer by username_8 on 2017-06-04. Score: 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`
  
  
  ---
  
  ### Answer by username_9 on 2017-06-03. Score: -2
  
  Tee will be a very simple tool for logging, you can refer the following command.
  
  ```
  username_9@username_9-MacBookPro:~$ ansible -m ping all | tee > /tmp/ansible.log
  username_9@username_9-MacBookPro:~$ cat /tmp/ansible.log 
  localhost | SUCCESS => {
      "changed": false,
      "ping": "pong"
  }
  
  ```
  
  > **Comments:**
  > **username_1**: 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.  
  
  ---
  
  ### Answer by username_10 on 2017-06-04. Score: -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....
  
  > **Comments:**
  > **username_6**: Which is only a partial answer, OP wants to see the log in case if error.  
  > **username_11**: I don't this is even a partial answer to this question.  It is fine for a shell script, but useless for coding in [tag:ansible].  
  > **username_6**: @username_11 I think it could be a valid workaround on a 'shell' method approach within ansible (which I don't know much)  
  
  ---
  
  