Repository: kestra-io/kestra
Issue: Executions log tab: should be more realtime

Right now, we don't see a lot of information on running tasks.
We should at least display duration counter move to properly understand that the execution is running

Issue comments:

Pull request review comments:
It seems that the simple `humanizeDuration(this.delta());` produce a better result I think 
Take care here, some time we passed an execution, some time an taskrun (on loglist), we should adapt between both
see comment below about taskrun & execution, it may be better to have 2 props `execution` or `taskrun` to have the detect what is the end 
I made this quite strange code to handle inconsistant counter display.
the one existing looks like 

![flakycount](https://user-images.githubusercontent.com/5399780/146082158-e27118af-1d8d-41de-b22c-e1dd6a5e9e38.gif)

The new on I make in this PR looks like the following


![countnormal](https://user-images.githubusercontent.com/5399780/146082060-3960fc76-e40b-40de-95d6-56a98dc28bca.gif)




handled now
I only look at histories. it should be enough no , isn't it ?

Patch that resolved the issue:
diff --git a/ui/src/components/executions/Gantt.vue b/ui/src/components/executions/Gantt.vue
index 1b32155807..27b6ca6011 100644
--- a/ui/src/components/executions/Gantt.vue
+++ b/ui/src/components/executions/Gantt.vue
@@ -3,7 +3,9 @@
         <table class="table table-sm mb-0">
             <thead>
                 <tr class="bg-light">
-                    <th>{{ duration }}</th>
+                    <th>
+                        <real-time :histories="execution.state.histories" />
+                    </th>
                     <td v-for="(date, i) in dates" :key="i">
                         {{ date }}
                     </td>
@@ -67,11 +69,12 @@
     import {mapState} from "vuex";
     import humanizeDuration from "humanize-duration";
     import State from "../../utils/state";
+    import RealTime from "./RealTime.vue";
 
     const ts = date => new Date(date).getTime();
     const TASKRUN_THRESHOLD = 50
     export default {
-        components: {LogList},
+        components: {LogList, RealTime},
         data() {
             return {
                 colors: State.colorClass(),
@@ -173,7 +176,6 @@
             compute() {
                 this.computeSeries();
                 this.computeDates();
-                this.computeDuration();
             },
             delta() {
                 return this.stop() - this.start;
@@ -259,9 +261,6 @@
                 }
                 this.dates = dates;
             },
-            computeDuration() {
-                this.duration = humanizeDuration(this.delta());
-            },
             onTaskSelect(taskRun) {
                 taskRun = this.taskRun && this.taskRun.id === taskRun.id ? undefined : taskRun;
                 this.$store.commit("execution/setTaskRun", taskRun);
diff --git a/ui/src/components/executions/Logs.vue b/ui/src/components/executions/Logs.vue
index dbb8761ff4..eb33dab2c9 100644
--- a/ui/src/components/executions/Logs.vue
+++ b/ui/src/components/executions/Logs.vue
@@ -8,6 +8,7 @@
     import LogList from "../logs/LogList";
     import LogFilters from "../logs/LogFilters";
     import {mapState} from "vuex";
+
     export default {
         components: {LogList, LogFilters},
         computed: {
diff --git a/ui/src/components/executions/RealTime.vue b/ui/src/components/executions/RealTime.vue
new file mode 100644
index 0000000000..e538475296
--- /dev/null
+++ b/ui/src/components/executions/RealTime.vue
@@ -0,0 +1,73 @@
+<template>
+    <span v-b-tooltip.hover :title="duration" v-if="histories">{{ duration }}</span>
+</template>
+
+<script>
+    import humanizeDuration from "humanize-duration";
+    import State from "../../utils/state";
+    const ts = date => new Date(date).getTime();
+
+    export default {
+        props: {
+            histories: {
+                type: Array,
+                default: undefined
+            }
+        },
+        watch: {
+            histories(oldValue, newValue) {
+                if (oldValue[0].date !== newValue[0].date) {
+                    this.paint()
+                }
+            },
+        },
+        data () {
+            return   {
+                duration: "",
+                enabled: true
+            }
+        },
+        mounted() {
+            this.enabled = true
+            this.paint()
+        },
+        computed: {
+            start() {
+                return this.histories && this.histories.length && ts(this.histories[0].date);
+            },
+            lastStep() {
+                return this.histories[this.histories.length - 1]
+            }
+        },
+        methods: {
+            paint() {
+                const repaint = ()=> {
+                    this.computeDuration()
+                    if (this.enabled && this.histories && State.isRunning(this.lastStep.state)) {
+                        setTimeout(repaint, 200);
+                    }
+                }
+                setTimeout(repaint);
+            },
+            delta() {
+                return this.stop() - this.start;
+            },
+            computeDuration() {
+                const duration = humanizeDuration(this.delta(), {maxDecimalPoints: 0});
+                if (duration.endsWith(",")) {
+                    this.duration = duration.splice(duration.length - 1, 1)
+                }
+                this.duration = duration
+            },
+            stop() {
+                if (!this.histories || State.isRunning(this.lastStep.state)) {
+                    return +new Date();
+                }
+                return ts(this.lastStep.date)
+            },
+        },
+        destroyed() {
+            this.enabled = false
+        }
+    }
+</script>
diff --git a/ui/src/components/logs/LogList.vue b/ui/src/components/logs/LogList.vue
index 9a831f7ae6..aee4e09d55 100644
--- a/ui/src/components/logs/LogList.vue
+++ b/ui/src/components/logs/LogList.vue
@@ -41,7 +41,7 @@
                                 <div class="task-duration">
                                     <small class="mr-1">
                                         <clock />
-                                        {{ attempt.state.duration | humanizeDuration }}
+                                        <real-time class="ml-2" :histories="attempt.state.histories" />
                                     </small>
                                 </div>
 
@@ -154,6 +154,7 @@
     import Status from "../Status";
     import SubFlowLink from "../flows/SubFlowLink"
     import Kicon from "../Kicon"
+    import RealTime from "../executions/RealTime.vue";
 
     export default {
         components: {
@@ -167,6 +168,7 @@
             Status,
             SubFlowLink,
             Kicon,
+            RealTime
         },
         props: {
             level: {


Test patch: