azkaban-developers

Details

diff --git a/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm b/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
index 3ecc9cf..c8cbc5c 100644
--- a/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
@@ -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
@@ -14,16 +14,18 @@
  * the License.
 *#
 
-<!DOCTYPE html> 
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 
 #parse("azkaban/webapp/servlet/velocity/style.vm")
 #parse("azkaban/webapp/servlet/velocity/javascript.vm")
 #parse("azkaban/webapp/servlet/velocity/svgflowincludes.vm")
+    <script type="text/javascript" src="${context}/js/raphael.min.js"></script>
+    <script type="text/javascript" src="${context}/js/morris.min.js"></script>
 		<script type="text/javascript" src="${context}/js/moment.min.js"></script>
     <script type="text/javascript" src="${context}/js/bootstrap-datetimepicker.min.js"></script>
-    
+
     <script type="text/javascript" src="${context}/js/dust-full-2.2.3.min.js"></script>
 		<script type="text/javascript" src="${context}/js/flowstats.js"></script>
 		<script type="text/javascript" src="${context}/js/flowstats-no-data.js"></script>
@@ -43,7 +45,7 @@
 			var flowId = "${flowid}";
 			var execId = "${execid}";
 		</script>
-
+		<link rel="stylesheet" type="text/css" href="${context}/css/morris.css" />
 		<link rel="stylesheet" type="text/css" href="${context}/css/jquery-ui-1.10.1.custom.css" />
 	</head>
 	<body>
@@ -97,7 +99,7 @@
 		<div class="container-full">
 
   #parse ("azkaban/webapp/servlet/velocity/alerts.vm")
-	
+
 	## Tabs and buttons.
 
 			<ul class="nav nav-tabs nav-sm" id="headertabs">
@@ -116,7 +118,7 @@
 	## Graph View
 
 	#parse ("azkaban/webapp/servlet/velocity/flowgraphview.vm")
-	
+
 	## Job List View
 
     <div class="container-full" id="jobListView">
@@ -178,7 +180,7 @@
         </div>
 			</div><!-- /.row -->
     </div><!-- /.container-fill -->
-	
+
 	## Error message message dialog.
 
     <div class="container-full">
diff --git a/src/java/azkaban/webapp/servlet/velocity/flowpage.vm b/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
index acb0573..c523aea 100644
--- a/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
@@ -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
@@ -14,7 +14,7 @@
  * the License.
 *#
 
-<!DOCTYPE html> 
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 
@@ -25,12 +25,12 @@
     <script type="text/javascript" src="${context}/js/bootstrap-datetimepicker.min.js"></script>
     <script type="text/javascript" src="${context}/js/raphael.min.js"></script>
     <script type="text/javascript" src="${context}/js/morris.min.js"></script>
-		
+
     <script type="text/javascript" src="${context}/js/dust-full-2.2.3.min.js"></script>
 		<script type="text/javascript" src="${context}/js/flowsummary.js"></script>
 		<script type="text/javascript" src="${context}/js/flowstats-no-data.js"></script>
 		<script type="text/javascript" src="${context}/js/flowstats.js"></script>
-		
+
 		<script type="text/javascript" src="${context}/js/azkaban/view/time-graph.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban/util/schedule.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban/view/schedule-sla.js"></script>
@@ -43,7 +43,7 @@
 			var timezone = "${timezone}";
 			var errorMessage = null;
 			var successMessage = null;
-			
+
 			var projectId = ${project.id};
 			var projectName = "${project.name}";
 			var flowId = "${flowid}";
@@ -60,7 +60,7 @@
 #if ($errorMsg)
   #parse ("azkaban/webapp/servlet/velocity/errormsg.vm")
 #else
-	
+
 	## Page header.
 
 		<div class="az-page-header page-header-bare">
@@ -87,9 +87,9 @@
     </div>
 
 		<div class="container-full">
-      
+
   #parse ("azkaban/webapp/servlet/velocity/alerts.vm")
-  
+
   ## Tabs
 
 			<ul class="nav nav-tabs nav-sm" id="headertabs">
@@ -98,7 +98,7 @@
 				<li id="summaryViewLink"><a href="#summary">Summary</a></li>
 			</ul>
     </div>
-					
+
 	## Graph view.
 
 	#parse ("azkaban/webapp/servlet/velocity/flowgraphview.vm")
diff --git a/src/java/azkaban/webapp/servlet/velocity/jobhistorypage.vm b/src/java/azkaban/webapp/servlet/velocity/jobhistorypage.vm
index b1838bb..270f8e1 100644
--- a/src/java/azkaban/webapp/servlet/velocity/jobhistorypage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/jobhistorypage.vm
@@ -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
@@ -14,7 +14,7 @@
  * the License.
 *#
 
-<!DOCTYPE html> 
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 
@@ -32,7 +32,7 @@
 			var timezone = "${timezone}";
 			var errorMessage = null;
 			var successMessage = null;
-			
+
 			var projectId = "$projectId";
 			var projectName = "$projectName";
 			var jobName = "$jobid";
@@ -48,7 +48,7 @@
 #if ($errorMsg)
   #parse ("azkaban/webapp/servlet/velocity/errormsg.vm")
 #else
-	
+
 	## Page header
 
 		<div class="az-page-header page-header-bare">
@@ -66,7 +66,7 @@
     </div>
 
 		<div class="container-full">
-	
+
   #parse ("azkaban/webapp/servlet/velocity/alerts.vm")
 
   ## Time graph and job history table.
@@ -84,7 +84,7 @@
                 <th class="flowid">Flow</th>
                 <th class="date">Start Time</th>
                 <th class="date">End Time</th>
-                <th class="elapse">Elapse</th>		
+                <th class="elapse">Elapse</th>
                 <th class="status">Status</th>
                 <th class="logs">Logs</th>
               </tr>
diff --git a/src/tl/flowstats.tl b/src/tl/flowstats.tl
index 8fffebe..ef24ad0 100644
--- a/src/tl/flowstats.tl
+++ b/src/tl/flowstats.tl
@@ -1,5 +1,13 @@
       <div class="row">
         <div class="col-xs-12">
+          <div class="well well-clear well-sm">
+            <div id="job-histogram"></div>
+          </div>
+        </div>
+      </div>
+
+      <div class="row">
+        <div class="col-xs-12">
           <h4>Resources</h4>
           <table class="table table-bordered table-condensed table-striped">
             <thead>
diff --git a/src/web/js/azkaban/view/flow-stats.js b/src/web/js/azkaban/view/flow-stats.js
index 5f2919e..3aee5be 100644
--- a/src/web/js/azkaban/view/flow-stats.js
+++ b/src/web/js/azkaban/view/flow-stats.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
@@ -25,7 +25,7 @@ azkaban.FlowStatsView = Backbone.View.extend({
 		this.model.bind('change:view', this.handleChangeView, this);
 		this.model.bind('render', this.render, this);
   },
-	
+
   render: function(evt) {
   },
 
@@ -38,10 +38,7 @@ azkaban.FlowStatsView = Backbone.View.extend({
     var requestData = {"execid": execId, "ajax":"fetchexecflow"};
     var jobs = [];
     var successHandler = function(data) {
-      for (var i = 0; i < data.nodes.length; ++i) {
-        var node = data.nodes[i];
-        jobs.push(node.id);
-      }
+      jobs = data.nodes;
     };
     $.ajax({
       url: requestURL,
@@ -127,7 +124,7 @@ azkaban.FlowStatsView = Backbone.View.extend({
         }
       }
       if (str.indexOf('Xms') > -1) {
-        if (str.length <= 4) { 
+        if (str.length <= 4) {
           continue;
         }
         var size = str.substring(4, str.length);
@@ -179,13 +176,13 @@ azkaban.FlowStatsView = Backbone.View.extend({
       stats.fileBytesWritten.max = fileBytesWritten;
       stats.fileBytesWritten.job = job;
     }
-    
+
     var hdfsBytesRead = parseInt(fileSystemCounters['HDFS_BYTES_READ']);
     if (hdfsBytesRead >= stats.hdfsBytesRead.max) {
       stats.hdfsBytesRead.max = hdfsBytesRead;
       stats.hdfsBytesRead.job = job;
     }
-    
+
     var hdfsBytesWritten = parseInt(fileSystemCounters['HDFS_BYTES_WRITTEN']);
     if (hdfsBytesWritten >= stats.hdfsBytesWritten.max) {
       stats.hdfsBytesWritten.max = hdfsBytesWritten;
@@ -219,6 +216,7 @@ azkaban.FlowStatsView = Backbone.View.extend({
       success: false,
       message: null,
       warnings: [],
+      durations: [],
       stats: {
         mapSlots: {
           max: 0,
@@ -277,13 +275,19 @@ azkaban.FlowStatsView = Backbone.View.extend({
 
     for (var i = 0; i < jobs.length; ++i) {
       var job = jobs[i];
-      var jobStats = this.fetchJobStats(job, execId);
+      var duration = job.endTime - job.startTime;
+      data.durations.push({
+        job: job.id,
+        duration: duration
+      });
+
+      var jobStats = this.fetchJobStats(job.id, execId);
       if (jobStats.jobStats == null) {
         data.warnings.push("No job stats available for job " + job.id);
         continue;
       }
       for (var j = 0; j < jobStats.jobStats.length; ++j) {
-        this.updateStats(jobStats.jobStats[j], data, job);
+        this.updateStats(jobStats.jobStats[j], data, job.id);
       }
     }
     this.finalizeStats(data);
@@ -308,6 +312,13 @@ azkaban.FlowStatsView = Backbone.View.extend({
     else {
       dust.render("flowstats", data, function(err, out) {
         view.display(out);
+        Morris.Bar({
+          element: "job-histogram",
+          data: data.durations,
+          xkey: "job",
+          ykeys: ["duration"],
+          labels: ["Duration"]
+        });
       });
     }
   },