azkaban-aplcache
Changes
src/web/js/azkaban/model/log-data.js 53(+37 -16)
src/web/js/azkaban/view/job-details.js 44(+44 -0)
Details
diff --git a/src/java/azkaban/webapp/servlet/velocity/jobdetailspage.vm b/src/java/azkaban/webapp/servlet/velocity/jobdetailspage.vm
index 335f24c..f551245 100644
--- a/src/java/azkaban/webapp/servlet/velocity/jobdetailspage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/jobdetailspage.vm
@@ -84,6 +84,11 @@
</div>
</h3>
+ <div id="jobType">
+ <table id="jobTypeTable" class="table table-striped table-bordered table-hover">
+ </table>
+ </div>
+
<div id="command-summary">
<h4>Command Summary</h4>
<table id="commandTable" class="table table-striped table-bordered table-hover">
@@ -121,6 +126,13 @@
</tbody>
</table>
</div>
+
+ <div id="jobIds">
+ <h4>Map Reduce Jobs</h4>
+ <table class="table table-striped table-bordered table-hover">
+ <tbody id="jobIdsTableBody"></tbody>
+ </table>
+ </div>
</div>
</div>
</div>
src/web/js/azkaban/model/log-data.js 53(+37 -16)
diff --git a/src/web/js/azkaban/model/log-data.js b/src/web/js/azkaban/model/log-data.js
index 2fe3ac5..90a958f 100644
--- a/src/web/js/azkaban/model/log-data.js
+++ b/src/web/js/azkaban/model/log-data.js
@@ -24,6 +24,8 @@ azkaban.LogDataModel = Backbone.Model.extend({
HIVE_MAP_REDUCE_JOBS_SUMMARY: "MapReduce Jobs Launched:",
HIVE_MAP_REDUCE_SUMMARY_REGEX: /Job (\d+):\s+Map: (\d+)\s+Reduce: (\d+)\s+(?:Cumulative CPU: (.+?))?\s+HDFS Read: (\d+)\s+HDFS Write: (\d+)/,
+ JOB_ID_REGEX: /job_\d{12}_\d{4,}/,
+
initialize: function() {
this.set("offset", 0 );
this.set("logData", "");
@@ -91,14 +93,19 @@ azkaban.LogDataModel = Backbone.Model.extend({
var lines = data.split("\n");
if (this.parseCommand(lines)) {
+ this.parseJobType(lines);
this.parseJobTrackerUrls(lines);
- var jobType = this.parseJobType(lines);
- if (jobType.indexOf("pig") !== -1) {
- this.parsePigTable(lines, "pigSummary", this.PIG_JOB_SUMMARY_START, "", 0);
- this.parsePigTable(lines, "pigStats", this.PIG_JOB_STATS_START, "", 1);
- } else if (jobType.indexOf("hive") !== -1) {
- this.parseHiveQueries(lines);
+ var jobType = this.get("jobType");
+ if (jobType) {
+ if (jobType.indexOf("pig") !== -1) {
+ this.parsePigTable(lines, "pigSummary", this.PIG_JOB_SUMMARY_START, "", 0);
+ this.parsePigTable(lines, "pigStats", this.PIG_JOB_STATS_START, "", 1);
+ } else if (jobType.indexOf("hive") !== -1) {
+ this.parseHiveQueries(lines);
+ } else {
+ this.parseJobIds(lines);
+ }
}
}
},
@@ -163,16 +170,32 @@ azkaban.LogDataModel = Backbone.Model.extend({
this.set("jobTrackerUrlsOrdered", jobTrackerUrlsOrdered);
},
+ parseJobIds: function(lines) {
+ var seenJobIds = {};
+ var jobIds = [];
+ var numLines = lines.length;
+ var match;
+ for (var i = 0; i < numLines; i++) {
+ if ((match = this.JOB_ID_REGEX.exec(lines[i])) && !seenJobIds[match[0]]) {
+ seenJobIds[match[0]] = true;
+ jobIds.push(match[0]);
+ }
+ }
+
+ if (jobIds.length > 0) {
+ this.set("jobIds", jobIds);
+ }
+ },
+
parseJobType: function(lines) {
var numLines = lines.length;
var match;
- for (var i = 0; numLines; i++) {
+ for (var i = 0; i < numLines; i++) {
if (match = this.JOB_TYPE_REGEX.exec(lines[i])) {
- return match[1];
+ this.set("jobType", match[1]);
+ break;
}
}
-
- return null;
},
parsePigTable: function(lines, tableName, startPattern, endPattern, linesToSkipAfterStart) {
@@ -262,14 +285,12 @@ azkaban.LogDataModel = Backbone.Model.extend({
job.push("<a href='" + this.get("jobTrackerUrlsOrdered")[currMapReduceJob++] + "'>" + currJob + "</a>");
job.push(match[2]);
job.push(match[3]);
- job.push(match[4]);
- job.push(match[5]);
- job.push(match[6]);
-
- if (match[7]) {
+ if (match[4]) {
this.set("hasCumulativeCPU", true);
- job.push(match[7]);
+ job.push(match[4]);
}
+ job.push(match[5]);
+ job.push(match[6]);
queryJobs.push(job);
previousJob = currJob;
src/web/js/azkaban/view/job-details.js 44(+44 -0)
diff --git a/src/web/js/azkaban/view/job-details.js b/src/web/js/azkaban/view/job-details.js
index ab77045..07b823e 100644
--- a/src/web/js/azkaban/view/job-details.js
+++ b/src/web/js/azkaban/view/job-details.js
@@ -45,15 +45,19 @@ azkaban.JobSummaryView = Backbone.View.extend({
},
initialize: function(settings) {
+ $("#jobType").hide();
$("#commandSummary").hide();
$("#pigJobSummary").hide();
$("#pigJobStats").hide();
$("#hiveJobSummary").hide();
+ $("#jobIds").hide();
+ this.listenTo(this.model, "change:jobType", this.renderJobTypeTable);
this.listenTo(this.model, "change:commandProperties", this.renderCommandTable);
this.listenTo(this.model, "change:pigSummary", this.renderPigSummaryTable);
this.listenTo(this.model, "change:pigStats", this.renderPigStatsTable);
this.listenTo(this.model, "change:hiveSummary", this.renderHiveTable);
+ this.listenTo(this.model, "change:jobIds", this.renderJobIdsTable);
},
refresh: function() {
@@ -65,6 +69,46 @@ azkaban.JobSummaryView = Backbone.View.extend({
renderJobTable(jobSummary.statTableHeaders, jobSummary.statTableData, "stats");
renderHiveTable(jobSummary.hiveQueries, jobSummary.hiveQueryJobs);
},
+
+ renderJobTypeTable: function() {
+ var jobTypeTable = $("#jobTypeTable");
+ var jobType = this.model.get("jobType");
+
+ var tr = document.createElement("tr");
+ var td = document.createElement("td");
+ $(td).html("<b>Job Type</b>");
+ $(tr).append(td);
+ td = document.createElement("td");
+ $(td).html(jobType);
+ $(tr).append(td);
+
+ jobTypeTable.append(tr);
+
+ $("#jobType").show();
+ },
+
+ renderJobIdsTable: function() {
+ var oldBody = $("#jobIdsTableBody");
+ var newBody = $(document.createElement("tbody")).attr("id", "jobIdsTableBody");
+
+ var jobIds = this.model.get("jobIds");
+ var jobUrls = this.model.get("jobTrackerUrls");
+ var numJobs = jobIds.length;
+ for (var i = 0; i < numJobs; i++) {
+ var job = jobIds[i];
+ var tr = document.createElement("tr");
+ var td = document.createElement("td");
+ var html = jobUrls[job] ? "<a href='" + jobUrls[job] + "'>" + job + "</a>" : job;
+ $(td).html(html);
+ $(tr).append(td);
+ newBody.append(tr);
+ }
+
+ oldBody.replaceWith(newBody);
+
+ $("#jobIds").show();
+ },
+
renderCommandTable: function() {
var commandTable = $("#commandTable");
var commandProperties = this.model.get("commandProperties");