flink-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From u..@apache.org
Subject [09/11] flink git commit: [FLINK-4410] [runtime-web] Rebuild JS/HTML files
Date Tue, 10 Jan 2017 08:49:48 GMT
http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node-list.checkpoints.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node-list.checkpoints.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node-list.checkpoints.html
index 690881c..66906dd 100644
--- a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node-list.checkpoints.html
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node-list.checkpoints.html
@@ -17,32 +17,15 @@ See the License for the specific language governing permissions and
 limitations under the License.
 
 -->
-<div ng-if="!jobCheckpointStats">
-  <p><em>No checkpoints</em></p>
-</div>
-<div ng-if="jobCheckpointStats">
-  <h2>Overview</h2>
-  <div ng-include=" 'partials/jobs/job.plan.node.checkpoints.job.html' "></div>
-  <h2>Operators</h2>
-  <table class="table table-body-hover table-clickable table-activable">
-    <thead>
-      <tr>
-        <th>Name</th>
-        <th>Status</th>
-      </tr>
-    </thead>
-    <tbody ng-repeat="v in job.vertices" ng-class="{ active: v.id == nodeid }" ng-click="v.id == nodeid || changeNode(v.id)">
-      <tr ng-if="v.type == 'regular'">
-        <td>{{ v.name | humanizeText }}</td>
-        <td>
-          <bs-label status="{{v.status}}">{{v.status}}</bs-label>
-        </td>
-      </tr>
-      <tr ng-if="nodeid &amp;&amp; v.id == nodeid">
-        <td colspan="10">
-          <div ng-include=" 'partials/jobs/job.plan.node.checkpoints.operator.html' "></div>
-        </td>
-      </tr>
-    </tbody>
-  </table>
+<div class="split">
+  <nav class="navbar navbar-default navbar-secondary-additional">
+    <ul class="nav nav-tabs">
+      <li ui-sref-active="active"><a ui-sref=".overview">Overview</a></li>
+      <li ui-sref-active="active"><a ui-sref=".history">History</a></li>
+      <li ui-sref-active="active"><a ui-sref=".summary">Summary</a></li>
+      <li ui-sref-active="active"><a ui-sref=".config">Configuration</a></li>
+      <li ng-if="checkpointDetails.id != -1" class="active"><a>Details for Checkpoint {{ checkpointDetails.id }}</a></li>
+    </ul>
+  </nav>
+  <div id="checkpoints-view" ui-view="checkpoints-view" class="clean checkpoints-view"></div>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoint-history.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoint-history.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoint-history.html
new file mode 100644
index 0000000..aa1cc2e
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoint-history.html
@@ -0,0 +1,57 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-if="checkpointStats">
+  <h3>History</h3>
+</div>
+<!--  h3 History-->
+<!--  table.table.table-body-hover.table-clickable-->
+<!--    thead-->
+<!--      tr-->
+<!--        td #[strong ID]-->
+<!--        td #[strong Status]-->
+<!--        td #[strong Acknowledged]-->
+<!--        td #[strong Trigger Time]-->
+<!--        td #[strong Latest Ack]-->
+<!--        td #[strong Duration]-->
+<!--        td #[strong State Size]-->
+<!--        td-->
+<!--    tbody(ng-if="checkpointStats['checkpoints'] && checkpointStats['checkpoints'].length > 0")-->
+<!--      tr(ng-repeat="checkpoint in checkpointStats['checkpoints']" ng-class="{'bg-warning': checkpoint['status'] == 'FAILED'}")-->
+<!--        td {{ checkpoint['id'] }}-->
+<!--        td(ng-if="checkpoint['status'] == 'IN_PROGRESS'") #[i(aria-hidden="true").fa.fa-circle-o-notch.fa-spin.fa-fw] In Progress-->
+<!--        td(ng-if="checkpoint['status'] == 'COMPLETED'") #[i(aria-hidden="true").fa.fa-check]-->
+<!--        td(ng-if="checkpoint['status'] == 'FAILED'") #[i(aria-hidden="true").fa.fa-remove] Failed-->
+<!--        td {{ checkpoint['subtasks']['acknowledged'] }}/{{ checkpoint['subtasks']['count'] }}-->
+<!--          = ' '-->
+<!--          span(ng-if="checkpoint['status'] == 'IN_PROGRESS'") ({{ checkpoint['subtasks']['acknowledged']/checkpoint['subtasks']['count'] | percentage }})-->
+<!--        td {{ checkpoint['trigger_timestamp'] | amDateFormat:'H:mm:ss' }}-->
+<!--        td {{ checkpoint['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}-->
+<!--        td {{ checkpoint['duration'] | humanizeDuration }}-->
+<!--        td {{ checkpoint['size'] | humanizeBytes }}-->
+<!--        td-->
+<!--          //a.btn.btn-default(ng-click="toggleCheckpointDetails(checkpoint['id'])")-->
+<!--          a.btn.btn-default(ui-sref="^.details({checkpointId: checkpoint['id']})")-->
+<!--            i(aria-hidden="true").fa.fa-chevron-right-->
+<!--            = ' '-->
+<!--            | <strong>More details</strong>-->
+<!--    tbody(ng-if="!checkpointStats['checkpoints'] || checkpointStats['checkpoints'].length == 0")-->
+<!--      tr-->
+<!--        td(colspan=5) No checkpoints triggered-->
+<!---->
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.config.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.config.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.config.html
new file mode 100644
index 0000000..9ef20a6
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.config.html
@@ -0,0 +1,59 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-if="checkpointConfig">
+  <table class="table">
+    <thead>
+      <tr>
+        <td><strong>Option</strong></td>
+        <td><strong>Value</strong></td>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Checkpointing Mode</td>
+        <td ng-if="checkpointConfig['mode'] == 'exactly_once'">Exactly Once</td>
+        <td ng-if="checkpointConfig['mode'] != 'exactly_once'">At Least Once</td>
+      </tr>
+      <tr>
+        <td>Interval</td>
+        <td ng-if="checkpointConfig['interval'] == '0x7fffffffffffffff'">Periodic checkpoints disabled</td>
+        <td ng-if="checkpointConfig['interval'] != '0x7fffffffffffffff'">{{ checkpointConfig['interval'] | humanizeDuration }}</td>
+      </tr>
+      <tr>
+        <td>Timeout</td>
+        <td>{{ checkpointConfig['timeout'] | humanizeDuration }}</td>
+      </tr>
+      <tr>
+        <td>Minimum Pause Between Checkpoints</td>
+        <td>{{ checkpointConfig['min_pause'] | humanizeDuration }}</td>
+      </tr>
+      <tr>
+        <td>Maximum Concurrent Checkpoints</td>
+        <td>{{ checkpointConfig['max_concurrent'] }}</td>
+      </tr>
+      <tr>
+        <td>Persist Checkpoints Externally</td>
+        <td ng-if="checkpointConfig['externalization']['enabled']">Enabled <span ng-if="checkpointConfig['externalization']['delete_on_cancellation']">(delete on cancellation)</span><span ng-if="!checkpointConfig['externalization']['delete_on_cancellation']">(retain on cancellation)</span>
+        </td>
+        <td ng-if="!checkpointConfig['externalization']['enabled']">Disabled</td>
+      </tr>
+    </tbody>
+  </table>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.counts.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.counts.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.counts.html
new file mode 100644
index 0000000..3b09269
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.counts.html
@@ -0,0 +1,51 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-if="checkpointStats">
+  <table class="table table-responsive">
+    <thead>
+      <tr>
+        <td width="30%"><strong>Checkpoint Event</strong></td>
+        <td width="70%"><strong>Count</strong></td>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Triggered</td>
+        <td>{{ checkpointStats['counts']['total'] }}</td>
+      </tr>
+      <tr>
+        <td>In Progress</td>
+        <td>{{ checkpointStats['counts']['in_progress'] }}</td>
+      </tr>
+      <tr>
+        <td>Completed</td>
+        <td>{{ checkpointStats['counts']['completed'] }}</td>
+      </tr>
+      <tr>
+        <td>Failed</td>
+        <td>{{ checkpointStats['counts']['failed'] }}</td>
+      </tr>
+      <tr>
+        <td>Restored</td>
+        <td>{{ checkpointStats['counts']['restored'] }}</td>
+      </tr>
+    </tbody>
+  </table>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.details.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.details.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.details.html
new file mode 100644
index 0000000..d7a3e54
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.details.html
@@ -0,0 +1,171 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-if="checkpoint">
+  <table class="table table-inner">
+    <thead>
+      <tr>
+        <td><strong>ID</strong></td>
+        <td><strong>Status</strong></td>
+        <td><strong>Acknowledged</strong></td>
+        <td><strong>Trigger Time</strong></td>
+        <td><strong>Latest Acknowledgement</strong></td>
+        <td ng-if="checkpoint['failure_timestamp']"><strong>Failure Time</strong></td>
+        <td><strong>End to End Duration</strong></td>
+        <td><strong>State Size</strong></td>
+        <td><strong>Buffered During Alignment</strong></td>
+        <td ng-if="checkpoint['status'] == 'COMPLETED'"><strong>Discarded</strong></td>
+        <td ng-if="checkpoint['external_path']"><strong>Path</strong></td>
+        <td ng-if="checkpoint['failure_message']"><strong>Failure Message</strong></td>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>{{ checkpoint['id'] }}</td>
+        <td ng-if="checkpoint['status'] == 'IN_PROGRESS'"><i aria-hidden="true" class="fa fa-circle-o-notch fa-spin fa-fw"></i> In progress <i ng-if="checkpoint['is_savepoint']">savepoint</i></td>
+        <td ng-if="checkpoint['status'] == 'COMPLETED'"><i aria-hidden="true" class="fa fa-check"></i> Completed <i ng-if="checkpoint['is_savepoint']">savepoint</i></td>
+        <td ng-if="checkpoint['status'] == 'FAILED'"><i aria-hidden="true" class="fa fa-remove"></i> Failed <i ng-if="checkpoint['is_savepoint']">savepoint</i></td>
+        <td>{{ checkpoint['num_acknowledged_subtasks'] }}/{{ checkpoint['num_subtasks'] }} ({{ checkpoint['num_acknowledged_subtasks']/checkpoint['num_subtasks'] | percentage }})</td>
+        <td>{{ checkpoint['trigger_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+        <td ng-if="checkpoint['latest_ack_timestamp'] &gt;= 0">{{ checkpoint['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+        <td ng-if="checkpoint['latest_ack_timestamp'] &lt; 0">n/a</td>
+        <td ng-if="checkpoint['failure_timestamp']">{{ checkpoint['failure_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+        <td ng-if="checkpoint['end_to_end_duration'] &gt;= 0">{{ checkpoint['end_to_end_duration'] | humanizeDuration }}</td>
+        <td ng-if="heckpoint['end_to_end_duration'] &lt; 0">n/a</td>
+        <td>{{ checkpoint['state_size'] | humanizeBytes }}</td>
+        <td> {{ checkpoint['alignment_buffered'] | humanizeBytes }}</td>
+        <td ng-if="checkpoint['status'] == 'COMPLETED'"><span ng-if="checkpoint['discarded']">Yes</span><span ng-if="!checkpoint['discarded']">No</span></td>
+        <td ng-if="checkpoint['external_path']">{{ checkpoint['external_path'] }}</td>
+        <td ng-if="checkpoint['status'] == 'FAILED' &amp;&amp; checkpoint['failure_message']">{{ checkpoint['failure_message'] }}</td>
+        <td ng-if="checkpoint['status'] == 'FAILED' &amp;&amp; !checkpoint['failure_message']">n/a</td>
+      </tr>
+    </tbody>
+  </table>
+  <h4>Operators</h4>
+  <table class="table table-body-hover table-clickable table-activable subtask-details">
+    <thead>
+      <tr>
+        <td><strong>Name</strong></td>
+        <td><strong>Acknowleged</strong></td>
+        <td><strong>Latest Acknowledgment</strong></td>
+        <td><strong>End to End Duration</strong></td>
+        <td><strong>State Size</strong></td>
+        <td><strong>Buffered During Alignment</strong></td>
+        <td></td>
+      </tr>
+    </thead>
+    <tbody ng-repeat="v in job.vertices" ng-class="{ active: v.id == nodeid }" ng-click="changeNode(v.id)">
+      <tr ng-if="v.type == 'regular'">
+        <td>{{ v.name | humanizeText }}</td>
+        <td>{{ checkpoint['tasks'][v.id]['num_acknowledged_subtasks'] }}/{{ checkpoint['tasks'][v.id]['num_subtasks'] }} ({{ checkpoint['tasks'][v.id]['num_acknowledged_subtasks']/checkpoint['tasks'][v.id]['num_subtasks'] | percentage }})</td>
+        <td ng-if="checkpoint['tasks'][v.id]['latest_ack_timestamp'] &gt;= 0">{{ checkpoint['tasks'][v.id]['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+        <td ng-if="checkpoint['tasks'][v.id]['latest_ack_timestamp'] &lt; 0">n/a</td>
+        <td ng-if="checkpoint['tasks'][v.id]['end_to_end_duration'] &gt;= 0">{{ checkpoint['tasks'][v.id]['end_to_end_duration'] | humanizeDuration }}</td>
+        <td ng-if="checkpoint['tasks'][v.id]['end_to_end_duration'] &lt; 0">n/a</td>
+        <td>{{ checkpoint['tasks'][v.id]['state_size'] | humanizeBytes }}</td>
+        <td>{{ checkpoint['tasks'][v.id]['alignment_buffered'] | humanizeBytes }}</td>
+        <td>
+          <div ng-if="!nodeid || v.id != nodeid"><a ng-click="toggleFold()" class="btn btn-default">Show Subtasks <i class="fa fa-chevron-down"></i></a></div>
+          <div ng-if="nodeid &amp;&amp; v.id == nodeid"><a ng-click="toggleFold()" class="btn btn-default">Hide Subtasks <i class="fa fa-chevron-up"></i></a></div>
+        </td>
+      </tr>
+      <tr ng-if="nodeid &amp;&amp; v.id == nodeid">
+        <td colspan="7">
+          <table class="table table-body-hover table-inner subtask-details">
+            <thead ng-if="subtaskDetails[v.id]['summary']">
+              <tr>
+                <td></td>
+                <td></td>
+                <td><strong>End to End Duration</strong></td>
+                <td><strong>State Size</strong></td>
+                <td><strong>Checkpoint Duration (Sync)</strong></td>
+                <td><strong>Checkpoint Duration (Async)</strong></td>
+                <td><strong>Alignment Buffered</strong></td>
+                <td><strong>Alignment Duration</strong></td>
+              </tr>
+              <tr>
+                <td></td>
+                <td><strong>Minimum</strong></td>
+                <td>{{ subtaskDetails[v.id]['summary']['end_to_end_duration']['min'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['state_size']['min'] | humanizeBytes }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['sync']['min'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['async']['min'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['alignment']['buffered']['min'] | humanizeBytes }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['alignment']['duration']['min'] | humanizeDuration }}</td>
+              </tr>
+              <tr>
+                <td></td>
+                <td><strong>Average</strong></td>
+                <td>{{ subtaskDetails[v.id]['summary']['end_to_end_duration']['avg'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['state_size']['avg'] | humanizeBytes }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['sync']['avg'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['async']['avg'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['alignment']['buffered']['avg'] | humanizeBytes }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['alignment']['duration']['avg'] | humanizeDuration }}</td>
+              </tr>
+              <tr>
+                <td></td>
+                <td><strong>Maximum</strong></td>
+                <td>{{ subtaskDetails[v.id]['summary']['end_to_end_duration']['max'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['state_size']['max'] | humanizeBytes }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['sync']['max'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['async']['max'] | humanizeDuration }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['alignment']['buffered']['max'] | humanizeBytes }}</td>
+                <td>{{ subtaskDetails[v.id]['summary']['alignment']['duration']['max'] | humanizeDuration }}</td>
+              </tr>
+              <tr class="blank">
+                <td colspan="8"></td>
+              </tr>
+            </thead>
+            <thead>
+              <tr>
+                <td><strong>Subtask #</strong></td>
+                <td><strong>Acknowledgement Time</strong></td>
+                <td><strong>End to End Duration</strong></td>
+                <td><strong>State Size</strong></td>
+                <td><strong>Checkpoint Duration (Sync)</strong></td>
+                <td><strong>Checkpoint Duration (Async)</strong></td>
+                <td><strong>Alignment Buffered</strong></td>
+                <td><strong>Alignment Duration</strong></td>
+              </tr>
+            </thead>
+            <tbody>
+              <tr ng-repeat="subtask in subtaskDetails[v.id]['subtasks']">
+                <td>{{ subtask['index'] + 1 }}</td>
+                <td ng-if-start="subtask['status'] == 'completed'">{{ subtask['ack_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+                <td>{{ subtask['end_to_end_duration'] | humanizeDuration }}</td>
+                <td>{{ subtask['state_size'] | humanizeBytes }}</td>
+                <td>{{ subtask['checkpoint']['sync'] | humanizeDuration }}</td>
+                <td>{{ subtask['checkpoint']['async'] | humanizeDuration }}</td>
+                <td>{{ subtask['alignment']['buffered'] | humanizeBytes}}</td>
+                <td ng-if-end="ng-if-end">{{ subtask['alignment']['duration'] | humanizeDuration }}</td>
+                <td ng-if="subtask['status'] == 'pending'" colspan="7">n/a</td>
+              </tr>
+            </tbody>
+          </table>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+<div ng-if="!checkpoint">
+  <p ng-if="unknown_checkpoint" role="alert" class="alert alert-danger"><strong>Unknown or expired checkpoint ID.</strong></p>
+  <p ng-if="!unknown_checkpoint" role="alert" class="alert alert-info"><strong>Waiting for response from JobManager with checkpoint details...</strong> <i aria-hidden="true" class="fa fa-circle-o-notch fa-spin fa-fw"></i>
+  </p>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.history.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.history.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.history.html
new file mode 100644
index 0000000..651d4f8
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.history.html
@@ -0,0 +1,65 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-if="checkpointStats['history'] &amp;&amp; checkpointStats['history'].length &gt; 0">
+  <table class="table">
+    <thead>
+      <tr>
+        <td><strong>ID</strong></td>
+        <td><strong>Status</strong></td>
+        <td><strong>Acknowledged</strong></td>
+        <td><strong>Trigger Time</strong></td>
+        <td><strong>Latest Acknowledgement</strong></td>
+        <td><strong>End to End Duration</strong></td>
+        <td><strong>State Size</strong></td>
+        <td><strong>Buffered During Alignment</strong></td>
+        <td></td>
+      </tr>
+    </thead>
+    <tbody>
+      <tr ng-repeat="checkpoint in checkpointStats['history']" ng-class="{'bg-danger': checkpoint['status'] == 'FAILED'}">
+        <td>{{ checkpoint['id'] }}</td>
+        <td ng-if="checkpoint['status'] == 'IN_PROGRESS'"><i aria-hidden="true" class="fa fa-circle-o-notch fa-spin fa-fw"></i> <i ng-if="checkpoint['is_savepoint']" aria-hidden="true" class="fa fa-floppy-o"></i></td>
+        <td ng-if="checkpoint['status'] == 'COMPLETED'"><i aria-hidden="true" class="fa fa-check"></i> <i ng-if="checkpoint['is_savepoint']" aria-hidden="true" class="fa fa-floppy-o"></i></td>
+        <td ng-if="checkpoint['status'] == 'FAILED'"><i aria-hidden="true" class="fa fa-remove"></i> <i ng-if="checkpoint['is_savepoint']" aria-hidden="true" class="fa fa-floppy-o"></i></td>
+        <td>{{ checkpoint['num_acknowledged_subtasks'] }}/{{ checkpoint['num_subtasks'] }} <span ng-if="checkpoint['status'] == 'IN_PROGRESS'">({{ checkpoint['num_acknowledged_subtasks']/checkpoint['num_subtasks'] | percentage }})</span>
+        </td>
+        <td>{{ checkpoint['trigger_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+        <td ng-if="checkpoint['latest_ack_timestamp'] &gt;= 0">{{ checkpoint['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+        <td ng-if="checkpoint['latest_ack_timestamp'] &lt; 0">n/a</td>
+        <td ng-if="checkpoint['end_to_end_duration'] &gt;= 0">{{ checkpoint['end_to_end_duration'] | humanizeDuration }}</td>
+        <td ng-if="checkpoint['end_to_end_duration'] &lt; 0">n/a</td>
+        <td>{{ checkpoint['state_size'] | humanizeBytes }}</td>
+        <td>{{ checkpoint['alignment_buffered'] | humanizeBytes }}</td>
+        <td><a ui-sref="^.details({checkpointId: checkpoint['id']})" class="btn btn-default"><i aria-hidden="true" class="fa fa-chevron-right"></i> <strong>More details</strong></a></td>
+      </tr>
+    </tbody>
+  </table>
+  <p><strong class="small">Status:</strong>
+    <ul class="small">
+      <li>In Progress: <i aria-hidden="true" class="fa fa-circle-o-notch fa-spin fa-fw"></i></li>
+      <li>Completed: <i aria-hidden="true" class="fa fa-check"></i></li>
+      <li>Failed: <i aria-hidden="true" class="fa fa-remove"></i></li>
+      <li>Savepoint: <i aria-hidden="true" class="fa fa-floppy-o"></i></li>
+    </ul>
+  </p>
+</div>
+<div ng-if="checkpointStats['history'] &amp;&amp; checkpointStats['history'].length == 0">
+  <p role="alert" class="alert alert-info"><strong>No checkpoint history available.</strong></p>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.html
new file mode 100644
index 0000000..2a3f1e1
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.html
@@ -0,0 +1,22 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-include="'partials/jobs/job.plan.node.checkpoints.overview.html'"></div>
+<div ng-include="'partials/jobs/job.plan.node.checkpoints.history.html'"></div>
+<div ng-include="'partials/jobs/job.plan.node.checkpoints.config.html'"></div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.job.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.job.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.job.html
index d21349c..2754e87 100644
--- a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.job.html
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.job.html
@@ -17,62 +17,88 @@ See the License for the specific language governing permissions and
 limitations under the License.
 
 -->
-<div ng-if="!jobCheckpointStats">
-  <p><em>No checkpoints</em></p>
+<div ng-if="jobCheckpointConfig">
+  <h3>Configuration</h3>
+  <table class="table">
+    <thead>
+      <tr>
+        <td><strong>Interval</strong></td>
+        <td><strong>Timeout</strong></td>
+        <td><strong>Minimum Pause between Checkpoints</strong></td>
+        <td><strong>Maximum Concurrent Checkpoints</strong></td>
+        <td><strong>Persist Checkpoints Externally</strong></td>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>{{ jobCheckpointConfig['interval'] | humanizeDuration }}</td>
+        <td>{{ jobCheckpointConfig['timeout'] | humanizeDuration }}</td>
+        <td>{{ jobCheckpointConfig['min_pause'] | humanizeDuration }}</td>
+        <td>{{ jobCheckpointConfig['max_concurrent'] }}</td>
+        <td ng-if="jobCheckpointConfig['externalization']['enabled']">Enabled <span ng-if="jobCheckpointConfig['externalization']['delete_on_cancellation']">(delete on cancellation)</span><span ng-if="!jobCheckpointConfig['externalization']['delete_on_cancellation']">(retain on cancellation)</span>
+        </td>
+        <td ng-if="!jobCheckpointConfig['externalization']['enabled']">Disabled</td>
+      </tr>
+    </tbody>
+  </table>
 </div>
-<table ng-if="jobCheckpointStats" class="table table-hover table-inner">
-  <tbody>
-    <tr>
-      <td><strong>Count</strong></td>
-      <td colspan="3"><span>{{ jobCheckpointStats['count'] }}</span></td>
-    </tr>
+<table ng-if="checkpointDetails == -1" class="table table-body-hover table-clickable">
+  <thead>
     <tr>
+      <td><strong>ID</strong></td>
+      <td><strong>Acknowledged</strong></td>
+      <td><strong>Trigger Time</strong></td>
+      <td><strong>Latest Ack</strong></td>
       <td><strong>Duration</strong></td>
-      <td>
-        <p><strong>Minimum:</strong><span> {{ jobCheckpointStats['duration']['min'] | humanizeDuration }}</span></p>
-      </td>
-      <td>
-        <p><strong>Maximum:</strong><span> {{ jobCheckpointStats['duration']['max'] | humanizeDuration }}</span></p>
-      </td>
-      <td>
-        <p><strong>Average:</strong><span> {{ jobCheckpointStats['duration']['avg'] | humanizeDuration }}</span></p>
-      </td>
-    </tr>
-    <tr>
       <td><strong>State Size</strong></td>
-      <td>
-        <p><strong>Minimum:</strong><span> {{ jobCheckpointStats['size']['min'] | humanizeBytes }}</span></p>
-      </td>
-      <td>
-        <p><strong>Maximum:</strong><span> {{ jobCheckpointStats['size']['max'] | humanizeBytes }}</span></p>
+      <td></td>
+    </tr>
+  </thead>
+  <!--ng-click="toggleCheckpointDetails(checkpoint['id'])"-->
+  <tbody ng-if="jobCheckpointStats['checkpoints'] &amp;&amp; jobCheckpointStats['checkpoints'].length &gt; 0">
+    <tr ng-repeat="checkpoint in jobCheckpointStats['checkpoints']" ng-class="{'bg-danger': checkpoint['status'] == 'FAILED'}">
+      <td><i ng-if="checkpoint['status'] == 'IN_PROGRESS'" aria-hidden="true" class="fa fa-circle-o-notch fa-spin fa-fw"></i><i ng-if="checkpoint['status'] == 'COMPLETED'" aria-hidden="true" class="fa fa-check"></i><i ng-if="checkpoint['status'] == 'FAILED'" aria-hidden="true" class="fa fa-remove"></i> {{ checkpoint['id'] }}
       </td>
+      <td>{{ checkpoint['subtasks']['acknowledged'] }}/{{ checkpoint['subtasks']['count'] }}</td>
+      <td>{{ checkpoint['trigger_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+      <td>{{ checkpoint['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}</td>
+      <td>{{ checkpoint['duration'] | humanizeDuration }}</td>
+      <td>{{ checkpoint['size'] | humanizeBytes }}</td>
       <td>
-        <p><strong>Average:</strong><span> {{ jobCheckpointStats['size']['avg'] | humanizeBytes }}</span></p>
-      </td>
-    </tr>
-    <tr ng-if="jobCheckpointStats['external-path']">
-      <td colspan="4"><strong>Latest Checkpoint Path:</strong> {{ jobCheckpointStats['external-path'] }}
+        <!--a.btn.btn-default(ng-click="toggleCheckpointDetails(checkpoint['id'])")--><a ui-sref="{checkpointid: checkpoint['id']}" class="btn btn-default"><strong>More details</strong> <i class="fa fa-chevron-down"></i></a>
       </td>
     </tr>
   </tbody>
 </table>
-<div ng-if="!showHistory &amp;&amp; jobCheckpointStats &amp;&amp; jobCheckpointStats['history'].length &gt; 0"><a ng-click="toggleHistory()" class="btn btn-default"><strong>Show history</strong> ({{ jobCheckpointStats['history'].length }}) <i class="fa fa-chevron-down"></i></a></div>
-<div ng-if="showHistory &amp;&amp; jobCheckpointStats &amp;&amp; jobCheckpointStats['history'].length &gt; 0"><a ng-click="toggleHistory()" class="btn btn-default">Hide history ({{ jobCheckpointStats['history'].length }}) <i class="fa fa-chevron-up"></i></a>
-  <table class="table table-hover table-inner">
+<div ng-if="checkpointDetails != -1"><a ng-click="toggleCheckpointDetails(-1)" class="btn btn-default"><strong>Back</strong> <i class="fa fa-chevron-left"></i></a>
+  <table class="table table-body-hover table-clickable table-activable">
     <thead>
       <tr>
-        <td><strong>ID</strong></td>
-        <td><strong>Trigger Time</strong></td>
-        <td><strong>Duration</strong></td>
-        <td><strong>State Size</strong></td>
+        <td rowspan="2">Name</td>
+        <td colspan="4">Size</td>
+        <td rowspan="2">Duration</td>
+        <td rowspan="2">Duration (Operator sync)</td>
+        <td rowspan="2">Status</td>
       </tr>
-    </thead>
-    <tbody ng-if="jobCheckpointStats['history'] &amp;&amp; jobCheckpointStats['history'].length &gt; 0" ng-repeat="historic in jobCheckpointStats['history']">
       <tr>
-        <td>{{ historic['id'] }}</td>
-        <td>{{ historic['timestamp'] | amDateFormat:'H:mm:ss' }}</td>
-        <td>{{ historic['duration'] | humanizeDuration }}</td>
-        <td>{{ historic['size'] | humanizeBytes }}</td>
+        <td>Min</td>
+        <td>Average</td>
+        <td>Max</td>
+        <td>Sum</td>
+      </tr>
+    </thead>
+    <tbody ng-repeat="v in job.vertices" ng-class="{ active: v.id == nodeid }" ng-click="v.id == nodeid || changeNode(v.id)">
+      <tr ng-if="v.type == 'regular'">
+        <td>{{ v.name | humanizeText }}</td>
+        <td>{{ operatorCheckpointStats[checkpoint['id']][v.id]['size']['min'] | humanizeBytes }}</td>
+        <td>{{ operatorCheckpointStats[checkpoint['id']][v.id]['size']['avg'] | humanizeBytes }}</td>
+        <td>{{ operatorCheckpointStats[checkpoint['id']][v.id]['size']['max'] | humanizeBytes }}</td>
+        <td>{{ operatorCheckpointStats[checkpoint['id']][v.id]['size']['sum'] | humanizeBytes }}</td>
+        <td>min: {{ operatorCheckpointStats[checkpoint['id']][v.id]['duration']['coordinator']['min'] | humanizeDuration }}, max: {{ operatorCheckpointStats[checkpoint['id']][v.id]['duration']['coordinator']['max'] | humanizeDuration }}, average: {{ operatorCheckpointStats[checkpoint['id']][v.id]['duration']['coordinator']['avg'] | humanizeDuration }}</td>
+        <td>min: {{ operatorCheckpointStats[checkpoint['id']][v.id]['duration']['operator']['sync']['min'] | humanizeDuration }}, max: {{ operatorCheckpointStats[checkpoint['id']][v.id]['duration']['operator']['sync']['max'] | humanizeDuration }}, average: {{ operatorCheckpointStats[checkpoint['id']][v.id]['duration']['operator']['sync']['avg'] | humanizeDuration }}</td>
+        <td>
+          <bs-label status="{{v.status}}">{{v.status}}</bs-label>
+        </td>
       </tr>
     </tbody>
   </table>

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.overview.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.overview.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.overview.html
new file mode 100644
index 0000000..e66d741
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.overview.html
@@ -0,0 +1,49 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-if="checkpointStats">
+  <table class="table checkpoint-overview">
+    <thead>
+      <tr>
+        <td><strong>Checkpoint Counts</strong></td>
+        <td>Triggered: {{ checkpointStats['counts']['total'] }}<span>In Progress: {{ checkpointStats['counts']['in_progress'] }}</span><span>Completed: {{ checkpointStats['counts']['completed'] }}</span><span>Failed: {{ checkpointStats['counts']['failed'] }}</span><span>Restored: {{ checkpointStats['counts']['restored'] }}</span></td>
+      </tr>
+      <tr>
+        <td><strong>Latest Completed Checkpoint</strong></td>
+        <td ng-if="checkpointStats['latest']['completed']">ID: {{ checkpointStats['latest']['completed']['id'] }}<span>Completion Time: {{ checkpointStats['latest']['completed']['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}</span><span>End to End Duration: {{ checkpointStats['latest']['completed']['end_to_end_duration'] | humanizeDuration }}</span><span>State Size: {{ checkpointStats['latest']['completed']['state_size'] | humanizeBytes }}</span><span><i aria-hidden="true" class="fa fa-caret-square-o-right"></i> <a ui-sref="^.details({checkpointId: checkpointStats['latest']['completed']['id']})">More details</a></span></td>
+        <td ng-if="!checkpointStats['latest']['completed']">None</td>
+      </tr>
+      <tr>
+        <td><strong>Latest Failed Checkpoint</strong></td>
+        <td ng-if="checkpointStats['latest']['failed']">ID: {{ checkpointStats['latest']['failed']['id'] }}<span>Failure Time: {{ checkpointStats['latest']['failed']['failure_timestamp'] | amDateFormat:'H:mm:ss' }}</span><span ng-if="checkpointStats['latest']['failed']['failure_message']">Cause: {{ checkpointStats['latest']['failed']['failure_message'] }}</span><span ng-if="!checkpointStats['latest']['failed']['failure_message']">Cause: n/a</span><span><i aria-hidden="true" class="fa fa-caret-square-o-right"></i> <a ui-sref="^.details({checkpointId: checkpointStats['latest']['failed']['id']})">More details</a></span></td>
+        <td ng-if="!checkpointStats['latest']['failed']">None</td>
+      </tr>
+      <tr>
+        <td><strong>Latest Savepoint</strong></td>
+        <td ng-if="checkpointStats['latest']['savepoint']">ID: {{ checkpointStats['latest']['savepoint']['id'] }}<span>Completion Time: {{ checkpointStats['latest']['savepoint']['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}</span><span>State Size: {{ checkpointStats['latest']['savepoint']['state_size'] | humanizeBytes }}</span><span>Path: {{ checkpointStats['latest']['savepoint']['external_path'] }}</span><span><i aria-hidden="true" class="fa fa-caret-square-o-right"></i> <a ui-sref="^.details({checkpointId: checkpointStats['latest']['savepoint']['id']})">More details</a></span></td>
+        <td ng-if="!checkpointStats['latest']['savepoint']">None</td>
+      </tr>
+      <tr>
+        <td><strong>Latest Restore</strong></td>
+        <td ng-if="checkpointStats['latest']['restored']">ID: {{ checkpointStats['latest']['restored']['id'] }}<span>Restore Time: {{ checkpointStats['latest']['restored']['restore_timestamp'] | amDateFormat:'H:mm:ss' }}</span><span ng-if="checkpointStats['latest']['restored']['is_savepoint']">Type: Savepoint</span><span ng-if="!checkpointStats['latest']['restored']['is_savepoint']">Type: Checkpoint</span><span ng-if="checkpointStats['latest']['restored']['external_path']">Path: {{ checkpointStats['latest']['restored']['external_path'] }}</span></td>
+        <td ng-if="!checkpointStats['latest']['restored']">None</td>
+      </tr>
+    </thead>
+  </table>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.statistics.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.statistics.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.statistics.html
new file mode 100644
index 0000000..17326e5
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.statistics.html
@@ -0,0 +1,56 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-if="checkpointStats">
+  <table class="table">
+    <thead>
+      <tr>
+        <td></td>
+        <td><strong>Minimum</strong></td>
+        <td><strong>Average</strong></td>
+        <td><strong>Maximum</strong></td>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td><strong>State Size</strong></td>
+        <td>{{ checkpointStats['summary']['state_size']['min'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['state_size']['avg'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['state_size']['max'] | humanizeBytes }}</td>
+      </tr>
+      <tr>
+        <td><strong>End to End Duration</strong></td>
+        <td>{{ checkpointStats['summary']['end_to_end_duration']['min'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['end_to_end_duration']['avg'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['end_to_end_duration']['max'] | humanizeBytes }}</td>
+      </tr>
+      <tr ng-if="isExactlyOnce">
+        <td><strong>Buffered during Alignment</strong></td>
+        <td>{{ checkpointStats['summary']['alignment_buffered']['min'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['alignment_buffered']['avg'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['alignment_buffered']['max'] | humanizeBytes }}</td>
+      </tr>
+      <tr ng-if="!isExactlyOnce">
+        <td><strong>Buffered during Alignment</strong></td>
+        <td colspan="3">No alignments with at-least-once checkpointing mode</td>
+      </tr>
+    </tbody>
+  </table>
+  <p>These number are computed over <i>all</i> completed checkpoints.</p>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flink/blob/536e4b35/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.summary.html
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.summary.html b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.summary.html
new file mode 100644
index 0000000..96f6d05
--- /dev/null
+++ b/flink-runtime-web/web-dashboard/web/partials/jobs/job.plan.node.checkpoints.summary.html
@@ -0,0 +1,53 @@
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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 License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<div ng-if="checkpointStats['summary']">
+  <table class="table">
+    <thead>
+      <tr>
+        <td></td>
+        <td><strong>State Size</strong></td>
+        <td><strong>End to End Duration</strong></td>
+        <td><strong>Buffered During Alignment</strong></td>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td><strong>Minimum</strong></td>
+        <td>{{ checkpointStats['summary']['end_to_end_duration']['min'] | humanizeDuration }}</td>
+        <td>{{ checkpointStats['summary']['state_size']['min'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['alignment_buffered']['min'] | humanizeBytes }}</td>
+      </tr>
+      <tr>
+        <td><strong>Average</strong></td>
+        <td>{{ checkpointStats['summary']['end_to_end_duration']['avg'] | humanizeDuration }}</td>
+        <td>{{ checkpointStats['summary']['state_size']['avg'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['alignment_buffered']['avg'] | humanizeBytes }}</td>
+      </tr>
+      <tr>
+        <td><strong>Maximum</strong></td>
+        <td>{{ checkpointStats['summary']['end_to_end_duration']['max'] | humanizeDuration }}</td>
+        <td>{{ checkpointStats['summary']['state_size']['max'] | humanizeBytes }}</td>
+        <td>{{ checkpointStats['summary']['alignment_buffered']['max'] | humanizeBytes }}</td>
+      </tr>
+    </tbody>
+  </table>
+  <p>These number are computed over <i>all</i> completed checkpoints.</p>
+</div>
+<p ng-if="!checkpointStats['summary']">No checkpoint statistics summary available.</p>
\ No newline at end of file


Mime
View raw message