azkaban-developers
Changes
src/tl/flowstats.tl 2(+2 -0)
src/web/js/azkaban/view/exflow.js 163(+82 -81)
src/web/js/azkaban/view/flow.js 124(+62 -62)
src/web/js/azkaban/view/flow-stats.js 32(+25 -7)
Details
src/tl/flowstats.tl 2(+2 -0)
diff --git a/src/tl/flowstats.tl b/src/tl/flowstats.tl
index ef24ad0..ffb5e2f 100644
--- a/src/tl/flowstats.tl
+++ b/src/tl/flowstats.tl
@@ -1,3 +1,4 @@
+ {?histogram}
<div class="row">
<div class="col-xs-12">
<div class="well well-clear well-sm">
@@ -5,6 +6,7 @@
</div>
</div>
</div>
+ {/histogram}
<div class="row">
<div class="col-xs-12">
src/web/js/azkaban/view/exflow.js 163(+82 -81)
diff --git a/src/web/js/azkaban/view/exflow.js b/src/web/js/azkaban/view/exflow.js
index 6129676..7c2548c 100644
--- a/src/web/js/azkaban/view/exflow.js
+++ b/src/web/js/azkaban/view/exflow.js
@@ -1,12 +1,12 @@
/*
* Copyright 2012 LinkedIn Corp.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -35,16 +35,16 @@ azkaban.StatusView = Backbone.View.extend({
},
render: function(evt) {
var data = this.model.get("data");
-
+
var user = data.submitUser;
$("#submitUser").text(user);
-
+
this.statusUpdate(evt);
},
-
+
statusUpdate: function(evt) {
var data = this.model.get("data");
-
+
statusItem = $("#flowStatus");
for (var j = 0; j < statusList.length; ++j) {
var status = statusList[j];
@@ -52,27 +52,27 @@ azkaban.StatusView = Backbone.View.extend({
}
$("#flowStatus").addClass(data.status);
$("#flowStatus").text(data.status);
-
+
var startTime = data.startTime;
var endTime = data.endTime;
-
+
if (!startTime || startTime == -1) {
$("#startTime").text("-");
}
else {
var date = new Date(startTime);
$("#startTime").text(getDateFormat(date));
-
+
var lastTime = endTime;
if (endTime == -1) {
var currentDate = new Date();
lastTime = currentDate.getTime();
}
-
+
var durationString = getDuration(startTime, lastTime);
$("#duration").text(durationString);
}
-
+
if (!endTime || endTime == -1) {
$("#endTime").text("-");
}
@@ -96,17 +96,17 @@ azkaban.FlowTabView = Backbone.View.extend({
"click #resumebtn": "handleResumeClick",
"click #retrybtn": "handleRetryClick"
},
-
+
initialize: function(settings) {
$("#cancelbtn").hide();
$("#executebtn").hide();
$("#pausebtn").hide();
$("#resumebtn").hide();
$("#retrybtn").hide();
-
+
this.model.bind('change:graph', this.handleFlowStatusChange, this);
this.model.bind('change:update', this.handleFlowStatusChange, this);
-
+
var selectedView = settings.selectedView;
if (selectedView == "jobslist") {
this.handleJobslistLinkClick();
@@ -115,60 +115,60 @@ azkaban.FlowTabView = Backbone.View.extend({
this.handleGraphLinkClick();
}
},
-
+
render: function() {
console.log("render graph");
},
-
+
handleGraphLinkClick: function(){
$("#jobslistViewLink").removeClass("active");
$("#graphViewLink").addClass("active");
$("#flowLogViewLink").removeClass("active");
$("#statsViewLink").removeClass("active");
-
+
$("#jobListView").hide();
$("#graphView").show();
$("#flowLogView").hide();
$("#statsView").hide();
},
-
+
handleJobslistLinkClick: function() {
$("#graphViewLink").removeClass("active");
$("#jobslistViewLink").addClass("active");
$("#flowLogViewLink").removeClass("active");
$("#statsViewLink").removeClass("active");
-
+
$("#graphView").hide();
$("#jobListView").show();
$("#flowLogView").hide();
$("#statsView").hide();
},
-
+
handleLogLinkClick: function() {
$("#graphViewLink").removeClass("active");
$("#jobslistViewLink").removeClass("active");
$("#flowLogViewLink").addClass("active");
$("#statsViewLink").removeClass("active");
-
+
$("#graphView").hide();
$("#jobListView").hide();
$("#flowLogView").show();
$("#statsView").hide();
},
-
+
handleStatsLinkClick: function() {
$("#graphViewLink").removeClass("active");
$("#jobslistViewLink").removeClass("active");
$("#flowLogViewLink").removeClass("active");
$("#statsViewLink").addClass("active");
-
+
$("#graphView").hide();
$("#jobListView").hide();
$("#flowLogView").hide();
statsView.show();
$("#statsView").show();
},
-
+
handleFlowStatusChange: function() {
var data = this.model.get("data");
$("#cancelbtn").hide();
@@ -203,7 +203,7 @@ azkaban.FlowTabView = Backbone.View.extend({
$("#executebtn").show();
}
},
-
+
handleCancelClick: function(evt) {
var requestURL = contextURL + "/executor";
var requestData = {"execid": execId, "ajax": "cancelFlow"};
@@ -219,7 +219,7 @@ azkaban.FlowTabView = Backbone.View.extend({
};
ajaxCall(requestURL, requestData, successHandler);
},
-
+
handleRetryClick: function(evt) {
var graphData = graphModel.get("data");
var requestURL = contextURL + "/executor";
@@ -236,11 +236,11 @@ azkaban.FlowTabView = Backbone.View.extend({
};
ajaxCall(requestURL, requestData, successHandler);
},
-
+
handleRestartClick: function(evt) {
console.log("handleRestartClick");
var data = graphModel.get("data");
-
+
var executingData = {
project: projectName,
ajax: "executeFlow",
@@ -250,7 +250,7 @@ azkaban.FlowTabView = Backbone.View.extend({
};
flowExecuteDialogView.show(executingData);
},
-
+
handlePauseClick: function(evt) {
var requestURL = contextURL + "/executor";
var requestData = {"execid": execId, "ajax":"pauseFlow"};
@@ -266,7 +266,7 @@ azkaban.FlowTabView = Backbone.View.extend({
};
ajaxCall(requestURL, requestData, successHandler);
},
-
+
handleResumeClick: function(evt) {
var requestURL = contextURL + "/executor";
var requestData = {"execid": execId, "ajax":"resumeFlow"};
@@ -304,17 +304,17 @@ azkaban.FlowLogView = Backbone.View.extend({
},
handleUpdate: function(evt) {
var offset = this.model.get("offset");
- var requestURL = contextURL + "/executor";
+ var requestURL = contextURL + "/executor";
var model = this.model;
console.log("fetchLogs offset is " + offset)
$.ajax({
- async: false,
+ async: false,
url: requestURL,
data: {
- "execid": execId,
- "ajax": "fetchExecFlowLogs",
- "offset": offset,
+ "execid": execId,
+ "ajax": "fetchExecFlowLogs",
+ "offset": offset,
"length": 50000
},
success: function(data) {
@@ -346,7 +346,7 @@ var statsView;
azkaban.StatsView = Backbone.View.extend({
events: {
},
-
+
initialize: function(settings) {
this.model.bind('change:graph', this.statusUpdate, this);
this.model.bind('change:update', this.statusUpdate, this);
@@ -385,22 +385,22 @@ var updateStatus = function(updateTime) {
var requestURL = contextURL + "/executor";
var oldData = graphModel.get("data");
var nodeMap = graphModel.get("nodeMap");
-
+
if (!updateTime) {
updateTime = oldData.updateTime ? oldData.updateTime : 0;
}
var requestData = {
- "execid": execId,
- "ajax": "fetchexecflowupdate",
+ "execid": execId,
+ "ajax": "fetchexecflowupdate",
"lastUpdateTime": updateTime
};
-
+
var successHandler = function(data) {
console.log("data updated");
if (data.updateTime) {
updateGraph(oldData, data);
-
+
graphModel.set({"update": data});
graphModel.trigger("change:update");
}
@@ -415,12 +415,12 @@ var updateGraph = function(data, update) {
data.updateTime = update.updateTime;
data.status = update.status;
update.changedNode = data;
-
+
if (update.nodes) {
for (var i = 0; i < update.nodes.length; ++i) {
var newNode = update.nodes[i];
var oldNode = nodeMap[newNode.id];
-
+
updateGraph(oldNode, newNode);
}
}
@@ -429,17 +429,17 @@ var updateGraph = function(data, update) {
var updateTime = -1;
var updaterFunction = function() {
var oldData = graphModel.get("data");
- var keepRunning =
- oldData.status != "SUCCEEDED" &&
- oldData.status != "FAILED" &&
+ var keepRunning =
+ oldData.status != "SUCCEEDED" &&
+ oldData.status != "FAILED" &&
oldData.status != "KILLED";
if (keepRunning) {
updateStatus();
var data = graphModel.get("data");
- if (data.status == "UNKNOWN" ||
- data.status == "WAITING" ||
+ if (data.status == "UNKNOWN" ||
+ data.status == "WAITING" ||
data.status == "PREPARING") {
setTimeout(function() {updaterFunction();}, 1000);
}
@@ -459,9 +459,9 @@ var updaterFunction = function() {
var logUpdaterFunction = function() {
var oldData = graphModel.get("data");
- var keepRunning =
- oldData.status != "SUCCEEDED" &&
- oldData.status != "FAILED" &&
+ var keepRunning =
+ oldData.status != "SUCCEEDED" &&
+ oldData.status != "FAILED" &&
oldData.status != "KILLED";
if (keepRunning) {
// update every 30 seconds for the logs until finished
@@ -479,7 +479,7 @@ var exNodeClickCallback = function(event) {
var requestURL = contextURL + "/manager?project=" + projectName + "&flow=" + flowId + "&job=" + jobId;
var visualizerURL = contextURL + "/pigvisualizer?execid=" + execId + "&jobid=" + jobId;
- var menu = [
+ var menu = [
{title: "Open Job...", callback: function() {window.location.href = requestURL;}},
{title: "Open Job in New Window...", callback: function() {window.open(requestURL);}},
{title: "Visualize Job...", callback: function() {window.location.href = visualizerURL;}}
@@ -494,7 +494,7 @@ var exJobClickCallback = function(event) {
var requestURL = contextURL + "/manager?project=" + projectName + "&flow=" + flowId + "&job=" + jobId;
var visualizerURL = contextURL + "/pigvisualizer?execid=" + execId + "&jobid=" + jobId;
- var menu = [
+ var menu = [
{title: "Open Job...", callback: function() {window.location.href = requestURL;}},
{title: "Open Job in New Window...", callback: function() {window.open(requestURL);}},
{title: "Visualize Job...", callback: function() {window.location.href = visualizerURL;}}
@@ -511,13 +511,13 @@ var exGraphClickCallback = function(event) {
console.log("Graph clicked callback");
var requestURL = contextURL + "/manager?project=" + projectName + "&flow=" + flowId;
- var menu = [
+ var menu = [
{title: "Open Flow...", callback: function() {window.location.href=requestURL;}},
{title: "Open Flow in New Window...", callback: function() {window.open(requestURL);}},
{break: 1},
{title: "Center Graph", callback: function() {graphModel.trigger("resetPanZoom");}}
];
-
+
contextMenuView.show(event, menu);
}
@@ -526,68 +526,69 @@ var flowStatsModel;
$(function() {
var selected;
-
+
graphModel = new azkaban.GraphModel();
logModel = new azkaban.LogModel();
-
+
flowTabView = new azkaban.FlowTabView({
- el: $('#headertabs'),
+ el: $('#headertabs'),
model: graphModel
});
-
+
mainSvgGraphView = new azkaban.SvgGraphView({
- el: $('#svgDiv'),
- model: graphModel,
- rightClick: {
- "node": nodeClickCallback,
- "edge": edgeClickCallback,
- "graph": graphClickCallback
+ el: $('#svgDiv'),
+ model: graphModel,
+ rightClick: {
+ "node": nodeClickCallback,
+ "edge": edgeClickCallback,
+ "graph": graphClickCallback
}
});
-
+
jobsListView = new azkaban.JobListView({
- el: $('#joblist-panel'),
- model: graphModel,
+ el: $('#joblist-panel'),
+ model: graphModel,
contextMenuCallback: jobClickCallback
});
-
+
flowLogView = new azkaban.FlowLogView({
- el: $('#flowLogView'),
+ el: $('#flowLogView'),
model: logModel
});
-
+
statusView = new azkaban.StatusView({
- el: $('#flow-status'),
+ el: $('#flow-status'),
model: graphModel
});
-
+
flowStatsModel = new azkaban.FlowStatsModel();
flowStatsView = new azkaban.FlowStatsView({
el: $('#flow-stats-container'),
- model: flowStatsModel
+ model: flowStatsModel,
+ histogram: false
});
statsView = new azkaban.StatsView({
- el: $('#statsView'),
+ el: $('#statsView'),
model: graphModel
});
-
+
executionListView = new azkaban.ExecutionListView({
- el: $('#jobListView'),
+ el: $('#jobListView'),
model: graphModel
});
-
+
var requestURL = contextURL + "/executor";
var requestData = {"execid": execId, "ajax":"fetchexecflow"};
var successHandler = function(data) {
console.log("data fetched");
graphModel.addFlow(data);
graphModel.trigger("change:graph");
-
+
updateTime = Math.max(updateTime, data.submitTime);
updateTime = Math.max(updateTime, data.startTime);
updateTime = Math.max(updateTime, data.endTime);
-
+
if (window.location.hash) {
var hash = window.location.hash;
if (hash == "#jobslist") {
src/web/js/azkaban/view/flow.js 124(+62 -62)
diff --git a/src/web/js/azkaban/view/flow.js b/src/web/js/azkaban/view/flow.js
index 3934055..95aba17 100644
--- a/src/web/js/azkaban/view/flow.js
+++ b/src/web/js/azkaban/view/flow.js
@@ -1,12 +1,12 @@
/*
* Copyright 2012 LinkedIn Corp.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,7 +18,7 @@ $.namespace('azkaban');
var handleJobMenuClick = function(action, el, pos) {
var jobid = el[0].jobid;
- var requestURL = contextURL + "/manager?project=" + projectName + "&flow=" +
+ var requestURL = contextURL + "/manager?project=" + projectName + "&flow=" +
flowId + "&job=" + jobid;
if (action == "open") {
window.location.href = requestURL;
@@ -35,7 +35,7 @@ azkaban.FlowTabView = Backbone.View.extend({
"click #executionsViewLink": "handleExecutionLinkClick",
"click #summaryViewLink": "handleSummaryLinkClick"
},
-
+
initialize: function(settings) {
var selectedView = settings.selectedView;
if (selectedView == "executions") {
@@ -45,26 +45,26 @@ azkaban.FlowTabView = Backbone.View.extend({
this.handleGraphLinkClick();
}
},
-
+
render: function() {
console.log("render graph");
},
-
+
handleGraphLinkClick: function(){
$("#executionsViewLink").removeClass("active");
$("#graphViewLink").addClass("active");
$('#summaryViewLink').removeClass('active');
-
+
$("#executionsView").hide();
$("#graphView").show();
$('#summaryView').hide();
},
-
+
handleExecutionLinkClick: function() {
$("#graphViewLink").removeClass("active");
$("#executionsViewLink").addClass("active");
$('#summaryViewLink').removeClass('active');
-
+
$("#graphView").hide();
$("#executionsView").show();
$('#summaryView').hide();
@@ -90,35 +90,35 @@ azkaban.ExecutionsView = Backbone.View.extend({
events: {
"click #pageSelection li": "handleChangePageSelection"
},
-
+
initialize: function(settings) {
this.model.bind('change:view', this.handleChangeView, this);
this.model.bind('render', this.render, this);
this.model.set({page: 1, pageSize: 16});
this.model.bind('change:page', this.handlePageChange, this);
},
-
+
render: function(evt) {
console.log("render");
// Render page selections
var tbody = $("#execTableBody");
tbody.empty();
-
+
var executions = this.model.get("executions");
for (var i = 0; i < executions.length; ++i) {
var row = document.createElement("tr");
-
+
var tdId = document.createElement("td");
var execA = document.createElement("a");
$(execA).attr("href", contextURL + "/executor?execid=" + executions[i].execId);
$(execA).text(executions[i].execId);
tdId.appendChild(execA);
row.appendChild(tdId);
-
+
var tdUser = document.createElement("td");
$(tdUser).text(executions[i].submitUser);
row.appendChild(tdUser);
-
+
var startTime = "-";
if (executions[i].startTime != -1) {
var startDateTime = new Date(executions[i].startTime);
@@ -128,7 +128,7 @@ azkaban.ExecutionsView = Backbone.View.extend({
var tdStartTime = document.createElement("td");
$(tdStartTime).text(startTime);
row.appendChild(tdStartTime);
-
+
var endTime = "-";
var lastTime = executions[i].endTime;
if (executions[i].endTime != -1) {
@@ -142,11 +142,11 @@ azkaban.ExecutionsView = Backbone.View.extend({
var tdEndTime = document.createElement("td");
$(tdEndTime).text(endTime);
row.appendChild(tdEndTime);
-
+
var tdElapsed = document.createElement("td");
$(tdElapsed).text( getDuration(executions[i].startTime, lastTime));
row.appendChild(tdElapsed);
-
+
var tdStatus = document.createElement("td");
var status = document.createElement("div");
$(status).addClass("status");
@@ -160,22 +160,22 @@ azkaban.ExecutionsView = Backbone.View.extend({
tbody.append(row);
}
-
+
this.renderPagination(evt);
},
-
+
renderPagination: function(evt) {
var total = this.model.get("total");
total = total? total : 1;
var pageSize = this.model.get("pageSize");
var numPages = Math.ceil(total / pageSize);
-
+
this.model.set({"numPages": numPages});
var page = this.model.get("page");
-
+
//Start it off
$("#pageSelection .active").removeClass("active");
-
+
// Disable if less than 5
console.log("Num pages " + numPages)
var i = 1;
@@ -185,7 +185,7 @@ azkaban.ExecutionsView = Backbone.View.extend({
for (; i <= 5; ++i) {
$("#page" + i).addClass("disabled");
}
-
+
// Disable prev/next if necessary.
if (page > 1) {
$("#previous").removeClass("disabled");
@@ -195,7 +195,7 @@ azkaban.ExecutionsView = Backbone.View.extend({
else {
$("#previous").addClass("disabled");
}
-
+
if (page < numPages) {
$("#next")[0].page = page + 1;
$("#next").removeClass("disabled");
@@ -205,7 +205,7 @@ azkaban.ExecutionsView = Backbone.View.extend({
$("#next")[0].page = page + 1;
$("#next").addClass("disabled");
}
-
+
// Selection is always in middle unless at barrier.
var startPage = 0;
var selectionPosition = 0;
@@ -235,14 +235,14 @@ azkaban.ExecutionsView = Backbone.View.extend({
for (var j = 0; j < 5; ++j) {
var realPage = startPage + j;
var elementId = "#page" + (j+1);
-
+
$(elementId)[0].page = realPage;
var a = $(elementId + " a");
a.text(realPage);
a.attr("href", "#page" + realPage);
}
},
-
+
handleChangePageSelection: function(evt) {
if ($(evt.currentTarget).hasClass("disabled")) {
return;
@@ -250,7 +250,7 @@ azkaban.ExecutionsView = Backbone.View.extend({
var page = evt.currentTarget.page;
this.model.set({"page": page});
},
-
+
handleChangeView: function(evt) {
if (this.init) {
return;
@@ -259,23 +259,23 @@ azkaban.ExecutionsView = Backbone.View.extend({
this.handlePageChange(evt);
this.init = true;
},
-
+
handlePageChange: function(evt) {
var page = this.model.get("page") - 1;
var pageSize = this.model.get("pageSize");
var requestURL = contextURL + "/manager";
-
+
var model = this.model;
var requestData = {
- "project": projectName,
- "flow": flowId,
- "ajax": "fetchFlowExecutions",
- "start": page * pageSize,
+ "project": projectName,
+ "flow": flowId,
+ "ajax": "fetchFlowExecutions",
+ "start": page * pageSize,
"length": pageSize
};
var successHandler = function(data) {
model.set({
- "executions": data.executions,
+ "executions": data.executions,
"total": data.total
});
model.trigger("render");
@@ -289,11 +289,11 @@ azkaban.SummaryView = Backbone.View.extend({
events: {
'click #analyze-btn': 'fetchLastRun'
},
-
+
initialize: function(settings) {
this.model.bind('change:view', this.handleChangeView, this);
this.model.bind('render', this.render, this);
-
+
this.fetchDetails();
this.fetchSchedule();
this.model.trigger('render');
@@ -306,7 +306,7 @@ azkaban.SummaryView = Backbone.View.extend({
'project': projectName,
'flow': flowId
};
-
+
var model = this.model;
var successHandler = function(data) {
@@ -318,7 +318,7 @@ azkaban.SummaryView = Backbone.View.extend({
};
$.get(requestURL, requestData, successHandler, 'json');
},
-
+
fetchSchedule: function() {
var requestURL = contextURL + "/schedule"
var requestData = {
@@ -390,10 +390,10 @@ $(function() {
// Execution model has to be created before the window switches the tabs.
executionModel = new azkaban.ExecutionModel();
executionsView = new azkaban.ExecutionsView({
- el: $('#executionsView'),
+ el: $('#executionsView'),
model: executionModel
});
-
+
summaryModel = new azkaban.SummaryModel();
summaryView = new azkaban.SummaryView({
el: $('#summaryView'),
@@ -407,35 +407,35 @@ $(function() {
});
flowTabView = new azkaban.FlowTabView({
- el: $('#headertabs'),
- selectedView: selected
+ el: $('#headertabs'),
+ selectedView: selected
});
graphModel = new azkaban.GraphModel();
mainSvgGraphView = new azkaban.SvgGraphView({
- el: $('#svgDiv'),
- model: graphModel,
- rightClick: {
- "node": nodeClickCallback,
- "edge": edgeClickCallback,
- "graph": graphClickCallback
+ el: $('#svgDiv'),
+ model: graphModel,
+ rightClick: {
+ "node": nodeClickCallback,
+ "edge": edgeClickCallback,
+ "graph": graphClickCallback
}
});
-
+
jobsListView = new azkaban.JobListView({
- el: $('#joblist-panel'),
- model: graphModel,
+ el: $('#joblist-panel'),
+ model: graphModel,
contextMenuCallback: jobClickCallback
});
-
+
executionsTimeGraphView = new azkaban.TimeGraphView({
- el: $('#timeGraph'),
+ el: $('#timeGraph'),
model: executionModel,
modelField: 'executions'
});
-
+
slaView = new azkaban.ChangeSlaView({el:$('#sla-options')});
-
+
var requestURL = contextURL + "/manager";
// Set up the Flow options view. Create a new one every time :p
$('#executebtn').click(function() {
@@ -451,15 +451,15 @@ $(function() {
});
var requestData = {
- "project": projectName,
- "ajax": "fetchflowgraph",
+ "project": projectName,
+ "ajax": "fetchflowgraph",
"flow": flowId
};
var successHandler = function(data) {
console.log("data fetched");
graphModel.addFlow(data);
graphModel.trigger("change:graph");
-
+
// Handle the hash changes here so the graph finishes rendering first.
if (window.location.hash) {
var hash = window.location.hash;
@@ -470,7 +470,7 @@ $(function() {
flowTabView.handleSummaryLinkClick();
}
else if (hash == "#graph") {
- // Redundant, but we may want to change the default.
+ // Redundant, but we may want to change the default.
selected = "graph";
}
else {
src/web/js/azkaban/view/flow-stats.js 32(+25 -7)
diff --git a/src/web/js/azkaban/view/flow-stats.js b/src/web/js/azkaban/view/flow-stats.js
index 3aee5be..dcf5985 100644
--- a/src/web/js/azkaban/view/flow-stats.js
+++ b/src/web/js/azkaban/view/flow-stats.js
@@ -21,9 +21,14 @@ azkaban.FlowStatsView = Backbone.View.extend({
events: {
},
+ histogram: true,
+
initialize: function(settings) {
this.model.bind('change:view', this.handleChangeView, this);
this.model.bind('render', this.render, this);
+ if (settings.histogram != null) {
+ this.histogram = settings.histogram;
+ }
},
render: function(evt) {
@@ -38,6 +43,9 @@ azkaban.FlowStatsView = Backbone.View.extend({
var requestData = {"execid": execId, "ajax":"fetchexecflow"};
var jobs = [];
var successHandler = function(data) {
+ data.nodes.sort(function(a, b) {
+ return a.startTime - b.startTime;
+ });
jobs = data.nodes;
};
$.ajax({
@@ -217,6 +225,7 @@ azkaban.FlowStatsView = Backbone.View.extend({
message: null,
warnings: [],
durations: [],
+ histogram: this.histogram,
stats: {
mapSlots: {
max: 0,
@@ -310,15 +319,24 @@ azkaban.FlowStatsView = Backbone.View.extend({
});
}
else {
+ var histogram = this.histogram;
dust.render("flowstats", data, function(err, out) {
view.display(out);
- Morris.Bar({
- element: "job-histogram",
- data: data.durations,
- xkey: "job",
- ykeys: ["duration"],
- labels: ["Duration"]
- });
+ if (histogram == true) {
+ var yLabelFormatCallback = function(y) {
+ var seconds = y / 1000.0;
+ return seconds.toString() + " s";
+ };
+
+ Morris.Bar({
+ element: "job-histogram",
+ data: data.durations,
+ xkey: "job",
+ ykeys: ["duration"],
+ labels: ["Duration"],
+ yLabelFormat: yLabelFormatCallback
+ });
+ }
});
}
},