Repository: ansible/ansible
Pull request: default callback - add "show_task_path_on_failure" option
##### SUMMARY
<!--- Describe the change below, including rationale and design decisions -->
When running in verbosity <2, display the file and line number for tasks that fail. This provides
useful information without having to run at increased verbosity.

Fixes #64625

- [x] Add tests
<!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
- Feature Pull Request


##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below -->
`lib/ansible/plugins/callback/default.py`

Problem statement:
Add Filename and Line number to ansible_failed_task
<!--- Verify first that your feature was not already discussed on GitHub -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
<!--- Describe the new feature/improvement briefly below -->
I'd like to see variables added to ansible_failed_task which represent the filename and line of the task that failed.  This information is available inside the JUnit callback module already, but would be helpful to expose for better information in a rescue block notice.

##### ISSUE TYPE
- Feature Idea

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below, use your best guess if unsure -->
ansible_failed_task

##### ADDITIONAL INFORMATION
<!--- Describe how the feature would be used, why it is needed and what it would solve -->
The name of the task is nice, but in large projects may not be specific enough to hunt though and find the file/line to troubleshoot.  This is even worse if the names of tasks aren't unique.  This provide something like a slack task in a rescue block the ability to inform where the fault is possible to have come from.

<!--- Paste example playbooks or commands between quotes below -->
```yaml

```

<!--- HINT: You can also paste gist.github.com links for larger files -->

Hints from issue discussion:
Files identified in the description:
None

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
https://github.com/ansible/ansible/blob/9ccef9e8192084e9e6b38c36a38c820fc8bd66db/lib/ansible/plugins/strategy/__init__.py#L515
!component =lib/ansible/plugins/strategy/\_\_init\_\_.py
Files identified in the description:
* [`lib/ansible/plugins/strategy/__init__.py`](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/strategy/__init__.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
For reference: This is where the JUnit side of things gets access to this information https://github.com/ansible/ansible/blob/e2f85b3f6cfd56846e65cad51c5fe47c551e72dd/lib/ansible/plugins/callback/junit.py#L189 for example.
Files identified in the description:
* [`lib/ansible/plugins/strategy/\_\_init\_\_.py`](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/strategy/\_\_init\_\_.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
Hi @samdoran @jhg03a ,

Is this still open ? I have been using ansible for about a year now and would like to contribute.

Can you give me more information on where to begin. 

- From which branch to start ? 

- how to produce the first output ?

-  what is the expected output ?
@Tazminia 

Start by [setting up your development environment](https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html#common-environment-setup). Then read [this section](https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html#contributing-back-to-ansible) on contributing back to Ansible.

> what is the expected output ?

I believe the goal is to display the task path on failed tasks. Something like this:
```
PLAY [Local testing playbook] ******************************************************************************************************************

TASK [fail] ************************************************************************************************************************************
task path: /Users/sdoran/Projects/Vagrant/Ansible Lab/test-local.yml:6
fatal: [localhost]: FAILED! => {
    "changed": false
}

MSG:

Failed as requested from task

...ignoring

TASK [fail] ************************************************************************************************************************************
task path: /Users/sdoran/Projects/Vagrant/Ansible Lab/test-local.yml:10
fatal: [localhost]: FAILED! => {
    "changed": false
}

MSG:

Failed as requested from task


TASK [debug] ***********************************************************************************************************************************
ok: [localhost] => {}

MSG:

rescue


PLAY RECAP *************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=1    ignored=1
```

This information is displayed when running with `-vv` or higher verbosity, but I believe @jhg03a would like this information to be displayed only on failed tasks without having to increase verbosity.

You will need to modify this method in the default stdout callback plugin:
https://github.com/ansible/ansible/blob/d3f69434465c90aff9fb73f34c3d4b34609c94d0/lib/ansible/plugins/callback/default.py#L94-L94

This code in `_print_task_banner()` is what displays the task path information. https://github.com/ansible/ansible/blob/d3f69434465c90aff9fb73f34c3d4b34609c94d0/lib/ansible/plugins/callback/default.py#L242-L247

You'll have to use that same code but in the `v2_runner_on_failed()` method and wrap it in a conditional that checks the verbosity setting so the task path isn't printed twice if verbosity is set to two or higher.

It might make sense to put the task path printing in a private method since it looks like there are three places where it needs to be called.

Also, this should be a setting of the default stdout callback plugin that is disabled by default. Settings for plugins are configured via their documentation. You'll need to add the new option to the [default callback doc fragment](https://github.com/ansible/ansible/blob/d3f69434465c90aff9fb73f34c3d4b34609c94d0/lib/ansible/plugins/doc_fragments/default_callback.py).

You can test for the value of the option in the callback plugin with `self.get_option('show_task_path_on_failure')` or whatever you name the new setting.
Thank you for the clarification @samdoran , I will go through the documentation and update the issue as soon as possible.
Hello @jhg03a @samdoran,

can you please check the [PR](https://github.com/ansible/ansible/pull/65233) and let me know if i have to fix something ?

Commit message: default callback - add "show_task_path_on_failure" option

When running in verbosity <2, display the file and line number for tasks that fail. This provides
useful information without having to run at increased verbosity.

Co-authored-by: tahar.jegham <jeghamseifeddine@gmail.com>

Patch to review:
diff --git a/changelogs/fragments/64625-show-file-path-on-task-failure-callback-option.yml b/changelogs/fragments/64625-show-file-path-on-task-failure-callback-option.yml
new file mode 100644
index 00000000000000..42af5e8715602b
--- /dev/null
+++ b/changelogs/fragments/64625-show-file-path-on-task-failure-callback-option.yml
@@ -0,0 +1,5 @@
+minor_changes:
+  - >
+    default callback - add ``show_task_path_on_failure`` option to display file and
+    line number of tasks only on failed tasks when running at
+    normal verbosity lev (https://github.com/ansible/ansible/issues/64625)
diff --git a/lib/ansible/plugins/callback/default.py b/lib/ansible/plugins/callback/default.py
index 7872974d4f303a..cfb7760115483e 100644
--- a/lib/ansible/plugins/callback/default.py
+++ b/lib/ansible/plugins/callback/default.py
@@ -82,6 +82,9 @@ def v2_runner_on_failed(self, result, ignore_errors=False):
 
         if self._last_task_banner != result._task._uuid:
             self._print_task_banner(result._task)
+            path = result._task.get_path()
+            if path:
+                self._display.display(u"task path: %s" % path, color=C.COLOR_DEBUG)
 
         self._handle_exception(result._result, use_stderr=self.display_failed_stderr)
         self._handle_warnings(result._result)
@@ -91,10 +94,14 @@ def v2_runner_on_failed(self, result, ignore_errors=False):
 
         else:
             if delegated_vars:
+                if self._display.verbosity < 2 and self.get_option('show_task_path_on_failure'):
+                    self._print_task_path(result._task)
                 self._display.display("fatal: [%s -> %s]: FAILED! => %s" % (result._host.get_name(), delegated_vars['ansible_host'],
                                                                             self._dump_results(result._result)),
                                       color=C.COLOR_ERROR, stderr=self.display_failed_stderr)
             else:
+                if self._display.verbosity < 2 and self.get_option('show_task_path_on_failure'):
+                    self._print_task_path(result._task)
                 self._display.display("fatal: [%s]: FAILED! => %s" % (result._host.get_name(), self._dump_results(result._result)),
                                       color=C.COLOR_ERROR, stderr=self.display_failed_stderr)
 
@@ -199,6 +206,11 @@ def _task_start(self, task, prefix=None):
             if self.display_skipped_hosts and self.display_ok_hosts:
                 self._print_task_banner(task)
 
+    def _print_task_path(self, task):
+        path = task.get_path()
+        if path:
+            self._display.display(u"task path: %s" % path, color=C.COLOR_DEBUG)
+
     def _print_task_banner(self, task):
         # args can be specified as no_log in several places: in the task or in
         # the argument spec.  We can check whether the task is no_log but the
@@ -225,10 +237,9 @@ def _print_task_banner(self, task):
         else:
             checkmsg = ""
         self._display.banner(u"%s [%s%s]%s" % (prefix, task_name, args, checkmsg))
+
         if self._display.verbosity >= 2:
-            path = task.get_path()
-            if path:
-                self._display.display(u"task path: %s" % path, color=C.COLOR_DEBUG)
+            self._print_task_path(task)
 
         self._last_task_banner = task._uuid
 
diff --git a/lib/ansible/plugins/doc_fragments/default_callback.py b/lib/ansible/plugins/doc_fragments/default_callback.py
index df3966b937c424..55540726853fdc 100644
--- a/lib/ansible/plugins/doc_fragments/default_callback.py
+++ b/lib/ansible/plugins/doc_fragments/default_callback.py
@@ -82,4 +82,17 @@ class ModuleDocFragment(object):
         ini:
           - key: check_mode_markers
             section: defaults
+      show_task_path_on_failure:
+        name: Show file path on failed tasks
+        description:
+         When a task fails, display the path to the file containing the failed task and the line number.
+         This information is displayed automatically for every task when running with C(-vv) or greater verbosity.
+        type: bool
+        default: no
+        env:
+          - name: ANSIBLE_SHOW_TASK_PATH_ON_FAILURE
+        ini:
+          - key: show_task_path_on_failure
+            section: defaults
+        version_added: '2.11'
 '''


Code review comments:
diff_hunk: @@ -0,0 +1,5 @@
+minor_changes:
+  - >
+    default callback - add ``show_task_path_on_failure`` option to display file and
+    line number of tasks only on failed tasks when running at
+    normal verbosity lev (https://github.com/ansible/ansible/issues/64625)
path: changelogs/fragments/64625-show-file-path-on-task-failure-callback-option.yml
text: @user1:
```suggestion
    normal verbosity level (https://github.com/ansible/ansible/issues/64625)
```
?

diff_hunk: @@ -0,0 +1,5 @@
+minor_changes:
+  - >
path: changelogs/fragments/64625-show-file-path-on-task-failure-callback-option.yml
text: @user1:
Did you mean
```suggestion
  - >-
```