0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 var shouldBlockUI = true;
0019
0020 $(document).ajaxStop(function () {
0021 if (shouldBlockUI) {
0022 $.unblockUI();
0023 shouldBlockUI = false;
0024 }
0025 });
0026
0027 $(document).ajaxStart(function () {
0028 if (shouldBlockUI) {
0029 $.blockUI({message: '<h3>Loading Stage Page...</h3>'});
0030 }
0031 });
0032
0033 $.extend( $.fn.dataTable.ext.type.order, {
0034 "duration-pre": ConvertDurationString,
0035
0036 "duration-asc": function ( a, b ) {
0037 a = ConvertDurationString( a );
0038 b = ConvertDurationString( b );
0039 return ((a < b) ? -1 : ((a > b) ? 1 : 0));
0040 },
0041
0042 "duration-desc": function ( a, b ) {
0043 a = ConvertDurationString( a );
0044 b = ConvertDurationString( b );
0045 return ((a < b) ? 1 : ((a > b) ? -1 : 0));
0046 }
0047 } );
0048
0049
0050
0051
0052 function stageEndPoint(appId) {
0053 var queryString = document.baseURI.split('?');
0054 var words = document.baseURI.split('/');
0055 var indexOfProxy = words.indexOf("proxy");
0056 var stageId = queryString[1].split("&").filter(word => word.includes("id="))[0].split("=")[1];
0057 if (indexOfProxy > 0) {
0058 var appId = words[indexOfProxy + 1];
0059 var newBaseURI = words.slice(0, words.indexOf("proxy") + 2).join('/');
0060 return newBaseURI + "/api/v1/applications/" + appId + "/stages/" + stageId;
0061 }
0062 var indexOfHistory = words.indexOf("history");
0063 if (indexOfHistory > 0) {
0064 var appId = words[indexOfHistory + 1];
0065 var appAttemptId = words[indexOfHistory + 2];
0066 var newBaseURI = words.slice(0, words.indexOf("history")).join('/');
0067 if (isNaN(appAttemptId) || appAttemptId == "0") {
0068 return newBaseURI + "/api/v1/applications/" + appId + "/stages/" + stageId;
0069 } else {
0070 return newBaseURI + "/api/v1/applications/" + appId + "/" + appAttemptId + "/stages/" + stageId;
0071 }
0072 }
0073 return location.origin + "/api/v1/applications/" + appId + "/stages/" + stageId;
0074 }
0075
0076 function getColumnNameForTaskMetricSummary(columnKey) {
0077 switch(columnKey) {
0078 case "executorRunTime":
0079 return "Duration";
0080
0081 case "jvmGcTime":
0082 return "GC Time";
0083
0084 case "gettingResultTime":
0085 return "Getting Result Time";
0086
0087 case "inputMetrics":
0088 return "Input Size / Records";
0089
0090 case "outputMetrics":
0091 return "Output Size / Records";
0092
0093 case "peakExecutionMemory":
0094 return "Peak Execution Memory";
0095
0096 case "resultSerializationTime":
0097 return "Result Serialization Time";
0098
0099 case "schedulerDelay":
0100 return "Scheduler Delay";
0101
0102 case "diskBytesSpilled":
0103 return "Spill (disk)";
0104
0105 case "memoryBytesSpilled":
0106 return "Spill (memory)";
0107
0108 case "shuffleReadMetrics":
0109 return "Shuffle Read Size / Records";
0110
0111 case "shuffleWriteMetrics":
0112 return "Shuffle Write Size / Records";
0113
0114 case "executorDeserializeTime":
0115 return "Task Deserialization Time";
0116
0117 case "shuffleReadBlockedTime":
0118 return "Shuffle Read Blocked Time";
0119
0120 case "shuffleRemoteReads":
0121 return "Shuffle Remote Reads";
0122
0123 default:
0124 return "NA";
0125 }
0126 }
0127
0128 function displayRowsForSummaryMetricsTable(row, type, columnIndex) {
0129 switch(row.columnKey) {
0130 case 'inputMetrics':
0131 var str = formatBytes(row.data.bytesRead[columnIndex], type) + " / " +
0132 row.data.recordsRead[columnIndex];
0133 return str;
0134 break;
0135
0136 case 'outputMetrics':
0137 var str = formatBytes(row.data.bytesWritten[columnIndex], type) + " / " +
0138 row.data.recordsWritten[columnIndex];
0139 return str;
0140 break;
0141
0142 case 'shuffleReadMetrics':
0143 var str = formatBytes(row.data.readBytes[columnIndex], type) + " / " +
0144 row.data.readRecords[columnIndex];
0145 return str;
0146 break;
0147
0148 case 'shuffleReadBlockedTime':
0149 var str = formatDuration(row.data.fetchWaitTime[columnIndex]);
0150 return str;
0151 break;
0152
0153 case 'shuffleRemoteReads':
0154 var str = formatBytes(row.data.remoteBytesRead[columnIndex], type);
0155 return str;
0156 break;
0157
0158 case 'shuffleWriteMetrics':
0159 var str = formatBytes(row.data.writeBytes[columnIndex], type) + " / " +
0160 row.data.writeRecords[columnIndex];
0161 return str;
0162 break;
0163
0164 default:
0165 return (row.columnKey == 'peakExecutionMemory' || row.columnKey == 'memoryBytesSpilled'
0166 || row.columnKey == 'diskBytesSpilled') ? formatBytes(
0167 row.data[columnIndex], type) : (formatDuration(row.data[columnIndex]));
0168
0169 }
0170 }
0171
0172 function createDataTableForTaskSummaryMetricsTable(taskSummaryMetricsTable) {
0173 var taskMetricsTable = "#summary-metrics-table";
0174 if ($.fn.dataTable.isDataTable(taskMetricsTable)) {
0175 taskSummaryMetricsDataTable.clear().draw();
0176 taskSummaryMetricsDataTable.rows.add(taskSummaryMetricsTable).draw();
0177 } else {
0178 var taskConf = {
0179 "data": taskSummaryMetricsTable,
0180 "columns": [
0181 {data : 'metric'},
0182
0183 {
0184 data: function (row, type) {
0185 return displayRowsForSummaryMetricsTable(row, type, 0);
0186 }
0187 },
0188
0189 {
0190 data: function (row, type) {
0191 return displayRowsForSummaryMetricsTable(row, type, 1);
0192 }
0193 },
0194
0195 {
0196 data: function (row, type) {
0197 return displayRowsForSummaryMetricsTable(row, type, 2);
0198 }
0199 },
0200
0201 {
0202 data: function (row, type) {
0203 return displayRowsForSummaryMetricsTable(row, type, 3);
0204 }
0205 },
0206
0207 {
0208 data: function (row, type) {
0209 return displayRowsForSummaryMetricsTable(row, type, 4);
0210 }
0211 }
0212 ],
0213 "columnDefs": [
0214 { "type": "duration", "targets": 1 },
0215 { "type": "duration", "targets": 2 },
0216 { "type": "duration", "targets": 3 },
0217 { "type": "duration", "targets": 4 },
0218 { "type": "duration", "targets": 5 }
0219 ],
0220 "paging": false,
0221 "searching": false,
0222 "order": [[0, "asc"]],
0223 "bSort": false,
0224 "bAutoWidth": false,
0225 "oLanguage": {
0226 "sEmptyTable": "No tasks have reported metrics yet"
0227 }
0228 };
0229 taskSummaryMetricsDataTable = $(taskMetricsTable).DataTable(taskConf);
0230 }
0231 taskSummaryMetricsTableCurrentStateArray = taskSummaryMetricsTable.slice();
0232 }
0233
0234 function createRowMetadataForColumn(colKey, data, checkboxId) {
0235 var row = {
0236 "metric": getColumnNameForTaskMetricSummary(colKey),
0237 "data": data,
0238 "checkboxId": checkboxId,
0239 "columnKey": colKey
0240 };
0241 return row;
0242 }
0243
0244 function reselectCheckboxesBasedOnTaskTableState() {
0245 var allChecked = true;
0246 var taskSummaryMetricsTableCurrentFilteredArray = taskSummaryMetricsTableCurrentStateArray.slice();
0247 if (typeof taskTableSelector !== 'undefined' && taskSummaryMetricsTableCurrentStateArray.length > 0) {
0248 for (var k = 0; k < optionalColumns.length; k++) {
0249 if (taskTableSelector.column(optionalColumns[k]).visible()) {
0250 $("#box-"+optionalColumns[k]).prop('checked', true);
0251 taskSummaryMetricsTableCurrentStateArray.push(taskSummaryMetricsTableArray.filter(row => (row.checkboxId).toString() == optionalColumns[k])[0]);
0252 taskSummaryMetricsTableCurrentFilteredArray = taskSummaryMetricsTableCurrentStateArray.slice();
0253 } else {
0254 allChecked = false;
0255 }
0256 }
0257 if (allChecked) {
0258 $("#box-0").prop('checked', true);
0259 }
0260 createDataTableForTaskSummaryMetricsTable(taskSummaryMetricsTableCurrentFilteredArray);
0261 }
0262 }
0263
0264 function getStageAttemptId() {
0265 var words = document.baseURI.split('?');
0266 var digitsRegex = /[0-9]+/;
0267
0268
0269 var stgAttemptId = words[1].split("&").filter(
0270 word => word.includes("attempt="))[0].split("=")[1].match(digitsRegex);
0271 return stgAttemptId;
0272 }
0273
0274 var taskSummaryMetricsTableArray = [];
0275 var taskSummaryMetricsTableCurrentStateArray = [];
0276 var taskSummaryMetricsDataTable;
0277 var optionalColumns = [11, 12, 13, 14, 15, 16, 17];
0278 var taskTableSelector;
0279
0280 $(document).ready(function () {
0281 setDataTableDefaults();
0282
0283 $("#showAdditionalMetrics").append(
0284 "<div><a id='additionalMetrics'>" +
0285 "<span class='expand-input-rate-arrow arrow-closed' id='arrowtoggle1'></span>" +
0286 " Show Additional Metrics" +
0287 "</a></div>" +
0288 "<div class='container-fluid container-fluid-div' id='toggle-metrics' hidden>" +
0289 "<div id='select_all' class='select-all-checkbox-div'><input type='checkbox' class='toggle-vis' id='box-0' data-column='0'> Select All</div>" +
0290 "<div id='scheduler_delay' class='scheduler-delay-checkbox-div'><input type='checkbox' class='toggle-vis' id='box-11' data-column='11'> Scheduler Delay</div>" +
0291 "<div id='task_deserialization_time' class='task-deserialization-time-checkbox-div'><input type='checkbox' class='toggle-vis' id='box-12' data-column='12'> Task Deserialization Time</div>" +
0292 "<div id='shuffle_read_blocked_time' class='shuffle-read-blocked-time-checkbox-div'><input type='checkbox' class='toggle-vis' id='box-13' data-column='13'> Shuffle Read Blocked Time</div>" +
0293 "<div id='shuffle_remote_reads' class='shuffle-remote-reads-checkbox-div'><input type='checkbox' class='toggle-vis' id='box-14' data-column='14'> Shuffle Remote Reads</div>" +
0294 "<div id='result_serialization_time' class='result-serialization-time-checkbox-div'><input type='checkbox' class='toggle-vis' id='box-15' data-column='15'> Result Serialization Time</div>" +
0295 "<div id='getting_result_time' class='getting-result-time-checkbox-div'><input type='checkbox' class='toggle-vis' id='box-16' data-column='16'> Getting Result Time</div>" +
0296 "<div id='peak_execution_memory' class='peak-execution-memory-checkbox-div'><input type='checkbox' class='toggle-vis' id='box-17' data-column='17'> Peak Execution Memory</div>" +
0297 "</div>");
0298
0299 $('#scheduler_delay').attr("data-toggle", "tooltip")
0300 .attr("data-placement", "top")
0301 .attr("title", "Scheduler delay includes time to ship the task from the scheduler to the executor, and time to send " +
0302 "the task result from the executor to the scheduler. If scheduler delay is large, consider decreasing the size of tasks or decreasing the size of task results.");
0303 $('#task_deserialization_time').attr("data-toggle", "tooltip")
0304 .attr("data-placement", "top")
0305 .attr("title", "Time spent deserializing the task closure on the executor, including the time to read the broadcasted task.");
0306 $('#shuffle_read_blocked_time').attr("data-toggle", "tooltip")
0307 .attr("data-placement", "top")
0308 .attr("title", "Time that the task spent blocked waiting for shuffle data to be read from remote machines.");
0309 $('#shuffle_remote_reads').attr("data-toggle", "tooltip")
0310 .attr("data-placement", "top")
0311 .attr("title", "Total shuffle bytes read from remote executors. This is a subset of the shuffle read bytes; the remaining shuffle data is read locally. ");
0312 $('#result_serialization_time').attr("data-toggle", "tooltip")
0313 .attr("data-placement", "top")
0314 .attr("title", "Time spent serializing the task result on the executor before sending it back to the driver.");
0315 $('#getting_result_time').attr("data-toggle", "tooltip")
0316 .attr("data-placement", "top")
0317 .attr("title", "Time that the driver spends fetching task results from workers. If this is large, consider decreasing the amount of data returned from each task.");
0318 $('#peak_execution_memory').attr("data-toggle", "tooltip")
0319 .attr("data-placement", "top")
0320 .attr("title", "Execution memory refers to the memory used by internal data structures created during " +
0321 "shuffles, aggregations and joins when Tungsten is enabled. The value of this accumulator " +
0322 "should be approximately the sum of the peak sizes across all such data structures created " +
0323 "in this task. For SQL jobs, this only tracks all unsafe operators, broadcast joins, and " +
0324 "external sort.");
0325 $('[data-toggle="tooltip"]').tooltip();
0326 var tasksSummary = $("#parent-container");
0327 getStandAloneAppId(function (appId) {
0328
0329 $.get(createTemplateURI(appId, "stagespage"), function(template) {
0330 tasksSummary.append(Mustache.render($(template).filter("#stages-summary-template").html()));
0331
0332 $("#additionalMetrics").click(function(){
0333 $("#arrowtoggle1").toggleClass("arrow-open arrow-closed");
0334 $("#toggle-metrics").toggle();
0335 if (window.localStorage) {
0336 window.localStorage.setItem("arrowtoggle1class", $("#arrowtoggle1").attr('class'));
0337 }
0338 });
0339
0340 $("#aggregatedMetrics").click(function(){
0341 $("#arrowtoggle2").toggleClass("arrow-open arrow-closed");
0342 $("#toggle-aggregatedMetrics").toggle();
0343 if (window.localStorage) {
0344 window.localStorage.setItem("arrowtoggle2class", $("#arrowtoggle2").attr('class'));
0345 }
0346 });
0347
0348 var endPoint = stageEndPoint(appId);
0349 var stageAttemptId = getStageAttemptId();
0350 $.getJSON(endPoint + "/" + stageAttemptId, function(response, status, jqXHR) {
0351
0352 var responseBody = response;
0353 var dataToShow = {};
0354 dataToShow.showInputData = responseBody.inputBytes > 0;
0355 dataToShow.showOutputData = responseBody.outputBytes > 0;
0356 dataToShow.showShuffleReadData = responseBody.shuffleReadBytes > 0;
0357 dataToShow.showShuffleWriteData = responseBody.shuffleWriteBytes > 0;
0358 dataToShow.showBytesSpilledData =
0359 (responseBody.diskBytesSpilled > 0 || responseBody.memoryBytesSpilled > 0);
0360
0361 if (!dataToShow.showShuffleReadData) {
0362 $('#shuffle_read_blocked_time').remove();
0363 $('#shuffle_remote_reads').remove();
0364 optionalColumns.splice(2, 2);
0365 }
0366
0367
0368 var stageExecutorSummaryInfoKeys = Object.keys(responseBody.executorSummary);
0369 $.getJSON(createRESTEndPointForExecutorsPage(appId),
0370 function(executorSummaryResponse, status, jqXHR) {
0371 var executorDetailsMap = {};
0372 executorSummaryResponse.forEach(function (executorDetail) {
0373 executorDetailsMap[executorDetail.id] = executorDetail;
0374 });
0375
0376 var executorSummaryTable = [];
0377 stageExecutorSummaryInfoKeys.forEach(function (columnKeyIndex) {
0378 var executorSummary = responseBody.executorSummary[columnKeyIndex];
0379 var executorDetail = executorDetailsMap[columnKeyIndex.toString()];
0380 executorSummary.id = columnKeyIndex;
0381 executorSummary.executorLogs = {};
0382 executorSummary.hostPort = "CANNOT FIND ADDRESS";
0383
0384 if (executorDetail) {
0385 if (executorDetail["executorLogs"]) {
0386 responseBody.executorSummary[columnKeyIndex].executorLogs =
0387 executorDetail["executorLogs"];
0388 }
0389 if (executorDetail["hostPort"]) {
0390 responseBody.executorSummary[columnKeyIndex].hostPort =
0391 executorDetail["hostPort"];
0392 }
0393 }
0394 executorSummaryTable.push(responseBody.executorSummary[columnKeyIndex]);
0395 });
0396
0397 var executorSummaryConf = {
0398 "data": executorSummaryTable,
0399 "columns": [
0400 {data : "id"},
0401 {data : "executorLogs", render: formatLogsCells},
0402 {data : "hostPort"},
0403 {
0404 data : function (row, type) {
0405 return type === 'display' ? formatDuration(row.taskTime) : row.taskTime;
0406 }
0407 },
0408 {
0409 data : function (row, type) {
0410 var totaltasks = row.succeededTasks + row.failedTasks + row.killedTasks;
0411 return type === 'display' ? totaltasks : totaltasks.toString();
0412 }
0413 },
0414 {data : "failedTasks"},
0415 {data : "killedTasks"},
0416 {data : "succeededTasks"},
0417 {data : "isBlacklistedForStage"},
0418 {
0419 data : function (row, type) {
0420 return row.inputRecords != 0 ? formatBytes(row.inputBytes, type) + " / " + row.inputRecords : "";
0421 }
0422 },
0423 {
0424 data : function (row, type) {
0425 return row.outputRecords != 0 ? formatBytes(row.outputBytes, type) + " / " + row.outputRecords : "";
0426 }
0427 },
0428 {
0429 data : function (row, type) {
0430 return row.shuffleReadRecords != 0 ? formatBytes(row.shuffleRead, type) + " / " + row.shuffleReadRecords : "";
0431 }
0432 },
0433 {
0434 data : function (row, type) {
0435 return row.shuffleWriteRecords != 0 ? formatBytes(row.shuffleWrite, type) + " / " + row.shuffleWriteRecords : "";
0436 }
0437 },
0438 {
0439 data : function (row, type) {
0440 return typeof row.memoryBytesSpilled != 'undefined' ? formatBytes(row.memoryBytesSpilled, type) : "";
0441 }
0442 },
0443 {
0444 data : function (row, type) {
0445 return typeof row.diskBytesSpilled != 'undefined' ? formatBytes(row.diskBytesSpilled, type) : "";
0446 }
0447 }
0448 ],
0449 "order": [[0, "asc"]],
0450 "bAutoWidth": false,
0451 "oLanguage": {
0452 "sEmptyTable": "No data to show yet"
0453 }
0454 };
0455 var executorSummaryTableSelector =
0456 $("#summary-executor-table").DataTable(executorSummaryConf);
0457 $('#parent-container [data-toggle="tooltip"]').tooltip();
0458
0459 executorSummaryTableSelector.column(9).visible(dataToShow.showInputData);
0460 if (dataToShow.showInputData) {
0461 $('#executor-summary-input').attr("data-toggle", "tooltip")
0462 .attr("data-placement", "top")
0463 .attr("title", "Bytes and records read from Hadoop or from Spark storage.");
0464 $('#executor-summary-input').tooltip(true);
0465 }
0466 executorSummaryTableSelector.column(10).visible(dataToShow.showOutputData);
0467 if (dataToShow.showOutputData) {
0468 $('#executor-summary-output').attr("data-toggle", "tooltip")
0469 .attr("data-placement", "top")
0470 .attr("title", "Bytes and records written to Hadoop.");
0471 $('#executor-summary-output').tooltip(true);
0472 }
0473 executorSummaryTableSelector.column(11).visible(dataToShow.showShuffleReadData);
0474 if (dataToShow.showShuffleReadData) {
0475 $('#executor-summary-shuffle-read').attr("data-toggle", "tooltip")
0476 .attr("data-placement", "top")
0477 .attr("title", "Total shuffle bytes and records read (includes both data read locally and data read from remote executors).");
0478 $('#executor-summary-shuffle-read').tooltip(true);
0479 }
0480 executorSummaryTableSelector.column(12).visible(dataToShow.showShuffleWriteData);
0481 if (dataToShow.showShuffleWriteData) {
0482 $('#executor-summary-shuffle-write').attr("data-toggle", "tooltip")
0483 .attr("data-placement", "top")
0484 .attr("title", "Bytes and records written to disk in order to be read by a shuffle in a future stage.");
0485 $('#executor-summary-shuffle-write').tooltip(true);
0486 }
0487 executorSummaryTableSelector.column(13).visible(dataToShow.showBytesSpilledData);
0488 executorSummaryTableSelector.column(14).visible(dataToShow.showBytesSpilledData);
0489 });
0490
0491
0492 var accumulatorTable = responseBody.accumulatorUpdates.filter(accumUpdate =>
0493 !(accumUpdate.name).toString().includes("internal."));
0494
0495 var quantiles = "0,0.25,0.5,0.75,1.0";
0496 $.getJSON(endPoint + "/" + stageAttemptId + "/taskSummary?quantiles=" + quantiles,
0497 function(taskMetricsResponse, status, jqXHR) {
0498 var taskMetricKeys = Object.keys(taskMetricsResponse);
0499 taskMetricKeys.forEach(function (columnKey) {
0500 switch(columnKey) {
0501 case "shuffleReadMetrics":
0502 var row1 = createRowMetadataForColumn(
0503 columnKey, taskMetricsResponse[columnKey], 3);
0504 var row2 = createRowMetadataForColumn(
0505 "shuffleReadBlockedTime", taskMetricsResponse[columnKey], 13);
0506 var row3 = createRowMetadataForColumn(
0507 "shuffleRemoteReads", taskMetricsResponse[columnKey], 14);
0508 if (dataToShow.showShuffleReadData) {
0509 taskSummaryMetricsTableArray.push(row1);
0510 taskSummaryMetricsTableArray.push(row2);
0511 taskSummaryMetricsTableArray.push(row3);
0512 }
0513 break;
0514
0515 case "schedulerDelay":
0516 var row = createRowMetadataForColumn(
0517 columnKey, taskMetricsResponse[columnKey], 11);
0518 taskSummaryMetricsTableArray.push(row);
0519 break;
0520
0521 case "executorDeserializeTime":
0522 var row = createRowMetadataForColumn(
0523 columnKey, taskMetricsResponse[columnKey], 12);
0524 taskSummaryMetricsTableArray.push(row);
0525 break;
0526
0527 case "resultSerializationTime":
0528 var row = createRowMetadataForColumn(
0529 columnKey, taskMetricsResponse[columnKey], 15);
0530 taskSummaryMetricsTableArray.push(row);
0531 break;
0532
0533 case "gettingResultTime":
0534 var row = createRowMetadataForColumn(
0535 columnKey, taskMetricsResponse[columnKey], 16);
0536 taskSummaryMetricsTableArray.push(row);
0537 break;
0538
0539 case "peakExecutionMemory":
0540 var row = createRowMetadataForColumn(
0541 columnKey, taskMetricsResponse[columnKey], 17);
0542 taskSummaryMetricsTableArray.push(row);
0543 break;
0544
0545 case "inputMetrics":
0546 var row = createRowMetadataForColumn(
0547 columnKey, taskMetricsResponse[columnKey], 1);
0548 if (dataToShow.showInputData) {
0549 taskSummaryMetricsTableArray.push(row);
0550 }
0551 break;
0552
0553 case "outputMetrics":
0554 var row = createRowMetadataForColumn(
0555 columnKey, taskMetricsResponse[columnKey], 2);
0556 if (dataToShow.showOutputData) {
0557 taskSummaryMetricsTableArray.push(row);
0558 }
0559 break;
0560
0561 case "shuffleWriteMetrics":
0562 var row = createRowMetadataForColumn(
0563 columnKey, taskMetricsResponse[columnKey], 4);
0564 if (dataToShow.showShuffleWriteData) {
0565 taskSummaryMetricsTableArray.push(row);
0566 }
0567 break;
0568
0569 case "diskBytesSpilled":
0570 var row = createRowMetadataForColumn(
0571 columnKey, taskMetricsResponse[columnKey], 5);
0572 if (dataToShow.showBytesSpilledData) {
0573 taskSummaryMetricsTableArray.push(row);
0574 }
0575 break;
0576
0577 case "memoryBytesSpilled":
0578 var row = createRowMetadataForColumn(
0579 columnKey, taskMetricsResponse[columnKey], 6);
0580 if (dataToShow.showBytesSpilledData) {
0581 taskSummaryMetricsTableArray.push(row);
0582 }
0583 break;
0584
0585 default:
0586 if (getColumnNameForTaskMetricSummary(columnKey) != "NA") {
0587 var row = createRowMetadataForColumn(
0588 columnKey, taskMetricsResponse[columnKey], 0);
0589 taskSummaryMetricsTableArray.push(row);
0590 }
0591 break;
0592 }
0593 });
0594 var taskSummaryMetricsTableFilteredArray =
0595 taskSummaryMetricsTableArray.filter(row => row.checkboxId < 11);
0596 taskSummaryMetricsTableCurrentStateArray = taskSummaryMetricsTableFilteredArray.slice();
0597 reselectCheckboxesBasedOnTaskTableState();
0598 });
0599
0600
0601 var accumulatorConf = {
0602 "data": accumulatorTable,
0603 "columns": [
0604 {data : "id"},
0605 {data : "name"},
0606 {data : "value"}
0607 ],
0608 "paging": false,
0609 "searching": false,
0610 "order": [[0, "asc"]],
0611 "bAutoWidth": false
0612 };
0613 $("#accumulator-table").DataTable(accumulatorConf);
0614
0615
0616 var totalTasksToShow = responseBody.numCompleteTasks + responseBody.numActiveTasks +
0617 responseBody.numKilledTasks + responseBody.numFailedTasks;
0618 var taskTable = "#active-tasks-table";
0619 var taskConf = {
0620 "serverSide": true,
0621 "paging": true,
0622 "info": true,
0623 "processing": true,
0624 "lengthMenu": [[20, 40, 60, 100, totalTasksToShow], [20, 40, 60, 100, "All"]],
0625 "orderMulti": false,
0626 "bAutoWidth": false,
0627 "ajax": {
0628 "url": endPoint + "/" + stageAttemptId + "/taskTable",
0629 "data": function (data) {
0630 var columnIndexToSort = 0;
0631 var columnNameToSort = "Index";
0632 if (data.order[0].column && data.order[0].column != "") {
0633 columnIndexToSort = parseInt(data.order[0].column);
0634 columnNameToSort = data.columns[columnIndexToSort].name;
0635 }
0636 delete data.columns;
0637 data.numTasks = totalTasksToShow;
0638 data.columnIndexToSort = columnIndexToSort;
0639 data.columnNameToSort = columnNameToSort;
0640 },
0641 "dataSrc": function (jsons) {
0642 var jsonStr = JSON.stringify(jsons);
0643 var tasksToShow = JSON.parse(jsonStr);
0644 return tasksToShow.aaData;
0645 },
0646 "error": function (jqXHR, textStatus, errorThrown) {
0647 alert("Unable to connect to the server. Looks like the Spark " +
0648 "application must have ended. Please Switch to the history UI.");
0649 $("#active-tasks-table_processing").css("display","none");
0650 }
0651 },
0652 "columns": [
0653 {data: function (row, type) {
0654 return type !== 'display' ? (isNaN(row.index) ? 0 : row.index ) : row.index;
0655 },
0656 name: "Index"
0657 },
0658 {data : "taskId", name: "ID"},
0659 {data : "attempt", name: "Attempt"},
0660 {data : "status", name: "Status"},
0661 {data : "taskLocality", name: "Locality Level"},
0662 {data : "executorId", name: "Executor ID"},
0663 {data : "host", name: "Host"},
0664 {data : "executorLogs", name: "Logs", render: formatLogsCells},
0665 {data : "launchTime", name: "Launch Time", render: formatDate},
0666 {
0667 data : function (row, type) {
0668 if (row.taskMetrics && row.taskMetrics.executorRunTime) {
0669 return type === 'display' ? formatDuration(row.taskMetrics.executorRunTime) : row.taskMetrics.executorRunTime;
0670 } else {
0671 return "";
0672 }
0673 },
0674 name: "Duration"
0675 },
0676 {
0677 data : function (row, type) {
0678 if (row.taskMetrics && row.taskMetrics.jvmGcTime) {
0679 return type === 'display' ? formatDuration(row.taskMetrics.jvmGcTime) : row.taskMetrics.jvmGcTime;
0680 } else {
0681 return "";
0682 }
0683 },
0684 name: "GC Time"
0685 },
0686 {
0687 data : function (row, type) {
0688 if (row.schedulerDelay) {
0689 return type === 'display' ? formatDuration(row.schedulerDelay) : row.schedulerDelay;
0690 } else {
0691 return "";
0692 }
0693 },
0694 name: "Scheduler Delay"
0695 },
0696 {
0697 data : function (row, type) {
0698 if (row.taskMetrics && row.taskMetrics.executorDeserializeTime) {
0699 return type === 'display' ? formatDuration(row.taskMetrics.executorDeserializeTime) : row.taskMetrics.executorDeserializeTime;
0700 } else {
0701 return "";
0702 }
0703 },
0704 name: "Task Deserialization Time"
0705 },
0706 {
0707 data : function (row, type) {
0708 if (row.taskMetrics && row.taskMetrics.shuffleReadMetrics) {
0709 return type === 'display' ? formatDuration(row.taskMetrics.shuffleReadMetrics.fetchWaitTime) : row.taskMetrics.shuffleReadMetrics.fetchWaitTime;
0710 } else {
0711 return "";
0712 }
0713 },
0714 name: "Shuffle Read Blocked Time"
0715 },
0716 {
0717 data : function (row, type) {
0718 if (row.taskMetrics && row.taskMetrics.shuffleReadMetrics) {
0719 return type === 'display' ? formatBytes(row.taskMetrics.shuffleReadMetrics.remoteBytesRead, type) : row.taskMetrics.shuffleReadMetrics.remoteBytesRead;
0720 } else {
0721 return "";
0722 }
0723 },
0724 name: "Shuffle Remote Reads"
0725 },
0726 {
0727 data : function (row, type) {
0728 if (row.taskMetrics && row.taskMetrics.resultSerializationTime) {
0729 return type === 'display' ? formatDuration(row.taskMetrics.resultSerializationTime) : row.taskMetrics.resultSerializationTime;
0730 } else {
0731 return "";
0732 }
0733 },
0734 name: "Result Serialization Time"
0735 },
0736 {
0737 data : function (row, type) {
0738 if (row.gettingResultTime) {
0739 return type === 'display' ? formatDuration(row.gettingResultTime) : row.gettingResultTime;
0740 } else {
0741 return "";
0742 }
0743 },
0744 name: "Getting Result Time"
0745 },
0746 {
0747 data : function (row, type) {
0748 if (row.taskMetrics && row.taskMetrics.peakExecutionMemory) {
0749 return type === 'display' ? formatBytes(row.taskMetrics.peakExecutionMemory, type) : row.taskMetrics.peakExecutionMemory;
0750 } else {
0751 return "";
0752 }
0753 },
0754 name: "Peak Execution Memory"
0755 },
0756 {
0757 data : function (row, type) {
0758 if (accumulatorTable.length > 0 && row.accumulatorUpdates.length > 0) {
0759 var allAccums = "";
0760 row.accumulatorUpdates.forEach(function(accumulator) {
0761 allAccums += accumulator.name + ': ' + accumulator.update + "<BR>";
0762 })
0763 return allAccums;
0764 } else {
0765 return "";
0766 }
0767 },
0768 name: "Accumulators"
0769 },
0770 {
0771 data : function (row, type) {
0772 if (row.taskMetrics && row.taskMetrics.inputMetrics && row.taskMetrics.inputMetrics.bytesRead > 0) {
0773 if (type === 'display') {
0774 return formatBytes(row.taskMetrics.inputMetrics.bytesRead, type) + " / " + row.taskMetrics.inputMetrics.recordsRead;
0775 } else {
0776 return row.taskMetrics.inputMetrics.bytesRead + " / " + row.taskMetrics.inputMetrics.recordsRead;
0777 }
0778 } else {
0779 return "";
0780 }
0781 },
0782 name: "Input Size / Records"
0783 },
0784 {
0785 data : function (row, type) {
0786 if (row.taskMetrics && row.taskMetrics.outputMetrics && row.taskMetrics.outputMetrics.bytesWritten > 0) {
0787 if (type === 'display') {
0788 return formatBytes(row.taskMetrics.outputMetrics.bytesWritten, type) + " / " + row.taskMetrics.outputMetrics.recordsWritten;
0789 } else {
0790 return row.taskMetrics.outputMetrics.bytesWritten + " / " + row.taskMetrics.outputMetrics.recordsWritten;
0791 }
0792 } else {
0793 return "";
0794 }
0795 },
0796 name: "Output Size / Records"
0797 },
0798 {
0799 data : function (row, type) {
0800 if (row.taskMetrics && row.taskMetrics.shuffleWriteMetrics && row.taskMetrics.shuffleWriteMetrics.writeTime > 0) {
0801 return type === 'display' ? formatDuration(parseInt(row.taskMetrics.shuffleWriteMetrics.writeTime) / 1000000) : row.taskMetrics.shuffleWriteMetrics.writeTime;
0802 } else {
0803 return "";
0804 }
0805 },
0806 name: "Write Time"
0807 },
0808 {
0809 data : function (row, type) {
0810 if (row.taskMetrics && row.taskMetrics.shuffleWriteMetrics && row.taskMetrics.shuffleWriteMetrics.bytesWritten > 0) {
0811 if (type === 'display') {
0812 return formatBytes(row.taskMetrics.shuffleWriteMetrics.bytesWritten, type) + " / " + row.taskMetrics.shuffleWriteMetrics.recordsWritten;
0813 } else {
0814 return row.taskMetrics.shuffleWriteMetrics.bytesWritten + " / " + row.taskMetrics.shuffleWriteMetrics.recordsWritten;
0815 }
0816 } else {
0817 return "";
0818 }
0819 },
0820 name: "Shuffle Write Size / Records"
0821 },
0822 {
0823 data : function (row, type) {
0824 if (row.taskMetrics && row.taskMetrics.shuffleReadMetrics && row.taskMetrics.shuffleReadMetrics.localBytesRead > 0) {
0825 var totalBytesRead = parseInt(row.taskMetrics.shuffleReadMetrics.localBytesRead) + parseInt(row.taskMetrics.shuffleReadMetrics.remoteBytesRead);
0826 if (type === 'display') {
0827 return formatBytes(totalBytesRead, type) + " / " + row.taskMetrics.shuffleReadMetrics.recordsRead;
0828 } else {
0829 return totalBytesRead + " / " + row.taskMetrics.shuffleReadMetrics.recordsRead;
0830 }
0831 } else {
0832 return "";
0833 }
0834 },
0835 name: "Shuffle Read Size / Records"
0836 },
0837 {
0838 data : function (row, type) {
0839 if (row.taskMetrics && row.taskMetrics.memoryBytesSpilled && row.taskMetrics.memoryBytesSpilled > 0) {
0840 return type === 'display' ? formatBytes(row.taskMetrics.memoryBytesSpilled, type) : row.taskMetrics.memoryBytesSpilled;
0841 } else {
0842 return "";
0843 }
0844 },
0845 name: "Spill (Memory)"
0846 },
0847 {
0848 data : function (row, type) {
0849 if (row.taskMetrics && row.taskMetrics.diskBytesSpilled && row.taskMetrics.diskBytesSpilled > 0) {
0850 return type === 'display' ? formatBytes(row.taskMetrics.diskBytesSpilled, type) : row.taskMetrics.diskBytesSpilled;
0851 } else {
0852 return "";
0853 }
0854 },
0855 name: "Spill (Disk)"
0856 },
0857 {
0858 data : function (row, type) {
0859 var msg = row.errorMessage;
0860 if (typeof msg === 'undefined') {
0861 return "";
0862 } else {
0863 var formHead = msg.substring(0, msg.indexOf("at"));
0864 var form = "<span onclick=\"this.parentNode.querySelector('.stacktrace-details').classList.toggle('collapsed')\" class=\"expand-details\">+details</span>";
0865 var formMsg = "<div class=\"stacktrace-details collapsed\"><pre>" + row.errorMessage + "</pre></div>";
0866 return formHead + form + formMsg;
0867 }
0868 },
0869 name: "Errors"
0870 }
0871 ],
0872 "columnDefs": [
0873 { "visible": false, "targets": 11 },
0874 { "visible": false, "targets": 12 },
0875 { "visible": false, "targets": 13 },
0876 { "visible": false, "targets": 14 },
0877 { "visible": false, "targets": 15 },
0878 { "visible": false, "targets": 16 },
0879 { "visible": false, "targets": 17 },
0880 { "visible": false, "targets": 18 }
0881 ],
0882 "deferRender": true
0883 };
0884 taskTableSelector = $(taskTable).DataTable(taskConf);
0885 $('#active-tasks-table_filter input').unbind();
0886 var searchEvent;
0887 $('#active-tasks-table_filter input').bind('keyup', function(e) {
0888 if (typeof searchEvent !== 'undefined') {
0889 window.clearTimeout(searchEvent);
0890 }
0891 var value = this.value;
0892 searchEvent = window.setTimeout(function(){
0893 taskTableSelector.search( value ).draw();}, 500);
0894 });
0895 reselectCheckboxesBasedOnTaskTableState();
0896
0897
0898 $('input.toggle-vis').on('click', function(e){
0899
0900 var para = $(this).attr('data-column');
0901 if (para == "0") {
0902 var allColumns = taskTableSelector.columns(optionalColumns);
0903 if ($(this).is(":checked")) {
0904 $(".toggle-vis").prop('checked', true);
0905 allColumns.visible(true);
0906 createDataTableForTaskSummaryMetricsTable(taskSummaryMetricsTableArray);
0907 } else {
0908 $(".toggle-vis").prop('checked', false);
0909 allColumns.visible(false);
0910 var taskSummaryMetricsTableFilteredArray =
0911 taskSummaryMetricsTableArray.filter(row => row.checkboxId < 11);
0912 createDataTableForTaskSummaryMetricsTable(taskSummaryMetricsTableFilteredArray);
0913 }
0914 } else {
0915 var column = taskTableSelector.column(para);
0916
0917 column.visible(!column.visible());
0918 var taskSummaryMetricsTableFilteredArray = [];
0919 if ($(this).is(":checked")) {
0920 taskSummaryMetricsTableCurrentStateArray.push(taskSummaryMetricsTableArray.filter(row => (row.checkboxId).toString() == para)[0]);
0921 taskSummaryMetricsTableFilteredArray = taskSummaryMetricsTableCurrentStateArray.slice();
0922 } else {
0923 taskSummaryMetricsTableFilteredArray =
0924 taskSummaryMetricsTableCurrentStateArray.filter(row => (row.checkboxId).toString() != para);
0925 }
0926 createDataTableForTaskSummaryMetricsTable(taskSummaryMetricsTableFilteredArray);
0927 }
0928 });
0929
0930
0931 $("#summaryMetricsTitle").html("Summary Metrics for " + "<a href='#tasksTitle'>" + responseBody.numCompleteTasks + " Completed Tasks" + "</a>");
0932 $("#tasksTitle").html("Tasks (" + totalTasksToShow + ")");
0933
0934
0935 if (accumulatorTable.length == 0) {
0936 $("#accumulator-update-table").hide();
0937 } else {
0938 taskTableSelector.column(18).visible(true);
0939 $("#accumulator-update-table").show();
0940 }
0941
0942
0943 taskTableSelector.column(19).visible(dataToShow.showInputData);
0944 taskTableSelector.column(20).visible(dataToShow.showOutputData);
0945 taskTableSelector.column(21).visible(dataToShow.showShuffleWriteData);
0946 taskTableSelector.column(22).visible(dataToShow.showShuffleWriteData);
0947 taskTableSelector.column(23).visible(dataToShow.showShuffleReadData);
0948 taskTableSelector.column(24).visible(dataToShow.showBytesSpilledData);
0949 taskTableSelector.column(25).visible(dataToShow.showBytesSpilledData);
0950
0951 if (window.localStorage) {
0952 if (window.localStorage.getItem("arrowtoggle1class") !== null &&
0953 window.localStorage.getItem("arrowtoggle1class").includes("arrow-open")) {
0954 $("#arrowtoggle1").toggleClass("arrow-open arrow-closed");
0955 $("#toggle-metrics").toggle();
0956 }
0957 if (window.localStorage.getItem("arrowtoggle2class") !== null &&
0958 window.localStorage.getItem("arrowtoggle2class").includes("arrow-open")) {
0959 $("#arrowtoggle2").toggleClass("arrow-open arrow-closed");
0960 $("#toggle-aggregatedMetrics").toggle();
0961 }
0962 }
0963 });
0964 });
0965 });
0966 });