3782: keep log viewer code in _show_log.html.erb
[arvados.git] / apps / workbench / app / views / jobs / _show_log.html.erb
1 <% if !@object.log %>
2
3 <% log_history = stderr_log_history([@object.uuid]) %>
4 <div class="arv-log-event-listener arv-log-event-handler-append-logs arv-job-log-window" id="pipeline_event_log_div" data-object-uuids="<%= @object.uuid %>">
5   <% log_history.each do |entry| %>
6     <%=entry%><br/>
7   <% end %>
8 </div>
9
10 <% else %>
11
12 <script>
13 (function() {
14 var pagesize = 1000;
15 var logViewer = new List('log-viewer', {
16   valueNames: [ 'id', 'timestamp', 'taskid', 'message', 'type'],
17   page: pagesize
18 });
19
20 logViewer.page_offset = 0;
21 logViewer.on("updated", function() { updatePaging(".log-viewer-paging", logViewer, pagesize) } );
22 $(".log-viewer-page-up").on("click", function() { prevPage(logViewer, pagesize, ".log-viewer-paging"); return false; });
23 $(".log-viewer-page-down").on("click", function() { nextPage(logViewer, pagesize, ".log-viewer-paging"); return false; });
24
25 var taskState = newTaskState();
26
27 var makeFilter = function() {
28   var pass = [];
29   $(".toggle-filter, .radio-filter").each(function(i, e) {
30     if (e.checked) {
31       pass.push(e.id.substr(5));
32     }
33   });
34
35   return (function(item) {
36     var v = false;
37     if (item.values().taskid !== "") {
38       for (a in pass) {
39         if (pass[a] == "all-tasks") { v = true; }
40         else if (pass[a] == "successful-tasks" && taskState[item.values().taskid].outcome == "success") { v = true; }
41         else if (pass[a] == "failed-tasks" && taskState[item.values().taskid].outcome == "failure") { v = true; }
42       }
43     } else {
44       v = true;
45     }
46     for (a in pass) {
47       if (pass[a] == item.values().type) { return v; }
48     }
49     return false;
50   });
51 }
52
53 <% if @object.log %>
54   <% logcollection = Collection.find @object.log %>
55   <% if logcollection %>
56     var log_maxbytes = <%= Rails.configuration.log_viewer_max_bytes %>
57     $.ajax('<%=j url_for logcollection %>/<%=j logcollection.files[0][1] %>',
58            {
59              headers: {'Range': 'bytes=0-' + log_maxbytes}
60            }).
61         done(function(data, status, jqxhr) {
62             logViewer.filter();
63             addToLogViewer(logViewer, data.split("\n"), taskState);
64             logViewer.filter(makeFilter());
65             if (data.length == log_maxbytes) {
66               $("#log-viewer-overview").html(
67                 '<p>The log was truncated after ' + log_maxbytes +
68                 ' bytes. To view the entire log, run this command' +
69                 ' from an Arvados shell VM:</p>' +
70                 ' <p><span style="font-family:monospace">arv-get' +
71                 ' <%=j logcollection.uuid %>/<%=j logcollection.files[0][1] %>' +
72                 '</p>'
73               );
74             } else {
75               generateJobOverview("#log-viewer-overview", logViewer, taskState);
76             }
77             $("#log-viewer .spinner").detach();
78         }).
79         fail(function(jqxhr, status, error) {
80             $("#log-viewer .spinner").detach();
81         });
82   <% end %>
83 <% else %>
84   <%# Live log loading not implemented yet. %>
85 <% end %>
86
87 $(".toggle-filter, .radio-filter").on("change", function() {
88   logViewer.filter(makeFilter());
89 });
90
91 $("#filter-all").on("click", function() {
92   $(".toggle-filter").each(function(i, f) { f.checked = true; });
93   logViewer.filter(makeFilter());
94 });
95
96 $("#filter-none").on("click", function() {
97   $(".toggle-filter").each(function(i, f) { f.checked = false; console.log(f); });
98   logViewer.filter(makeFilter());
99 });
100
101 $("#sort-by-time").on("change", function() {
102   logViewer.sort("id", {sortFunction: sortById});
103 });
104
105 $("#sort-by-task").on("change", function() {
106   logViewer.sort("taskid", {sortFunction: sortByTask});
107 });
108
109 $("#sort-by-node").on("change", function() {
110   logViewer.sort("node", {sortFunction: sortByNode});
111 });
112
113 $("#set-show-failed-only").on("click", function() {
114   $("#sort-by-task").prop("checked", true);
115   $("#show-failed-tasks").prop("checked", true);
116   $("#show-crunch").prop("checked", false);
117   $("#show-task-dispatch").prop("checked", true);
118   $("#show-script-print").prop("checked", true);
119   $("#show-crunchstat").prop("checked", false);
120   logViewer.filter(makeFilter());
121   logViewer.sort("taskid", {sortFunction: sortByTask});
122 });
123
124 })();
125
126 </script>
127
128 <div id="log-viewer">
129
130   <h3>Summary</h3>
131   <p id="log-viewer-overview">
132     <% if !logcollection %>
133       The collection containing the job log was not found.
134     <% end %>
135   </p>
136
137   <div class="h3">Log
138
139     <span class="pull-right">
140       <% if @object.andand.tasks_summary.andand[:failed] and @object.tasks_summary[:failed] > 0 %>
141         <button id="set-show-failed-only" class="btn btn-danger">
142           Show failed task diagnostics only
143         </button>
144       <% end %>
145
146       <button id="filter-all" class="btn">
147         Select all
148       </button>
149       <button id="filter-none" class="btn">
150         Select none
151       </button>
152     </span>
153   </div>
154
155   <input class="search pull-right" style="margin-top: 1em" placeholder="Search" />
156
157   <div>
158     <div class="radio-inline log-viewer-button" style="margin-left: 10px">
159       <label><input id="sort-by-time" type="radio" name="sort-radio" checked> Sort by time</label>
160     </div>
161     <div class="radio-inline log-viewer-button">
162       <label><input id="sort-by-node" type="radio" name="sort-radio" > Sort by node</label>
163     </div>
164
165     <div class="radio-inline log-viewer-button">
166       <label><input id="sort-by-task" type="radio" name="sort-radio" > Sort by task</label>
167     </div>
168   </div>
169
170   <div>
171     <div class="radio-inline log-viewer-button" style="margin-left: 10px">
172       <label><input id="show-all-tasks" type="radio" name="show-tasks-group" checked="true" class="radio-filter"> Show all tasks</label>
173     </div>
174     <div class="radio-inline log-viewer-button">
175       <label><input id="show-successful-tasks" type="radio" name="show-tasks-group" class="radio-filter"> Only successful tasks</label>
176     </div>
177     <div class="radio-inline log-viewer-button">
178       <label><input id="show-failed-tasks" type="radio" name="show-tasks-group" class="radio-filter"> Only failed tasks</label>
179     </div>
180   </div>
181
182   <div>
183     <div class="checkbox-inline log-viewer-button" style="margin-left: 10px">
184       <label><input id="show-crunch" type="checkbox" checked="true" class="toggle-filter"> Show crunch diagnostics</label>
185     </div>
186     <div class="checkbox-inline log-viewer-button">
187       <label><input id="show-task-dispatch" type="checkbox" checked="true" class="toggle-filter"> Show task dispatch</label>
188     </div>
189     <div class="checkbox-inline log-viewer-button">
190       <label><input id="show-task-print" type="checkbox" checked="true" class="toggle-filter"> Show task diagnostics</label>
191     </div>
192     <div class="checkbox-inline log-viewer-button">
193       <label><input id="show-crunchstat" type="checkbox" checked="true" class="toggle-filter"> Show compute usage</label>
194     </div>
195
196   </div>
197
198   <div class="smart-scroll" data-smart-scroll-padding-bottom="50" style="margin-bottom: 0px">
199     <table class="log-viewer-table">
200       <thead>
201         <tr>
202           <th class="id" data-sort="id"></th>
203           <th class="timestamp" data-sort="timestamp">Timestamp</th>
204           <th class="node"  data-sort="node">Node</th>
205           <th class="slot"  data-sort="slot">Slot</th>
206           <th class="type" data-sort="type">Log type</th>
207           <th class="taskid"  data-sort="taskid">Task</th>
208           <th class="message" data-sort="message">Message</th>
209         </tr>
210       </thead>
211       <tbody class="list">
212         <tr>
213           <td class="id"></td>
214           <td class="timestamp"></td>
215           <td class="node"></td>
216           <td class="slot"></td>
217           <td class="type"></td>
218           <td class="taskid"></td>
219           <td class="message"></td>
220         </tr>
221       </tbody>
222     </table>
223
224     <% if @object.log and logcollection %>
225       <div class="spinner spinner-32px"></div>
226     <% end %>
227
228   </div>
229
230   <div class="log-viewer-paging-div" style="margin-bottom: -15px">
231     <a href="#" class="log-viewer-page-up"><span class='glyphicon glyphicon-arrow-up'></span></a>
232     <span class="log-viewer-paging"></span>
233     <a href="#" class="log-viewer-page-down"><span class='glyphicon glyphicon-arrow-down'></span></a>
234   </div>
235
236 </div>
237
238 <% end %>