You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tez.apache.org by ss...@apache.org on 2015/05/06 09:41:09 UTC

[07/50] [abbrv] tez git commit: TEZ-2386. Tez UI: Inconsistent usage of icon colors (pramachandran)

TEZ-2386. Tez UI: Inconsistent usage of icon colors (pramachandran)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/1dd5f9fd
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/1dd5f9fd
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/1dd5f9fd

Branch: refs/heads/TEZ-2003
Commit: 1dd5f9fdae99ebb6d1351d2ac49a16065251d689
Parents: 748f58d
Author: Prakash Ramachandran <pr...@hortonworks.com>
Authored: Fri May 1 19:40:57 2015 +0530
Committer: Prakash Ramachandran <pr...@hortonworks.com>
Committed: Fri May 1 19:41:46 2015 +0530

----------------------------------------------------------------------
 CHANGES.txt                                       |  1 +
 .../org/apache/tez/dag/app/dag/impl/TaskImpl.java |  4 ++--
 .../tez/dag/history/events/TaskFinishedEvent.java |  8 +++++++-
 .../tez/dag/app/dag/impl/TestTaskRecovery.java    |  4 ++--
 .../events/TestHistoryEventsProtoConversion.java  |  4 ++--
 .../impl/TestHistoryEventJsonConversion.java      |  2 +-
 .../ats/HistoryEventTimelineConversion.java       |  1 +
 .../ats/TestHistoryEventTimelineConversion.java   |  7 ++++---
 .../app/scripts/components/dag-view/graph-view.js |  3 ++-
 .../scripts/controllers/dag_index_controller.js   | 17 +++++++++--------
 .../webapp/app/scripts/controllers/dag_tasks.js   |  5 +++--
 .../app/scripts/controllers/dag_vertices.js       |  5 +++--
 .../app/scripts/controllers/dags_controller.js    |  5 +++--
 .../scripts/controllers/task_index_controller.js  |  7 ++++---
 .../app/scripts/controllers/tasks_controller.js   |  5 +++--
 .../controllers/tez-app-dags-controller.js        |  5 +++--
 .../controllers/vertex_index_controller.js        |  5 +++--
 .../controllers/vertex_tasks_controller.js        |  5 +++--
 .../app/scripts/models/TimelineRestAdapter.js     | 18 ++++++++++++++++++
 tez-ui/src/main/webapp/app/scripts/models/dag.js  | 16 ++++++++++++++++
 tez-ui/src/main/webapp/app/styles/main.less       | 10 ++++++----
 .../src/main/webapp/app/templates/dag/index.hbs   |  3 +++
 .../main/webapp/app/templates/vertex/index.hbs    |  6 ++++++
 23 files changed, 105 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 3cc9764..fe90418 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,6 +9,7 @@ INCOMPATIBLE CHANGES
   TEZ-1993. Implement a pluggable InputSizeEstimator for grouping fairly
 
 ALL CHANGES:
+  TEZ-2386. Tez UI: Inconsistent usage of icon colors
   TEZ-2395. Tez UI: Minimum/Maximum Duration show a empty bracket next to 0 secs when you purposefully failed a job.
   TEZ-2360. per-io counters flag should generate both overall and per-edge counters
   TEZ-2389. Tez UI: Sort by attempt-no is incorrect in attempts pages.

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java
index 91413a5..461339b 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java
@@ -948,7 +948,7 @@ public class TaskImpl implements Task, EventHandler<TaskEvent> {
     TaskFinishedEvent finishEvt = new TaskFinishedEvent(taskId,
         getVertex().getName(), getLaunchTime(), clock.getTime(),
         successfulAttempt,
-        TaskState.SUCCEEDED, "", getCounters());
+        TaskState.SUCCEEDED, "", getCounters(), failedAttempts);
     this.appContext.getHistoryHandler().handle(
         new DAGHistoryEvent(taskId.getVertexID().getDAGId(), finishEvt));
   }
@@ -958,7 +958,7 @@ public class TaskImpl implements Task, EventHandler<TaskEvent> {
         getVertex().getName(), getLaunchTime(), clock.getTime(), null,
         finalState, 
         StringUtils.join(getDiagnostics(), LINE_SEPARATOR),
-        getCounters());
+        getCounters(), failedAttempts);
     this.appContext.getHistoryHandler().handle(
         new DAGHistoryEvent(taskId.getVertexID().getDAGId(), finishEvt));
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-dag/src/main/java/org/apache/tez/dag/history/events/TaskFinishedEvent.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/history/events/TaskFinishedEvent.java b/tez-dag/src/main/java/org/apache/tez/dag/history/events/TaskFinishedEvent.java
index fa4f8ca..71ff6c8 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/history/events/TaskFinishedEvent.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/history/events/TaskFinishedEvent.java
@@ -44,11 +44,12 @@ public class TaskFinishedEvent implements HistoryEvent {
   private TezCounters tezCounters;
   private TezTaskAttemptID successfulAttemptID;
   private String diagnostics;
+  private int numFailedAttempts;
 
   public TaskFinishedEvent(TezTaskID taskID,
       String vertexName, long startTime, long finishTime,
       TezTaskAttemptID successfulAttemptID,
-      TaskState state, String diagnostics, TezCounters counters) {
+      TaskState state, String diagnostics, TezCounters counters, int failedAttempts) {
     this.vertexName = vertexName;
     this.taskID = taskID;
     this.startTime = startTime;
@@ -57,6 +58,7 @@ public class TaskFinishedEvent implements HistoryEvent {
     this.diagnostics = diagnostics;
     this.tezCounters = counters;
     this.successfulAttemptID = successfulAttemptID;
+    this.numFailedAttempts = failedAttempts;
   }
 
   public TaskFinishedEvent() {
@@ -161,4 +163,8 @@ public class TaskFinishedEvent implements HistoryEvent {
   public String getDiagnostics() {
     return diagnostics;
   }
+
+  public int getNumFailedAttempts() {
+    return numFailedAttempts;
+  }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskRecovery.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskRecovery.java b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskRecovery.java
index c2185d8..e182f24 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskRecovery.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskRecovery.java
@@ -240,7 +240,7 @@ public class TestTaskRecovery {
     try {
       task.restoreFromEvent(new TaskFinishedEvent(task.getTaskId(), vertexName,
           taskStartTime, taskFinishTime, null, TaskState.SUCCEEDED, "",
-          new TezCounters()));
+          new TezCounters(), 0));
       fail("Should fail due to no TaskStartEvent before TaskFinishEvent");
     } catch (Throwable e) {
       assertTrue(e.getMessage().contains(
@@ -413,7 +413,7 @@ public class TestTaskRecovery {
     recoveredState =
         task.restoreFromEvent(new TaskFinishedEvent(task.getTaskId(),
             vertexName, taskStartTime, taskFinishTime, taId,
-            TaskState.SUCCEEDED, "", new TezCounters()));
+            TaskState.SUCCEEDED, "", new TezCounters(), 0));
     assertEquals(TaskState.SUCCEEDED, recoveredState);
     assertEquals(taId, task.successfulAttempt);
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-dag/src/test/java/org/apache/tez/dag/history/events/TestHistoryEventsProtoConversion.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/history/events/TestHistoryEventsProtoConversion.java b/tez-dag/src/test/java/org/apache/tez/dag/history/events/TestHistoryEventsProtoConversion.java
index 302700c..1575adc 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/history/events/TestHistoryEventsProtoConversion.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/history/events/TestHistoryEventsProtoConversion.java
@@ -424,7 +424,7 @@ public class TestHistoryEventsProtoConversion {
       TaskFinishedEvent event = new TaskFinishedEvent(
           TezTaskID.getInstance(TezVertexID.getInstance(
               TezDAGID.getInstance(ApplicationId.newInstance(0, 1), 1), 111), 1),
-          "vertex1", 11000l, 1000000l, null, TaskState.FAILED, null, null);
+          "vertex1", 11000l, 1000000l, null, TaskState.FAILED, null, null, 0);
       TaskFinishedEvent deserializedEvent = (TaskFinishedEvent)
           testProtoConversion(event);
       Assert.assertEquals(event.getTaskID(), deserializedEvent.getTaskID());
@@ -444,7 +444,7 @@ public class TestHistoryEventsProtoConversion {
           "vertex1", 11000l, 1000000l,
           TezTaskAttemptID.getInstance(TezTaskID.getInstance(TezVertexID.getInstance(
               TezDAGID.getInstance(ApplicationId.newInstance(0, 1), 1), 111), 1), 1),
-          TaskState.FAILED, "task_diagnostics", new TezCounters());
+          TaskState.FAILED, "task_diagnostics", new TezCounters(), 0);
       TaskFinishedEvent deserializedEvent = (TaskFinishedEvent)
           testProtoConversion(event);
       Assert.assertEquals(event.getTaskID(), deserializedEvent.getTaskID());

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-dag/src/test/java/org/apache/tez/dag/history/logging/impl/TestHistoryEventJsonConversion.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/history/logging/impl/TestHistoryEventJsonConversion.java b/tez-dag/src/test/java/org/apache/tez/dag/history/logging/impl/TestHistoryEventJsonConversion.java
index c6749af..6469e78 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/history/logging/impl/TestHistoryEventJsonConversion.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/history/logging/impl/TestHistoryEventJsonConversion.java
@@ -155,7 +155,7 @@ public class TestHistoryEventJsonConversion {
           break;
         case TASK_FINISHED:
           event = new TaskFinishedEvent(tezTaskID, "v1", random.nextInt(), random.nextInt(),
-              tezTaskAttemptID, TaskState.FAILED, null, null);
+              tezTaskAttemptID, TaskState.FAILED, null, null, 0);
           break;
         case TASK_ATTEMPT_STARTED:
           event = new TaskAttemptStartedEvent(tezTaskAttemptID, "v1", random.nextInt(), containerId,

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/HistoryEventTimelineConversion.java
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/HistoryEventTimelineConversion.java b/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/HistoryEventTimelineConversion.java
index 7c804f5..77f4dd1 100644
--- a/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/HistoryEventTimelineConversion.java
+++ b/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/HistoryEventTimelineConversion.java
@@ -493,6 +493,7 @@ public class HistoryEventTimelineConversion {
     atsEntity.addOtherInfo(ATSConstants.FINISH_TIME, event.getFinishTime());
     atsEntity.addOtherInfo(ATSConstants.TIME_TAKEN, (event.getFinishTime() - event.getStartTime()));
     atsEntity.addOtherInfo(ATSConstants.STATUS, event.getState().name());
+    atsEntity.addOtherInfo(ATSConstants.NUM_FAILED_TASKS_ATTEMPTS, event.getNumFailedAttempts());
     if (event.getSuccessfulAttemptID() != null) {
       atsEntity.addOtherInfo(ATSConstants.SUCCESSFUL_ATTEMPT_ID,
           event.getSuccessfulAttemptID().toString());

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-plugins/tez-yarn-timeline-history/src/test/java/org/apache/tez/dag/history/logging/ats/TestHistoryEventTimelineConversion.java
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-yarn-timeline-history/src/test/java/org/apache/tez/dag/history/logging/ats/TestHistoryEventTimelineConversion.java b/tez-plugins/tez-yarn-timeline-history/src/test/java/org/apache/tez/dag/history/logging/ats/TestHistoryEventTimelineConversion.java
index 3d2b662..f5f3ae7 100644
--- a/tez-plugins/tez-yarn-timeline-history/src/test/java/org/apache/tez/dag/history/logging/ats/TestHistoryEventTimelineConversion.java
+++ b/tez-plugins/tez-yarn-timeline-history/src/test/java/org/apache/tez/dag/history/logging/ats/TestHistoryEventTimelineConversion.java
@@ -160,7 +160,7 @@ public class TestHistoryEventTimelineConversion {
           break;
         case TASK_FINISHED:
           event = new TaskFinishedEvent(tezTaskID, "v1", random.nextInt(), random.nextInt(),
-              tezTaskAttemptID, TaskState.FAILED, null, null);
+              tezTaskAttemptID, TaskState.FAILED, null, null, 0);
           break;
         case TASK_ATTEMPT_STARTED:
           event = new TaskAttemptStartedEvent(tezTaskAttemptID, "v1", random.nextInt(), containerId,
@@ -778,7 +778,7 @@ public class TestHistoryEventTimelineConversion {
     TezCounters counters = new TezCounters();
 
     TaskFinishedEvent event = new TaskFinishedEvent(tezTaskID, vertexName, startTime, finishTime,
-        tezTaskAttemptID, state, diagnostics, counters);
+        tezTaskAttemptID, state, diagnostics, counters, 3);
     TimelineEntity timelineEntity = HistoryEventTimelineConversion.convertToTimelineEntity(event);
 
     Assert.assertEquals(tezTaskID.toString(), timelineEntity.getEntityId());
@@ -800,12 +800,13 @@ public class TestHistoryEventTimelineConversion {
     Assert.assertEquals(finishTime, evt.getTimestamp());
 
     final Map<String, Object> otherInfo = timelineEntity.getOtherInfo();
-    Assert.assertEquals(6, otherInfo.size());
+    Assert.assertEquals(7, otherInfo.size());
     Assert.assertEquals(finishTime, otherInfo.get(ATSConstants.FINISH_TIME));
     Assert.assertEquals(finishTime - startTime, otherInfo.get(ATSConstants.TIME_TAKEN));
     Assert.assertEquals(state.name(), otherInfo.get(ATSConstants.STATUS));
     Assert.assertEquals(tezTaskAttemptID.toString(),
         otherInfo.get(ATSConstants.SUCCESSFUL_ATTEMPT_ID));
+    Assert.assertEquals(3, otherInfo.get(ATSConstants.NUM_FAILED_TASKS_ATTEMPTS));
     Assert.assertEquals(diagnostics, otherInfo.get(ATSConstants.DIAGNOSTICS));
     Assert.assertTrue(otherInfo.containsKey(ATSConstants.COUNTERS));
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/components/dag-view/graph-view.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/components/dag-view/graph-view.js b/tez-ui/src/main/webapp/app/scripts/components/dag-view/graph-view.js
index 45202ae..f3a87fd 100644
--- a/tez-ui/src/main/webapp/app/scripts/components/dag-view/graph-view.js
+++ b/tez-ui/src/main/webapp/app/scripts/components/dag-view/graph-view.js
@@ -223,7 +223,8 @@ App.DagViewComponent.graphView = (function (){
    */
   function _addStatusBar(node, d) {
     var group = node.append('g'),
-        statusIcon = App.Helpers.misc.getStatusClassForEntity(d.get('data.status'));
+        statusIcon = App.Helpers.misc.getStatusClassForEntity(d.get('data.status'),
+          d.get('data.hasFailedTaskAttempts'));
     group.attr('class', 'status-bar');
 
     group.append('foreignObject')

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js
index 416f500..2deab2d 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_index_controller.js
@@ -75,8 +75,9 @@ App.DagIndexController = Em.ObjectController.extend(App.ModelRefreshMixin, {
   },
 
   taskIconStatus: function() {
-    return App.Helpers.misc.getStatusClassForEntity(this.get('model.status'));
-  }.property('id', 'status', 'counterGroups'),
+    return App.Helpers.misc.getStatusClassForEntity(this.get('model.status'),
+      this.get('hasFailedTaskAttempts'));
+  }.property('id', 'model.status', 'hasFailedTaskAttempts'),
 
   progressStr: function() {
     var pct;
@@ -106,12 +107,12 @@ App.DagIndexController = Em.ObjectController.extend(App.ModelRefreshMixin, {
       'org.apache.tez.common.counters.DAGCounter', 'NUM_KILLED_TASKS')
   }.property('id', 'counterGroups'),
 
-  hasFailedTasks: function() {
-    return this.get('failedTasks') > 0;
-  }.property('id', 'counterGroups'),
-
   failedTasksLink: function() {
-    return '#tasks?status=FAILED&parentType=TEZ_DAG_ID&parentID=' + this.get('id');
-  }.property()
+    return '#/dag/%@/tasks?searchText=Status%3AFAILED'.fmt(this.get('id'));
+  }.property('id'),
+
+  failedTaskAttemptsLink: function() {
+    return '#/dag/%@/taskAttempts?searchText=Status%3AFAILED'.fmt(this.get('id'));
+  }.property('id'),
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
index 598fa3f..ec4a47f 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
@@ -163,7 +163,8 @@ App.DagTasksController = App.TablePageController.extend({
           var status = row.get('status');
           return {
             status: status,
-            statusIcon: App.Helpers.misc.getStatusClassForEntity(status)
+            statusIcon: App.Helpers.misc.getStatusClassForEntity(status,
+              row.get('hasFailedTaskAttempts'))
           };
         }
       },
@@ -189,7 +190,7 @@ App.DagTasksController = App.TablePageController.extend({
         }
       }
     ];
-  }.property(),
+  }.property('id'),
 
   columnConfigs: function() {
     return this.get('defaultColumnConfigs').concat(

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
index 4e5531a..e531bdf 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_vertices.js
@@ -175,7 +175,8 @@ App.DagVerticesController = App.TablePageController.extend({
               content = Ember.Object.create({
                 vertex: row,
                 status: status,
-                statusIcon: App.Helpers.misc.getStatusClassForEntity(status)
+                statusIcon: App.Helpers.misc.getStatusClassForEntity(status,
+                  row.get('hasFailedTaskAttempts'))
               });
 
           if(status == 'RUNNING') {
@@ -203,7 +204,7 @@ App.DagVerticesController = App.TablePageController.extend({
         }
       }
     ];
-  }.property(),
+  }.property('id'),
 
   columnConfigs: function() {
     return this.get('defaultColumnConfigs').concat(

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
index 94c6505..c02945c 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
@@ -221,7 +221,8 @@ App.DagsController = Em.ObjectController.extend(App.PaginatedContentMixin, App.C
               content = Ember.Object.create({
                 dag: row,
                 status: status,
-                statusIcon: App.Helpers.misc.getStatusClassForEntity(status)
+                statusIcon: App.Helpers.misc.getStatusClassForEntity(status,
+                  row.get('hasFailedTaskAttempts'))
               });
 
           if(status == 'RUNNING') {
@@ -292,7 +293,7 @@ App.DagsController = Em.ObjectController.extend(App.PaginatedContentMixin, App.C
         }
       }
     ];
-  }.property(),
+  }.property('id'),
 
   columnConfigs: function() {
     return this.get('defaultColumnConfigs').concat(

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js
index 2c526c4..1772e9c 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js
@@ -22,10 +22,11 @@ App.TaskIndexController = Em.ObjectController.extend(App.ModelRefreshMixin, {
 
   taskStatus: function() {
     return App.Helpers.misc.getFixedupDisplayStatus(this.get('model.status'));
-  }.property('id', 'status'),
+  }.property('id', 'model.status'),
 
   taskIconStatus: function() {
-    return App.Helpers.misc.getStatusClassForEntity(this.get('taskStatus'));
-  }.property('id', 'status', 'counterGroups'),
+    return App.Helpers.misc.getStatusClassForEntity(this.get('taskStatus'),
+      this.get('hasFailedTaskAttempts'));
+  }.property('id', 'taskStatus', 'hasFailedTaskAttempts'),
 
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/tasks_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/tasks_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/tasks_controller.js
index 548b516..366a86a 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/tasks_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/tasks_controller.js
@@ -106,13 +106,14 @@ App.TasksController = Em.ObjectController.extend(App.PaginatedContentMixin, App.
           var taskStatus = row.get('status');
           return {
             status: taskStatus,
-            statusIcon: App.Helpers.misc.getStatusClassForEntity(taskStatus)
+            statusIcon: App.Helpers.misc.getStatusClassForEntity(taskStatus,
+              row.get('hasFailedTaskAttempts'))
           };
         }
       }
     ];
     
-  }.property(),
+  }.property('id'),
 
   columnConfigs: function() {
     return this.get('defaultColumnConfigs').concat(

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/tez-app-dags-controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/tez-app-dags-controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/tez-app-dags-controller.js
index 22aaaf9..a61f8bb 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/tez-app-dags-controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/tez-app-dags-controller.js
@@ -94,7 +94,8 @@ App.TezAppDagsController = App.TablePageController.extend({
           var status = row.get('status'),
               content = Ember.Object.create({
                 status: status,
-                statusIcon: App.Helpers.misc.getStatusClassForEntity(status)
+                statusIcon: App.Helpers.misc.getStatusClassForEntity(status,
+                  row.get('hasFailedTaskAttempts'))
               });
 
           if(status == 'RUNNING') {
@@ -149,7 +150,7 @@ App.TezAppDagsController = App.TablePageController.extend({
         },
       }
     ];
-  }.property(),
+  }.property('id'),
 
   columnConfigs: function() {
     return this.get('defaultColumnConfigs').concat(

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js
index ebddf53..2339e99 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js
@@ -37,8 +37,9 @@ App.VertexIndexController = Em.ObjectController.extend(App.ModelRefreshMixin, {
 
   //TODO: TEZ-1705 : Create a parent class and move this function there to avoid duplication.
   iconStatus: function() {
-    return App.Helpers.misc.getStatusClassForEntity(this.get('model.status'));
-  }.property('id', 'model.status'),
+    return App.Helpers.misc.getStatusClassForEntity(this.get('model.status'),
+      this.get('model.hasFailedTaskAttempts'));
+  }.property('id', 'model.status', 'model.hasFailedTaskAttempts'),
 
   progressStr: function() {
     var pct;

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js
index 08c1a87..953ffcd 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js
@@ -145,7 +145,8 @@ App.VertexTasksController = App.TablePageController.extend({
           var status = row.get('status');
           return {
             status: status,
-            statusIcon: App.Helpers.misc.getStatusClassForEntity(status)
+            statusIcon: App.Helpers.misc.getStatusClassForEntity(status,
+              row.get('hasFailedTaskAttempts'))
           };
         }
       },
@@ -171,7 +172,7 @@ App.VertexTasksController = App.TablePageController.extend({
         }
       }
     ];
-  }.property(),
+  }.property('id'),
 
   columnConfigs: function() {
     return this.get('defaultColumnConfigs').concat(

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js b/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js
index 9c84771..5db0990 100644
--- a/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js
+++ b/tez-ui/src/main/webapp/app/scripts/models/TimelineRestAdapter.js
@@ -95,6 +95,15 @@ var timelineJsonToDagMap = {
   user: 'primaryfilters.user.0',
   applicationId: 'otherinfo.applicationId',
   status: 'otherinfo.status',
+  hasFailedTaskAttempts: {
+    custom: function(source) {
+      // if no other info is available we say no failed tasks attempts.
+      // since otherinfo is populated only at the end.
+      var numFailedAttempts = Em.get(source, 'otherinfo.numFailedTaskAttempts');
+      return !!numFailedAttempts && numFailedAttempts > 0;
+    }
+  },
+  numFailedTasks: 'otherinfo.numFailedTasks',
   diagnostics: 'otherinfo.diagnostics',
 
   counterGroups: 'otherinfo.counters.counterGroups',
@@ -158,6 +167,7 @@ var timelineJsonToTaskMap = {
   vertexID: 'primaryfilters.TEZ_VERTEX_ID.0',
   endTime: 'otherinfo.endTime',
   status: 'otherinfo.status',
+  numFailedTaskAttempts: 'otherinfo.numFailedTaskAttempts',
   diagnostics: 'otherinfo.diagnostics',
   counterGroups: 'otherinfo.counters.counterGroups',
   successfulAttemptId: 'otherinfo.successfulAttemptId',
@@ -187,6 +197,14 @@ var timelineJsonToVertexMap = {
   endTime: 'otherinfo.endTime',
 
   status: 'otherinfo.status',
+  hasFailedTaskAttempts: {
+    custom: function(source) {
+      // if no other info is available we say no failed tasks attempts.
+      // since otherinfo is populated only at the end.
+      var numFailedAttempts = Em.get(source, 'otherinfo.numFailedTaskAttempts');
+      return !!numFailedAttempts && numFailedAttempts > 0;
+    }
+  },
   diagnostics: 'otherinfo.diagnostics',
 
   failedTasks: 'otherinfo.numFailedTasks',

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/scripts/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/models/dag.js b/tez-ui/src/main/webapp/app/scripts/models/dag.js
index 9053078..db6577f 100644
--- a/tez-ui/src/main/webapp/app/scripts/models/dag.js
+++ b/tez-ui/src/main/webapp/app/scripts/models/dag.js
@@ -50,6 +50,12 @@ App.Dag = App.AbstractEntity.extend({
 
 	// status
 	status: DS.attr('string'),
+  hasFailedTaskAttempts: DS.attr('boolean'),
+  hasFailedTasks: function() {
+    var f = this.get('numFailedTasks');
+    return !!f && f > 0;
+  }.property('numFailedTasks'),
+  numFailedTasks: DS.attr('number'),
 
 	// diagnostics info if any.
 	diagnostics: DS.attr('string'),
@@ -118,6 +124,11 @@ App.Vertex = App.AbstractEntity.extend({
    * App.VertexState.
    */
   status: DS.attr('string'),
+  hasFailedTaskAttempts: DS.attr('boolean'),
+  hasFailedTasks: function() {
+    var f = this.get('failedTasks');
+    return !!f && f > 0;
+  }.property('failedTasks'),
 
   /**
    * Vertex type has to be one of the types defined in 'App.VertexType'
@@ -349,6 +360,11 @@ App.Task = App.AbstractEntity.extend({
   pivotAttempt: DS.belongsTo('taskAttempt'),
 
   counterGroups: DS.attr('array'), // Serialize when required
+  numFailedTaskAttempts: DS.attr('number'),
+  hasFailedTaskAttempts: function() {
+    var numAttempts = this.get('numFailedTaskAttempts') || 0;
+    return numAttempts > 1;
+  }.property('numFailedTaskAttempts')
 });
 App.DagTask = App.Task.extend({});
 App.VertexTask = App.Task.extend({});

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/styles/main.less
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/styles/main.less b/tez-ui/src/main/webapp/app/styles/main.less
index ba8f375..5da7e06 100644
--- a/tez-ui/src/main/webapp/app/styles/main.less
+++ b/tez-ui/src/main/webapp/app/styles/main.less
@@ -382,9 +382,6 @@ body, html {
 .task-status {
   .fa;
   .fa-lg;
-  .absolute;
-
-  top: 7px;
 
   &.success {
     .fa-icon(check-circle);
@@ -408,7 +405,7 @@ body, html {
   }
 
   &.warning {
-    .fa-icon(exclamation-triangle);
+    .fa-icon(check-circle);
     color: @warning-color;
   }
 
@@ -637,6 +634,11 @@ body, html {
 .table-container {
   .use-gpu;
 
+  .task-status {
+    .absolute;
+    top: 7px;
+  }
+
   margin: 10px 0px;
 
   .table-header {

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/dag/index.hbs b/tez-ui/src/main/webapp/app/templates/dag/index.hbs
index e7c6264..1384de2 100644
--- a/tez-ui/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui/src/main/webapp/app/templates/dag/index.hbs
@@ -63,6 +63,9 @@
             {{#if hasFailedTasks}}
               [ <a href='{{unbound failedTasksLink}}'>Failed Tasks</a> ]
             {{/if}}
+            {{#if hasFailedTaskAttempts}}
+              [ <a href='{{unbound failedTaskAttemptsLink}}'>Failed TaskAttempts</a> ]
+            {{/if}}
           </td>
         </tr>
         <tr>

http://git-wip-us.apache.org/repos/asf/tez/blob/1dd5f9fd/tez-ui/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui/src/main/webapp/app/templates/vertex/index.hbs
index acdce99..56f4eb9 100644
--- a/tez-ui/src/main/webapp/app/templates/vertex/index.hbs
+++ b/tez-ui/src/main/webapp/app/templates/vertex/index.hbs
@@ -65,6 +65,12 @@
             <i {{bind-attr class=':task-status iconStatus'}}></i>
             {{status}}
             {{#if progressStr}} {{bs-badge content=progressStr}}{{/if}}
+            {{#if hasFailedTasks}}
+              [ <a href='{{unbound failedTasksLink}}'>Failed Tasks</a> ]
+            {{/if}}
+            {{#if hasFailedTaskAttempts}}
+              [ <a href='{{unbound failedTaskAttemptsLink}}'>Failed TaskAttempts</a> ]
+            {{/if}}
           </td>
         </tr>
         <tr>