diff mbox series

[1/1] ui/knotty: print log paths for failed tasks in summary

Message ID 20240814135037.4018930-2-chris.laplante@agilent.com
State Accepted, archived
Commit 2852a478ab03a482989c3a7e247860ab4f0e9f3e
Headers show
Series ui/knotty: print log paths for failed tasks in summary | expand

Commit Message

chris.laplante@agilent.com Aug. 14, 2024, 1:50 p.m. UTC
From: Chris Laplante <chris.laplante@agilent.com>

When tasks fail, it's very frustrating to have to scroll up to find the
log path(s). Many of us have the muscle memory to navigate to the 'temp'
directories under tmp/work/, but new users do not.

This change enhances the final summary to include log paths (reported
via bb.build.TaskFailed events). Here's an example:

NOTE: Tasks Summary: Attempted 856 tasks of which 853 didn't need to be rerun and 3 failed.

Summary: 3 tasks failed:
  virtual:native:/home/chris/repos/poky/meta/recipes-core/ncurses/ncurses_6.5.bb:do_fetch
    log: /home/chris/repos/poky/build/tmp/work/x86_64-linux/ncurses-native/6.5/temp/log.do_fetch.1253462
  /home/chris/repos/poky/meta/recipes-core/ncurses/ncurses_6.5.bb:do_fetch
    log: /home/chris/repos/poky/build/tmp/work/core2-64-poky-linux/ncurses/6.5/temp/log.do_fetch.1253466
  virtual:nativesdk:/home/chris/repos/poky/meta/recipes-core/ncurses/ncurses_6.5.bb:do_fetch
    log: /home/chris/repos/poky/build/tmp/work/x86_64-nativesdk-pokysdk-linux/nativesdk-ncurses/6.5/temp/log.do_fetch.1253467
Summary: There were 3 WARNING messages.
Summary: There were 6 ERROR messages, returning a non-zero exit code.

Each log is rendered as a clickable hyperlink in the terminal. See
https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda

Signed-off-by: Chris Laplante <chris.laplante@agilent.com>
---
 lib/bb/ui/knotty.py | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

Comments

Richard Purdie Aug. 15, 2024, 2:08 p.m. UTC | #1
On Wed, 2024-08-14 at 09:50 -0400, Chris Laplante via lists.openembedded.org wrote:
> From: Chris Laplante <chris.laplante@agilent.com>
> 
> When tasks fail, it's very frustrating to have to scroll up to find the
> log path(s). Many of us have the muscle memory to navigate to the 'temp'
> directories under tmp/work/, but new users do not.
> 
> This change enhances the final summary to include log paths (reported
> via bb.build.TaskFailed events). Here's an example:
> 
> NOTE: Tasks Summary: Attempted 856 tasks of which 853 didn't need to be rerun and 3 failed.
> 
> Summary: 3 tasks failed:
>   virtual:native:/home/chris/repos/poky/meta/recipes-core/ncurses/ncurses_6.5.bb:do_fetch
>     log: /home/chris/repos/poky/build/tmp/work/x86_64-linux/ncurses-native/6.5/temp/log.do_fetch.1253462
>   /home/chris/repos/poky/meta/recipes-core/ncurses/ncurses_6.5.bb:do_fetch
>     log: /home/chris/repos/poky/build/tmp/work/core2-64-poky-linux/ncurses/6.5/temp/log.do_fetch.1253466
>   virtual:nativesdk:/home/chris/repos/poky/meta/recipes-core/ncurses/ncurses_6.5.bb:do_fetch
>     log: /home/chris/repos/poky/build/tmp/work/x86_64-nativesdk-pokysdk-linux/nativesdk-ncurses/6.5/temp/log.do_fetch.1253467
> Summary: There were 3 WARNING messages.
> Summary: There were 6 ERROR messages, returning a non-zero exit code.
> 
> Each log is rendered as a clickable hyperlink in the terminal. See
> https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
> 
> Signed-off-by: Chris Laplante <chris.laplante@agilent.com>
> ---
>  lib/bb/ui/knotty.py | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/bb/ui/knotty.py b/lib/bb/ui/knotty.py
> index f86999bb0..5956ab177 100644
> --- a/lib/bb/ui/knotty.py
> +++ b/lib/bb/ui/knotty.py
> @@ -640,7 +640,7 @@ def main(server, eventHandler, params, tf = TerminalFilter):
>      return_value = 0
>      errors = 0
>      warnings = 0
> -    taskfailures = []
> +    taskfailures = {}
>  
>      printintervaldelta = 10 * 60 # 10 minutes
>      printinterval = printintervaldelta
> @@ -726,6 +726,8 @@ def main(server, eventHandler, params, tf = TerminalFilter):
>              if isinstance(event, bb.build.TaskFailed):
>                  return_value = 1
>                  print_event_log(event, includelogs, loglines, termfilter)
> +                k = "{}:{}".format(event._fn, event._task)
> +                taskfailures[k] = event.logfile
>              if isinstance(event, bb.build.TaskBase):
>                  logger.info(event._message)
>                  continue
> @@ -821,7 +823,7 @@ def main(server, eventHandler, params, tf = TerminalFilter):
>  
>              if isinstance(event, bb.runqueue.runQueueTaskFailed):
>                  return_value = 1
> -                taskfailures.append(event.taskstring)
> +                taskfailures.setdefault(event.taskstring)
>                  logger.error(str(event))
>                  continue
>  
> @@ -942,11 +944,19 @@ def main(server, eventHandler, params, tf = TerminalFilter):
>      try:
>          termfilter.clearFooter()
>          summary = ""
> +        def print_hyperlink(url, link_text):
> +            start = f'\033]8;;{url}\033\\'
> +            end = '\033]8;;\033\\'
> +            return f'{start}{link_text}{end}'
> +
>          if taskfailures:
>              summary += pluralise("\nSummary: %s task failed:",
>                                   "\nSummary: %s tasks failed:", len(taskfailures))
> -            for failure in taskfailures:
> +            for (failure, log_file) in taskfailures.items():
>                  summary += "\n  %s" % failure
> +                if log_file:
> +                    hyperlink = print_hyperlink(f"file://{log_file}", log_file)
> +                    summary += "\n    log: {}".format(hyperlink)
>          if warnings:
>              summary += pluralise("\nSummary: There was %s WARNING message.",
>                                   "\nSummary: There were %s WARNING messages.", warnings)

Sorry for not replying sooner. Is this not going to print gibberish on
stream based output instead of console output?

At the very least I'd have expected an os.isatty() in there? Knotty
does that in various places and even the name hints it is both a tty
and non-tty driver.

Cheers,

Richard
chris.laplante@agilent.com Aug. 15, 2024, 2:11 p.m. UTC | #2
Hi Richard,

> Sorry for not replying sooner. Is this not going to print gibberish on stream
> based output instead of console output?
> 
> At the very least I'd have expected an os.isatty() in there? Knotty does that in
> various places and even the name hints it is both a tty and non-tty driver.

No problem :). Yes, absolutely. I will send a v2 with a check of os.isatty().

Thanks!
Chris
diff mbox series

Patch

diff --git a/lib/bb/ui/knotty.py b/lib/bb/ui/knotty.py
index f86999bb0..5956ab177 100644
--- a/lib/bb/ui/knotty.py
+++ b/lib/bb/ui/knotty.py
@@ -640,7 +640,7 @@  def main(server, eventHandler, params, tf = TerminalFilter):
     return_value = 0
     errors = 0
     warnings = 0
-    taskfailures = []
+    taskfailures = {}
 
     printintervaldelta = 10 * 60 # 10 minutes
     printinterval = printintervaldelta
@@ -726,6 +726,8 @@  def main(server, eventHandler, params, tf = TerminalFilter):
             if isinstance(event, bb.build.TaskFailed):
                 return_value = 1
                 print_event_log(event, includelogs, loglines, termfilter)
+                k = "{}:{}".format(event._fn, event._task)
+                taskfailures[k] = event.logfile
             if isinstance(event, bb.build.TaskBase):
                 logger.info(event._message)
                 continue
@@ -821,7 +823,7 @@  def main(server, eventHandler, params, tf = TerminalFilter):
 
             if isinstance(event, bb.runqueue.runQueueTaskFailed):
                 return_value = 1
-                taskfailures.append(event.taskstring)
+                taskfailures.setdefault(event.taskstring)
                 logger.error(str(event))
                 continue
 
@@ -942,11 +944,19 @@  def main(server, eventHandler, params, tf = TerminalFilter):
     try:
         termfilter.clearFooter()
         summary = ""
+        def print_hyperlink(url, link_text):
+            start = f'\033]8;;{url}\033\\'
+            end = '\033]8;;\033\\'
+            return f'{start}{link_text}{end}'
+
         if taskfailures:
             summary += pluralise("\nSummary: %s task failed:",
                                  "\nSummary: %s tasks failed:", len(taskfailures))
-            for failure in taskfailures:
+            for (failure, log_file) in taskfailures.items():
                 summary += "\n  %s" % failure
+                if log_file:
+                    hyperlink = print_hyperlink(f"file://{log_file}", log_file)
+                    summary += "\n    log: {}".format(hyperlink)
         if warnings:
             summary += pluralise("\nSummary: There was %s WARNING message.",
                                  "\nSummary: There were %s WARNING messages.", warnings)