[ARVADOS] updated: 189ce25a32a5916194597665435b269192a9baec

git at public.curoverse.com git at public.curoverse.com
Mon Jun 16 15:11:10 EDT 2014


Summary of changes:
 .../workbench/app/assets/javascripts/log_viewer.js | 139 +++++++++++++++++++--
 .../app/assets/stylesheets/log_viewer.scss         |   7 ++
 apps/workbench/app/views/jobs/_show_log.html.erb   |  89 ++++++++-----
 3 files changed, 189 insertions(+), 46 deletions(-)

       via  189ce25a32a5916194597665435b269192a9baec (commit)
      from  02825a88733a13a58775774053fb0945e9adf693 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 189ce25a32a5916194597665435b269192a9baec
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Mon Jun 16 19:11:08 2014 +0000

    2883: Added overview, node column and sort by node, style tweaks.

diff --git a/apps/workbench/app/assets/javascripts/log_viewer.js b/apps/workbench/app/assets/javascripts/log_viewer.js
index e8bbac6..c9e871b 100644
--- a/apps/workbench/app/assets/javascripts/log_viewer.js
+++ b/apps/workbench/app/assets/javascripts/log_viewer.js
@@ -15,7 +15,12 @@ function addToLogViewer(logViewer, lines, taskState) {
 
             var message = v[12];
             var type = "";
+            var node = "";
             if (v11 !== "") {
+                if (!taskState.hasOwnProperty(v11)) {
+                    taskState[v11] = {};
+                }
+
                 if (/^stderr /.test(message)) {
                     message = message.substr(7);
                     if (/^crunchstat: /.test(message)) {
@@ -28,13 +33,31 @@ function addToLogViewer(logViewer, lines, taskState) {
                     }
                 } else {
                     if (/^success /.test(message)) {
-                        taskState[v11] = "success";
+                        taskState[v11].outcome = "success";
+                        taskState.success_count += 1;
                     }
                     else if (/^failure /.test(message)) {
-                        taskState[v11] = "failure";
+                        taskState[v11].outcome = "failure";
+                        taskState.failure_count += 1;
+                    }
+                    else {
+                        var child = message.match(/^child \d+ started on (.*)/);
+                        if (child != null) {
+                            taskState[v11].node = child[1];
+                            for (var i in logViewer.items) {
+                                if (i > 0) {
+                                    var val = logViewer.items[i].values();
+                                    if (val.taskid === v11) {
+                                        val.node = child[1];
+                                        logViewer.items[i].values(val);
+                                    }
+                                }
+                            }
+                        }
                     }
                     type = "task-dispatch";
                 }
+                node = taskState[v11].node;
             } else {
                 if (/^status: /.test(message)) {
                     type = "job-status";
@@ -46,8 +69,10 @@ function addToLogViewer(logViewer, lines, taskState) {
 
             logViewer.add({
                 id: logViewer.items.length,
+                ts: ts,
                 timestamp: ts.toLocaleDateString() + " " + ts.toLocaleTimeString(),
                 taskid: v11,
+                node: node,
                 message: message,
                 type: type
             });
@@ -59,31 +84,121 @@ function addToLogViewer(logViewer, lines, taskState) {
     logViewer.update();
 }
 
-function sortByTaskThenId(a, b, opt) {
+function sortById(a, b, opt) {
     a = a.values();
     b = b.values();
 
-    if (a["taskid"] === "" && b["taskid"] !== "") {
+    if (a["id"] > b["id"]) {
+        return 1;
+    }
+    if (a["id"] < b["id"]) {
+        return -1;
+    }
+    return 0;
+}
+
+function sortByTask(a, b, opt) {
+    var aa = a.values();
+    var bb = b.values();
+
+    if (aa["taskid"] === "" && bb["taskid"] !== "") {
         return -1;
     }
-    if (a["taskid"] !== "" && b["taskid"] === "") {
+    if (aa["taskid"] !== "" && bb["taskid"] === "") {
         return 1;
     }
 
-    if (a["taskid"] !== "" && b["taskid"] !== "") {
-        if (a["taskid"] > b["taskid"]) {
+    if (aa["taskid"] !== "" && bb["taskid"] !== "") {
+        if (aa["taskid"] > bb["taskid"]) {
             return 1;
         }
-        if (a["taskid"] < b["taskid"]) {
+        if (aa["taskid"] < bb["taskid"]) {
             return -1;
         }
     }
 
-    if (a["id"] > b["id"]) {
+    return sortById(a, b, opt);
+}
+
+function sortByNode(a, b, opt) {
+    var aa = a.values();
+    var bb = b.values();
+
+    if (aa["node"] === "" && bb["node"] !== "") {
+        return -1;
+    }
+    if (aa["node"] !== "" && bb["node"] === "") {
         return 1;
     }
-    if (a["id"] < b["id"]) {
-        return -1;
+
+    if (aa["node"] !== "" && bb["node"] !== "") {
+        if (aa["node"] > bb["node"]) {
+            return 1;
+        }
+        if (aa["node"] < bb["node"]) {
+            return -1;
+        }
+    }
+
+    return sortById(a, b, opt);
+}
+
+
+function dumbPluralize(n, s, p) {
+    if (typeof p === 'undefined') {
+        p = "s";
+    }
+    if (n == 0 || n > 1) {
+        return (s + p);
+    } else {
+        return s;
     }
-    return 0;
 }
+
+function generateJobOverview(id, logViewer, taskState) {
+    var html = "";
+
+    var first = logViewer.items[1];
+    var last = logViewer.items[logViewer.items.length-1];
+
+    {
+        html += "<div>";
+        html += "Started at " + first.values().timestamp;
+
+        var duration = (last.values().ts.getTime() - first.values().ts.getTime()) / 1000;
+
+        var hours = 0;
+        var minutes = 0;
+        var seconds;
+
+        if (duration >= 3600) {
+            hours = Math.floor(duration / 3600);
+            duration -= (hours * 3600);
+        }
+        if (duration >= 60) {
+            minutes = Math.floor(duration / 60);
+            duration -= (minutes * 60);
+        }
+        seconds = duration;
+
+        var tcount = taskState.success_count + taskState.failure_count;
+
+        html += ".  " + tcount + dumbPluralize(tcount, " task") + " completed in ";
+        if (hours > 0) {
+            html += hours + dumbPluralize(hours, " hour");
+        }
+        if (minutes > 0) {
+            html += " " + minutes + dumbPluralize(minutes, " minute");
+        }
+        if (seconds > 0) {
+            html += " " + seconds + dumbPluralize(seconds, " second");
+        }
+        html += ".  " + taskState.success_count + dumbPluralize(taskState.success_count, " success", "es");
+        html += ", " + taskState.failure_count + dumbPluralize(taskState.failure_count, " failure");
+
+        html += ".  Completed at " + last.values().timestamp;
+        html += "</div>";
+    }
+
+    $(id).html(html);
+}
\ No newline at end of file
diff --git a/apps/workbench/app/assets/stylesheets/log_viewer.scss b/apps/workbench/app/assets/stylesheets/log_viewer.scss
index 600c012..55a0df0 100644
--- a/apps/workbench/app/assets/stylesheets/log_viewer.scss
+++ b/apps/workbench/app/assets/stylesheets/log_viewer.scss
@@ -19,6 +19,9 @@
    th.taskid {
      width: 3em;
    }
+   th.node {
+     width: 8em;
+   }
    th.message {
      width: auto;
    }
@@ -38,4 +41,8 @@
      word-wrap: break-word;
    }
  }
+}
+
+.log-viewer-button {
+  width: 12em;
 }
\ No newline at end of file
diff --git a/apps/workbench/app/views/jobs/_show_log.html.erb b/apps/workbench/app/views/jobs/_show_log.html.erb
index 41cd08f..a224bc1 100644
--- a/apps/workbench/app/views/jobs/_show_log.html.erb
+++ b/apps/workbench/app/views/jobs/_show_log.html.erb
@@ -5,7 +5,7 @@ var logViewer = new List('log-viewer', {
   page: 10000,
 });
 
-var taskState = {};
+var taskState = {"success_count": 0, "failure_count": 0};
 
 var makeFilter = function() {
   var pass = [];
@@ -19,8 +19,8 @@ var makeFilter = function() {
     var v = false;
     if (item.values().taskid !== "") {
       for (a in pass) {
-        if (pass[a] == "successful-tasks" && taskState[item.values().taskid] == "success") { v = true; }
-        if (pass[a] == "failed-tasks" && taskState[item.values().taskid] == "failure") { v = true; }
+        if (pass[a] == "successful-tasks" && taskState[item.values().taskid].outcome == "success") { v = true; }
+        if (pass[a] == "failed-tasks" && taskState[item.values().taskid].outcome == "failure") { v = true; }
       }
     } else {
       v = true;
@@ -40,6 +40,7 @@ $.ajax('<%=j url_for logcollection %>/<%=j logcollection.files[0][1] %>').
     logViewer.filter();
     addToLogViewer(logViewer, data.split("\n"), taskState);
     logViewer.filter(makeFilter());
+    generateJobOverview("#log-viewer-overview", logViewer, taskState);
     $("#logloadspinner").detach();
   });
 <% else %>
@@ -61,11 +62,15 @@ $("#filter-none").on("click", function() {
 });
 
 $("#sort-by-time").on("change", function() {
-  logViewer.sort("id");
+  logViewer.sort("id", {sortFunction: sortById});
 });
 
 $("#sort-by-task").on("change", function() {
-  logViewer.sort("taskid", {sortFunction: sortByTaskThenId});
+  logViewer.sort("taskid", {sortFunction: sortByTask});
+});
+
+$("#sort-by-node").on("change", function() {
+  logViewer.sort("node", {sortFunction: sortByNode});
 });
 
 })();
@@ -74,49 +79,64 @@ $("#sort-by-task").on("change", function() {
 
 <div id="log-viewer">
 
-    <div class="radio-inline">
-      <label><input id="sort-by-time" type="radio" name="sort-radio" checked> Sort by time</label>
-    </div>
-    <div class="radio-inline">
-      <label><input id="sort-by-task" type="radio" name="sort-radio" > Sort by task</label>
-    </div>
+  <h3>Overview</h3>
+  <div id="log-viewer-overview"></div>
 
-  <div class="checkbox-inline">
-    <label><input id="show-crunch" type="checkbox" checked="true" class="toggle-filter"> Show crunch output</label>
-  </div>
-  <div class="checkbox-inline">
-    <label><input id="show-job-status" type="checkbox" checked="true" class="toggle-filter"> Show job status</label>
-  </div>
-  <div class="checkbox-inline">
-    <label><input id="show-task-dispatch" type="checkbox" checked="true" class="toggle-filter"> Show task dispatch</label>
-  </div>
-  <div class="checkbox-inline">
-    <label><input id="show-task-output" type="checkbox" checked="true" class="toggle-filter"> Show task output</label>
-  </div>
-  <div class="checkbox-inline">
-    <label><input id="show-crunchstat" type="checkbox" checked="true" class="toggle-filter"> Show compute usage</label>
-  </div>
-  <div class="checkbox-inline">
-    <label><input id="show-successful-tasks" type="checkbox" checked="true" class="toggle-filter"> Show successful tasks</label>
-  </div>
-  <div class="checkbox-inline">
-    <label><input id="show-failed-tasks" type="checkbox" checked="true" class="toggle-filter"> Show failed tasks</label>
-  </div>
-
-<div class="pull-right">
+  <div class="h3">Log
+
+<span class="pull-right">
     <button id="filter-all" class="btn">
       Select all
     </button>
     <button id="filter-none" class="btn">
       Select none
     </button>
+</span>
 </div>
 
+  <div>
+    <div class="radio-inline log-viewer-button" style="margin-left: 10px">
+      <label><input id="sort-by-time" type="radio" name="sort-radio" checked> Sort by time</label>
+    </div>
+    <div class="radio-inline log-viewer-button">
+      <label><input id="sort-by-node" type="radio" name="sort-radio" > Sort by node</label>
+    </div>
+
+    <div class="radio-inline log-viewer-button">
+      <label><input id="sort-by-task" type="radio" name="sort-radio" > Sort by task</label>
+    </div>
+    </div>
+
+  <div>
+    <div class="checkbox-inline log-viewer-button" style="margin-left: 10px">
+      <label><input id="show-crunch" type="checkbox" checked="true" class="toggle-filter"> Show crunch output</label>
+    </div>
+    <div class="checkbox-inline log-viewer-button">
+      <label><input id="show-job-status" type="checkbox" checked="true" class="toggle-filter"> Show job status</label>
+    </div>
+    <div class="checkbox-inline log-viewer-button">
+      <label><input id="show-task-dispatch" type="checkbox" checked="true" class="toggle-filter"> Show task dispatch</label>
+    </div>
+    <div class="checkbox-inline log-viewer-button">
+      <label><input id="show-task-output" type="checkbox" checked="true" class="toggle-filter"> Show task output</label>
+    </div>
+    <div class="checkbox-inline log-viewer-button">
+      <label><input id="show-crunchstat" type="checkbox" checked="true" class="toggle-filter"> Show compute usage</label>
+    </div>
+    <div class="checkbox-inline log-viewer-button">
+      <label><input id="show-successful-tasks" type="checkbox" checked="true" class="toggle-filter"> Show successful tasks</label>
+    </div>
+    <div class="checkbox-inline log-viewer-button">
+      <label><input id="show-failed-tasks" type="checkbox" checked="true" class="toggle-filter"> Show failed tasks</label>
+    </div>
+    </div>
+
   <table class="log-viewer-table">
     <thead>
       <tr>
         <th class="id" data-sort="id"></th>
         <th class="timestamp" data-sort="timestamp">Timestamp</th>
+        <th class="node"  data-sort="taskid">Node</th>
         <th class="type" data-sort="type">Log type</th>
         <th class="taskid"  data-sort="taskid">Task</th>
         <th class="message" data-sort="message">Message</th>
@@ -126,6 +146,7 @@ $("#sort-by-task").on("change", function() {
       <tr>
         <td class="id"></td>
         <td class="timestamp"></td>
+        <td class="node"></td>
         <td class="type"></td>
         <td class="taskid"></td>
         <td class="message"></td>

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list