You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@storm.apache.org by bo...@apache.org on 2018/08/03 20:45:51 UTC
[02/36] storm git commit: STORM-1311: UI Migration from clj to java
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/logviewer-search-page-template.html
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/logviewer-search-page-template.html b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/logviewer-search-page-template.html
new file mode 100644
index 0000000..e132936
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/logviewer-search-page-template.html
@@ -0,0 +1,45 @@
+<!--
+ 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.
+-->
+<script id="logviewer-search-result-template" type="text/html">
+{{#nextByteOffset}}
+<a href="/logviewer_search.html?file={{file}}&search={{searchString}}&offset={{nextByteOffset}}&is-daemon={{isDaemon}}" class="btn btn-default enabled">Next</a>
+{{/nextByteOffset}}
+<table id="search-result-table" class="table table-striped compact">
+ <thead><tr><th>File offset</th><th>Match</th></tr></thead>
+ <tbody>
+ {{#matches}}
+ <tr>
+ <td>{{byteOffset}}</td>
+ <td><pre>{{beforeString}}<b><a href="{{logviewerURL}}">{{matchString}}</a></b>{{afterString}}</pre></td>
+ </tr>
+ {{/matches}}
+ </tbody>
+</table>
+{{#nextByteOffset}}
+<a href="/logviewer_search.html?file={{file}}&search={{searchString}}&offset={{nextByteOffset}}&is-daemon={{isDaemon}}" class="btn btn-default enabled">Next</a>
+{{/nextByteOffset}}
+</script>
+<script id="search-single-file" type="text/html">
+<form action="logviewer_search.html" id="search-box">
+ Search {{file}}:
+ <input type="text" name="search" value="{{search}}">
+ <input type="hidden" name="file" value="{{file}}">
+ <input type="hidden" name="is-daemon" value="{{isDaemon}}">
+ <input type="submit" value="Search">
+</form>
+</script>
+
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/owner-page-template.html
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/owner-page-template.html b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/owner-page-template.html
new file mode 100644
index 0000000..f1320b6
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/owner-page-template.html
@@ -0,0 +1,239 @@
+<!--
+ 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.
+-->
+<script id="owner-summary-template" type="text/html">
+ <table id="owner-summary-table" class="table compact">
+ <thead>
+ <tr>
+ <th>
+ Owner
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="above" title="Total number of topologies owned by owner.">
+ Total Topologies
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="above" title="Total number of tasks used by owner.">
+ Total Tasks
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="above" title="Total number of executors used by owner.">
+ Total Executors
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="above" title="Total number of workers used by owner.">
+ Total Workers
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{owner}}</td>
+ <td>{{totalTopologies}}</td>
+ <td>{{totalTasks}}</td>
+ <td>{{totalExecutors}}</td>
+ <td>{{totalWorkers}}</td>
+ </tr>
+ </tbody>
+ </table>
+</script>
+
+<script id="owner-resource-usage-template" type="text/html">
+ <table id="owner-resource-usage-table" class="table compact">
+ <thead>
+ <tr>
+ <th>
+ </th>
+ <th>
+ On-Heap Mem (MB)
+ </th>
+ <th>
+ Off-Heap Mem (MB)
+ </th>
+ <th>
+ Total Mem (MB)
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Total CPU Resource. Every 100 means 1 core.">
+ Total CPU (%)
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Requested</td>
+ <td>{{totalReqOnHeapMem}}</td>
+ <td>{{totalReqOffHeapMem}}</td>
+ <td>{{totalReqMem}}</td>
+ <td>{{totalReqCpu}}</td>
+ </tr>
+ <tr>
+ <td>Assigned</td>
+ <td>{{totalAssignedOnHeapMem}}</td>
+ <td>{{totalAssignedOffHeapMem}}</td>
+ <td>{{totalMemoryUsage}}</td>
+ <td>{{totalCpuUsage}}</td>
+ </tr>
+ </tbody>
+ </table>
+</script>
+
+<script id="owner-resource-guarantee-template" type="text/html">
+ <table id="owner-resource-guarantee-table" class="table compact">
+ <thead>
+ <tr>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The amount of CPU resource (every 100 means 1 core) guaranteed to owner.">
+ CPU Guarantee (%)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The amount of CPU resource (every 100 means 1 core) used by owner.">
+ CPU Usage (%)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The amount of guaranteed CPU resource (every 100 means 1 core) remaining.">
+ CPU Guarantee Remaining (%)
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{cpuGuarantee}}</td>
+ <td>{{totalCpuUsage}}</td>
+ <td id="cpu-guarantee-util">{{cpuGuaranteeRemaining}}</td>
+ </tr>
+ </tbody>
+ <thead>
+ <tr>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The amount of memory resource (in MB) guaranteed to owner.">
+ Memory Guarantee (MB)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The amount of memory resource (in MB) used by owner.">
+ Memory Usage (MB)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The amount of guaranteed memory resources (in MB) remaining.">
+ Memory Guarantee Remaining (MB)
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{memoryGuarantee}}</td>
+ <td>{{totalMemoryUsage}}</td>
+ <td id="mem-guarantee-util">{{memoryGuaranteeRemaining}}</td>
+ </tr>
+ </tbody>
+ </table>
+</script>
+
+<script id="owner-topology-summary-template" type="text/html">
+ <table id="owner-topology-summary-table" class="table table-striped compact">
+ <thead>
+ <tr>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The name given to the topology by when it was submitted. Click the name to view the Topology's information.">
+ Name
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The owner that submitted the Topology, if authentication is enabled.">
+ Owner
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The status can be one of ACTIVE, INACTIVE, KILLED, or REBALANCING.">
+ Status
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The time since the Topology was submitted.">
+ Uptime
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The number of Workers (processes).">
+ Num workers
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Executors are threads in a Worker process.">
+ Num executors
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="A Task is an instance of a Bolt or Spout. The number of Tasks is almost always equal to the number of Executors.">
+ Num tasks
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Assigned Total Memory by Scheduler.">
+ Assigned Mem (MB)
+ </span>
+ </th>
+ {{#schedulerDisplayResource}}
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Assigned Total CPU by Scheduler. Every 100 means 1 core.">
+ Assigned CPU (%)
+ </span>
+ </th>
+ {{/schedulerDisplayResource}}
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="This shows information from the scheduler about the latest attempt to schedule the Topology on the cluster.">
+ Scheduler Info
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="The version of this topology">
+ Topology Version
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#topologies}}
+ <tr>
+ <td><a href="/topology.html?id={{encodedId}}">{{name}}</a></td>
+ <td><a href="/owner.html?id={{owner}}">{{owner}}</a></td>
+ <td>{{status}}</td>
+ <td>{{uptime}}</td>
+ <td>{{workersTotal}}</td>
+ <td>{{executorsTotal}}</td>
+ <td>{{tasksTotal}}</td>
+ <td>{{assignedTotalMem}}</td>
+ {{#schedulerDisplayResource}}
+ <td>{{assignedCpu}}</td>
+ {{/schedulerDisplayResource}}
+ <td>{{schedulerInfo}}</td>
+ <td>{{topologyVersion}}</td>
+ </tr>
+ {{/topologies}}
+ </tbody>
+ </table>
+</script>
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/search-result-page-template.html
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/search-result-page-template.html b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/search-result-page-template.html
new file mode 100644
index 0000000..4376408
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/search-result-page-template.html
@@ -0,0 +1,60 @@
+<!--
+ 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.
+-->
+<script id="search-result-files-template" type="text/html">
+<table id="search-result-table" class="table table-striped compact">
+ <thead><tr><th>host:port</th><th>Match</th></tr></thead>
+ <tbody>
+ {{#hostPortList}}
+ <tr id="{{elemId}}">
+ <td>{{host}}:{{port}}</td>
+ <td>LOADING ...</td>
+ </tr>
+ {{/hostPortList}}
+ </tbody>
+</table>
+</script>
+<script id="search-result-identified-template" type="text/html">
+ {{#matches}}
+ <tr>
+ <td><a href="{{logviewerScheme}}://{{host}}:{{logviewerPort}}/logviewer_search.html?file={{file}}&search={{searchString}}">{{host}}:{{port}}</a></td>
+ <td><pre>{{beforeString}}<b><a href="{{logviewerURL}}">{{matchString}}</a></b>{{afterString}}</pre></td>
+ </tr>
+ {{/matches}}
+</script>
+<script id="deepsearch-result-identified-template" type="text/html">
+ {{#matches}}
+ {{#matches}}
+ <tr>
+ <td><a href="{{logviewerScheme}}://{{host}}:{{logviewerPort}}/logviewer_search.html?file={{fileName}}&search={{searchString}}">{{host}}:{{port}}</a></td>
+ <td><pre>{{beforeString}}<b><a href="{{logviewerURL}}">{{matchString}}</a></b>{{afterString}}</pre></td>
+ </tr>
+ {{/matches}}
+ {{/matches}}
+</script>
+<script id="search-form-template" type="text/html">
+ <div class="search-box">
+ <form action="search_result.html" id="search-box">
+ Search {{id}}:
+ <input type="text" name="search" value="{{search}}">
+ <input type="hidden" name="id" value="{{id}}">
+ <input type="hidden" name="count" value="{{count}}">
+ <input type="submit" value="Search">
+ Search Archived Logs: <input type="checkbox" name="searchArchived" value="checked" {{searchArchived}}>
+ </form>
+ </div>
+</script>
+
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/supervisor-page-template.html
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/supervisor-page-template.html b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/supervisor-page-template.html
new file mode 100644
index 0000000..6fa79c6
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/supervisor-page-template.html
@@ -0,0 +1,161 @@
+<!--
+ 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.
+-->
+<script id="supervisor-summary-template" type="text/html">
+ <table class="table table-striped compact" id="supervisor-summary-table">
+ <thead>
+ <tr>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The hostname reported by the remote host. (Note that this hostname is not the result of a reverse lookup at the Nimbus node.)">
+ Host
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="A unique identifier given to a Supervisor when it joins the cluster.">
+ Supervisor Id
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The length of time a Supervisor has been registered to the cluster.">
+ Uptime
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Slots are Workers (processes).">
+ Slots
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Slots are Workers (processes).">
+ Used slots
+ </span>
+ </th>
+ {{#schedulerDisplayResource}}
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Memory capacity of a supervisor.">
+ Total Mem (MB)
+ </span>
+ </th>
+ {{/schedulerDisplayResource}}
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Memory that has been allocated.">
+ Used Mem (MB)
+ </span>
+ </th>
+ {{#schedulerDisplayResource}}
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="The amount of Memory available in megabytes.">
+ Avail Mem (MB)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="CPU capacity of a supervisor. Every 100 means one core.">
+ Total CPU (%)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="CPU that has been allocated. Every 100 means one core">
+ Used CPU (%)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="The amount of CPU that is available. Every 100 means one core.">
+ Avail CPU (%)
+ </span>
+ </th>
+ {{/schedulerDisplayResource}}
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Version">
+ Version
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#supervisors}}
+ <tr>
+ <td><a href="/supervisor.html?host={{host}}">{{host}} (<a href="{{logLink}}" title="View log">log</a>)</a></td>
+ <td><a href="/supervisor.html?id={{id}}">{{id}}</td>
+ <td>{{uptime}}</td>
+ <td>{{slotsTotal}}</td>
+ <td>{{slotsUsed}}</td>
+ {{#schedulerDisplayResource}}
+ <td>{{totalMem}}</td>
+ {{/schedulerDisplayResource}}
+ <td>{{usedMem}}</td>
+ {{#schedulerDisplayResource}}
+ <td>{{availMem}}</td>
+ <td>{{totalCpu}}</td>
+ <td>{{usedCpu}}</td>
+ <td>{{availCpu}}</td>
+ {{/schedulerDisplayResource}}
+ <td>{{version}}</td>
+ </tr>
+ {{/supervisors}}
+ </tbody>
+ </table>
+</script>
+<script id="worker-stats-template" type="text/html">
+ <table class="table table-striped compact" id="worker-stats-table">
+ <thead>
+ <tr>
+ <th class="header headerSortDown">
+ <span data-toggle="tooltip" data-placement="top" title="The name given to the topology by when it was submitted. Click the name to view the Topology's information.">
+ Topology Name
+ </span>
+ </th>
+ <th class="header">
+ <span data-original-title="The hostname reported by the remote host. (Note that this hostname is not the result of a reverse lookup at the Nimbus node.)" data-toggle="tooltip" data-placement="top">
+ Host
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="The port number used by the Worker. Click on the port number to open the logviewer page for this Worker.">
+ Port
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="The length of time a Worker has been alive.">
+ Uptime
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="The number of executors.">
+ Num executors
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="Assigned Total Memory by Scheduler.">
+ Assigned Mem (MB)
+ </span>
+ </th>
+ {{#schedulerDisplayResource}}
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="Assigned Total CPU by Scheduler. Every 100 means 1 core.">
+ Assigned CPU (%)
+ </span>
+ </th>
+ {{/schedulerDisplayResource}}
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="The components running in this worker and the number of tasks per component.">
+ Components
+ </span>
+ </th>
+ </tr></thead>
+ <tbody>
+ </tbody>
+ </table>
+</script>
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/topology-page-template.html
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/topology-page-template.html b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/topology-page-template.html
new file mode 100644
index 0000000..49cb314
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/topology-page-template.html
@@ -0,0 +1,700 @@
+<!--
+ 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.
+-->
+<script id="topology-summary-template" type="text/html">
+ <table id="topology-summary-table" class="table compact">
+ <thead>
+ <tr>
+ <th>
+ <span data-toggle="tooltip" data-placement="right" title="The name given to the topology by when it was submitted.">
+ Name
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="right" title="The unique ID given to a Topology each time it is launched.">
+ Id
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The user that submitted the Topology, if authentication is enabled.">
+ Owner
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The status can be one of ACTIVE, INACTIVE, KILLED, or REBALANCING.">
+ Status
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The time since the Topology was submitted.">
+ Uptime
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The number of Workers (processes).">
+ Num workers
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Executors are threads in a Worker process.">
+ Num executors
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="A Task is an instance of a Bolt or Spout. The number of Tasks is almost always equal to the number of Executors.">
+ Num tasks
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Number of nimbus hosts on which this topology's code is replicated. ">
+ Replication count
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Assigned Total Memory by Scheduler.">
+ Assigned Mem (MB)
+ </span>
+ </th>
+ {{#schedulerDisplayResource}}
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Assigned Total CPU by Scheduler. Every 100 means 1 core.">
+ Assigned CPU (%)
+ </span>
+ </th>
+ {{/schedulerDisplayResource}}
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="This shows information from the scheduler about the latest attempt to schedule the Topology on the cluster.">
+ Scheduler Info
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="The version of this topology">
+ Topology Version
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="The version of the storm client that this topology request (was launched with)">
+ Storm Version
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{name}}</td>
+ <td>{{id}}</td>
+ <td><a href="/owner.html?id={{owner}}">{{owner}}</a></td>
+ <td>{{status}}</td>
+ <td>{{uptime}}</td>
+ <td>{{workersTotal}}</td>
+ <td>{{executorsTotal}}</td>
+ <td>{{tasksTotal}}</td>
+ <td>{{replicationCount}}</td>
+ <td>{{assignedTotalMem}}</td>
+ {{#schedulerDisplayResource}}
+ <td>{{assignedCpu}}</td>
+ {{/schedulerDisplayResource}}
+ <td>{{schedulerInfo}}</td>
+ <td>{{topologyVersion}}</td>
+ <td>{{stormVersion}}</td>
+ </tr>
+ </tbody>
+ </table>
+</script>
+<script id="topology-resources-template" type="text/html">
+ <table id="topology-resources-table" class="table compact">
+ <thead>
+ <tr>
+ <th>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="On-Heap memory that is not shared between executors">
+ Not Shared On-Heap Mem (MB)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="On-Heap memory that is shared between executors">
+ Shared On-Heap Mem (MB)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Off-Heap memory that is not shared between executors">
+ Not Shared Off-Heap Mem (MB)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Off-Heap memory that is shared between executors, either within a worker or between workers on a node">
+ Shared Off-Heap Mem (MB)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Total memory MB. For requested only one copy of each shared region is included so assigned may be more than requested.">
+ Total Mem (MB)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Total CPU Resource. Every 100 means 1 core.">
+ Total CPU (%)
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Requested</td>
+ <td>{{requestedRegularOnHeapMem}}</td>
+ <td>{{requestedSharedOnHeapMem}}</td>
+ <td>{{requestedRegularOffHeapMem}}</td>
+ <td>{{requestedSharedOffHeapMem}}</td>
+ <td>{{requestedTotalMem}}</td>
+ <td>{{requestedCpu}}</td>
+ </tr>
+ <tr>
+ <td>Assigned</td>
+ <td>{{assignedRegularOnHeapMem}}</td>
+ <td>{{assignedSharedOnHeapMem}}</td>
+ <td>{{assignedRegularOffHeapMem}}</td>
+ <td>{{assignedSharedOffHeapMem}}</td>
+ <td>{{assignedTotalMem}}</td>
+ <td>{{assignedCpu}}</td>
+ </tr>
+ </tbody>
+ </table>
+</script>
+<script id="topology-stats-template" type="text/html">
+ <h2>Topology stats</h2>
+ <table class="table table-striped compact" id="topology-stats-table">
+ <thead>
+ <tr>
+ <th>
+ <span data-toggle="tooltip" data-placement="right" title="The past period of time for which the statistics apply. Click on a value to set the window for this page.">
+ Window
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuples emitted.">
+ Emitted
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuples emitted that sent to one or more bolts.">
+ Transferred
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The average time a Tuple "tree" takes to be completely processed by the Topology. A value of 0 is expected if no acking is done.">
+ Complete latency (ms)
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuple "trees" successfully processed. A value of 0 is expected if no acking is done.">
+ Acked
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="The number of Tuple "trees" that were explicitly failed or timed out before acking was completed. A value of 0 is expected if no acking is done.">
+ Failed
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#topologyStats}}
+ <tr>
+ <td><a href="/topology.html?id={{encodedId}}&window={{window}}">{{windowPretty}}</td>
+ <td>{{emitted}}</td>
+ <td>{{transferred}}</td>
+ <td>{{completeLatency}}</td>
+ <td>{{acked}}</td>
+ <td>{{failed}}</td>
+ </tr>
+ {{/topologyStats}}
+ </tbody>
+ </table>
+</script>
+
+<script id="topology-kafka-spouts-lag-template" type="text/html">
+ <h2>Kafka Spouts Lag</h2>
+ <table class="table table-striped compact" id="topology-kafka-spouts-lag-table">
+ <thead>
+ <tr>
+ <th>
+ <span data-toggle="tooltip" data-placement="right" title="Kafka spout id">
+ Id
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Topic">
+ Topic
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Partition">
+ Partition
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Latest Offset">
+ Latest Offset
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Offset of last spout message successfully acked">
+ Spout Committed Offset
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="Lag">
+ Lag
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#kafkaSpoutsLagResults}}
+ <tr>
+ <td>{{id}}</td>
+ <td>{{topic}}</td>
+ <td>{{partition}}</td>
+ <td>{{logHeadOffset}}</td>
+ <td>{{consumerCommittedOffset}}</td>
+ <td>{{lag}}</td>
+ </tr>
+ {{/kafkaSpoutsLagResults}}
+ </tbody>
+ </table>
+</script>
+
+<script id="topology-spouts-lag-error-template" type="text/html">
+ <h2>Topology spouts lag error</h2>
+ <table class="table table-striped compact" id="topology-spouts-lag-error-table">
+ <thead>
+ <tr>
+ <th>
+ <span data-toggle="tooltip" data-placement="right" title="Spout id">
+ Id
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="top" title="Type of spout">
+ Type
+ </span>
+ </th>
+ <th>
+ <span data-toggle="tooltip" data-placement="left" title="Message to denote the reason for failure to get the lag">
+ Message
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#spoutsLagErrorResults}}
+ <tr>
+ <td>{{spoutId}}</td>
+ <td>{{spoutType}}</td>
+ <td>{{errorInfo}}</td>
+ </tr>
+ {{/spoutsLagErrorResults}}
+ </tbody>
+ </table>
+</script>
+
+<script id="topology-visualization-container-template" type="text/html">
+<iframe src="/visualize.html?id={{id}}&sys={{sys}}" width="100%" height="500px"></iframe>
+</script>
+
+<script id="topology-visualization-template" type="text/html">
+ <h2>Topology Visualization</h2>
+ <input type="button" id="show-hide-visualization" value="Show Visualization" class="btn btn-default"/>
+ <input type="button" id="open-visualization" value="Open Visualization" class="btn btn-default"/>
+ <p>
+ <div id="visualization-container" style="display:none;">
+ </div>
+ </p>
+</script>
+
+<script id="topology-configuration-template" type="text/html">
+ <h2>Topology Configuration</h2>
+ <table class="table table-striped compact" id="topology-configuration-table"><thead><tr><th>Key</th><th>Value</th></tr></thead>
+ <tbody>
+ {{#config}}
+ <tr>
+ <td>{{key}}</td>
+ <td>{{value}}</td>
+ </tr>
+ {{/config}}
+ </tbody>
+ </table>
+</script>
+<script id="spout-stats-template" type="text/html">
+ <h2>Spouts ({{windowHint}})</h2>
+ <table class="table table-striped compact" id="spout-stats-table">
+ <thead>
+ <tr>
+ <th class="header headerSortDown">
+ <span data-original-title="The ID assigned to a the Component by the Topology. Click on the name to view the Component's page." data-toggle="tooltip" data-placement="right">
+ Id
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-original-title="Executors are threads in a Worker process." data-toggle="tooltip" data-placement="right">
+ Executors
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="A Task is an instance of a Bolt or Spout. The number of Tasks is almost always equal to the number of Executors.">
+ Tasks
+ </span>
+ </th>
+ {{#schedulerDisplayResource}}
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The amount of on-heap memory in megabytes requested to run a single executor of this component.">
+ Req On-heap Mem (MB)
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The amount of off-heap memory in megabytes requested to run a single executor of this component.">
+ Req Off-heap Mem (MB)
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The amount of CPU resources requested to run a single executor of this component. Every 100 means 1 core.">
+ Req CPU
+ </span>
+ </th>
+ {{/schedulerDisplayResource}}
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuples emitted.">
+ Emitted
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuples emitted that sent to one or more bolts.">
+ Transferred
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The average time a Tuple "tree" takes to be completely processed by the Topology. A value of 0 is expected if no acking is done.">
+ Complete latency (ms)
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuple "trees" successfully processed. A value of 0 is expected if no acking is done.">
+ Acked
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuple "trees" that were explicitly failed or timed out before acking was completed. A value of 0 is expected if no acking is done.">
+ Failed
+ </span>
+ </th>
+ <th class="header">Error Host</th>
+ <th class="header">Error Port</th>
+ <th class="header">Last error</th>
+ <th class="header">Error Time</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#spouts}}
+ <tr>
+ <td><a href="/component.html?id={{encodedSpoutId}}&topology_id={{encodedId}}">{{spoutId}}</a></td>
+ <td>{{executors}}</td>
+ <td>{{tasks}}</td>
+ {{#schedulerDisplayResource}}
+ <td>{{requestedMemOnHeap}}</td>
+ <td>{{requestedMemOffHeap}}</td>
+ <td>{{requestedCpu}}</td>
+ {{/schedulerDisplayResource}}
+ <td>{{emitted}}</td>
+ <td>{{transferred}}</td>
+ <td>{{completeLatency}}</td>
+ <td>{{acked}}</td>
+ <td>{{failed}}</td>
+ <td>{{errorHost}}</td>
+ <td><a href="{{errorWorkerLogLink}}">{{errorPort}}</a></td>
+ <td>
+ <span id="{{errorLapsedSecs}}" class="errorSpan">{{lastError}}</span>
+ </td>
+ <td>
+ {{#errorTime}}
+ <span id="{{errorTime}}" class="errorTime" data-toggle="tooltip" title="{{errorLapsedSecs}}">{{errorTime}}</span>
+ {{/errorTime}}
+ </td>
+ {{/spouts}}
+ </tbody>
+ </table>
+</script>
+<script id="bolt-stats-template" type="text/html">
+ <h2>Bolts ({{windowHint}})</h2>
+ <table class="table table-striped compact" id="bolt-stats-table"><thead>
+ <tr>
+ <th class="header headerSortDown">
+ <span data-toggle="tooltip" data-placement="right" title="The ID assigned to a the Component by the Topology. Click on the name to view the Component's page.">
+ Id
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-original-title="Executors are threads in a Worker process." data-toggle="tooltip" data-placement="right">
+ Executors
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="A Task is an instance of a Bolt or Spout. The number of Tasks is almost always equal to the number of Executors.">
+ Tasks
+ </span>
+ </th>
+ {{#schedulerDisplayResource}}
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The amount of on-heap memory in megabytes requested to run a single executor of this component.">
+ Req On-heap Mem (MB)
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The amount of off-heap memory in megabytes requested to run a single executor of this component.">
+ Req Off-heap Mem (MB)
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The amount of CPU resources requested to run a single executor of this component. Every 100 means 1 core.">
+ Req CPU
+ </span>
+ </th>
+ {{/schedulerDisplayResource}}
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuples emitted.">
+ Emitted
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuples emitted that sent to one or more bolts.">
+ Transferred
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-original-title="If this is around 1.0, the corresponding Bolt is running as fast as it can, so you may want to increase the Bolt's parallelism. This is (number executed * average execute latency) / measurement time." data-toggle="tooltip" data-placement="top">
+ Capacity (last 10m)
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The average time a Tuple spends in the execute method. The execute method may complete without sending an Ack for the tuple.">
+ Execute latency (ms)
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The number of incoming Tuples processed.">
+ Executed
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The average time it takes to Ack a Tuple after it is first received. Bolts that join, aggregate or batch may not Ack a tuple until a number of other Tuples have been received.">
+ Process latency (ms)
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="top" title="The number of Tuples acknowledged by this Bolt.">
+ Acked
+ </span>
+ </th>
+ <th class="header table-num">
+ <span data-toggle="tooltip" data-placement="left" title="The number of tuples Failed by this Bolt.">
+ Failed
+ </span>
+ </th>
+ <th class="header">Error Host</th>
+ <th class="header">Error Port</th>
+ <th class="header">Last error</th>
+ <th class="header">Error Time</th>
+ </tr></thead>
+ <tbody>
+ {{#bolts}}
+ <tr>
+ <td><a href="/component.html?id={{encodedBoltId}}&topology_id={{encodedId}}">{{boltId}}</a></td>
+ <td>{{executors}}</td>
+ <td>{{tasks}}</td>
+ {{#schedulerDisplayResource}}
+ <td>{{requestedMemOnHeap}}</td>
+ <td>{{requestedMemOffHeap}}</td>
+ <td>{{requestedCpu}}</td>
+ {{/schedulerDisplayResource}}
+ <td>{{emitted}}</td>
+ <td>{{transferred}}</td>
+ <td>{{capacity}}</td>
+ <td>{{executeLatency}}</td>
+ <td>{{executed}}</td>
+ <td>{{processLatency}}</td>
+ <td>{{acked}}</td>
+ <td>{{failed}}</td>
+ <td>{{errorHost}}</td>
+ <td><a href="{{errorWorkerLogLink}}">{{errorPort}}</a></td>
+ <td>
+ <span id="{{errorLapsedSecs}}" class="errorSpan">{{lastError}}</span>
+ </td>
+ <td>
+ {{#errorTime}}
+ <span id="{{errorTime}}" class="errorTime" data-toggle="tooltip" title="{{errorLapsedSecs}}">{{errorTime}}</span>
+ {{/errorTime}}
+ </td>
+ {{/bolts}}
+ </tbody>
+</script>
+<script id="worker-stats-template" type="text/html">
+ <h2>Worker Resources</h2>
+ <table class="table table-striped compact" id="worker-stats-table">
+ <thead>
+ <tr>
+ <th class="header headerSortDown">
+ <span data-original-title="The hostname reported by the remote host. (Note that this hostname is not the result of a reverse lookup at the Nimbus node.)" data-toggle="tooltip" data-placement="top">
+ Host
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="A unique identifier given to a Supervisor when it joins the cluster.">
+ Supervisor Id
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="The port number used by the Worker. Click on the port number to open the logviewer page for this Worker.">
+ Port
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="The length of time a Worker has been alive.">
+ Uptime
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="The number of executors">
+ Num executors
+ </span>
+ </th>
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="Assigned Total Memory by Scheduler.">
+ Assigned Mem (MB)
+ </span>
+ </th>
+ {{#schedulerDisplayResource}}
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="Assigned Total CPU by Scheduler. Every 100 means 1 core.">
+ Assigned CPU (%)
+ </span>
+ </th>
+ {{/schedulerDisplayResource}}
+ <th class="header">
+ <span data-toggle="tooltip" data-placement="top" title="The components running in this worker and the number of tasks per component.">
+ Components
+ </span>
+ </th>
+ </tr></thead>
+ <tbody>
+ </tbody>
+</script>
+<script id="topology-actions-template" type="text/html">
+ <h2>Topology actions</h2>
+ <p id="topology-actions">
+ <input {{activateStatus}} onclick="confirmAction('{{encodedId}}', '{{name}}', 'activate', false)" type="button" value="Activate" class="btn btn-default">
+ <input {{deactivateStatus}} onclick="confirmAction('{{encodedId}}', '{{name}}', 'deactivate', false)" type="button" value="Deactivate" class="btn btn-default">
+ <input {{rebalanceStatus}} onclick="confirmAction('{{encodedId}}', '{{name}}', 'rebalance', true, {{msgTimeout}}, 'wait time in seconds')" type="button" value="Rebalance" class="btn btn-default">
+ <input {{killStatus}} onclick="confirmAction('{{encodedId}}', '{{name}}', 'kill', true, 30, 'wait time in seconds')" type="button" value="Kill" class="btn btn-default">
+ {{#loggersDisabled}}
+ <span style="display:inline-block;" data-toggle="tooltip" title="" data-original-title="To debug, set topology.eventlogger.executors to a value > 0">
+ {{/loggersDisabled}}
+ <input {{startDebugStatus}} onclick="confirmAction('{{encodedId}}', '{{name}}', 'debug/enable', true, {{currentSamplingPct}}, 'sampling percentage', 'debug')" type="button" value="Debug" class="btn btn-default" >
+ {{#loggersDisabled}}
+ </span>
+ {{/loggersDisabled}}
+ <input {{stopDebugStatus}} onclick="confirmAction('{{encodedId}}', '{{name}}', 'debug/disable', false, 0, 'sampling percentage', 'stop debugging')" type="button" value="Stop Debug" class="btn btn-default">
+ <input type="button" {{logLevel}} value="Change Log Level" onclick="toggleChangeLogLevel()" class="btn btn-default">
+ </p>
+ <!--
+ Contents of topology-change-log-level-template will be added to the div below
+ once user clicks on "Change Log Level"
+ -->
+ <div id="change-log-level" style="display:none"></div>
+</script>
+
+<script id="search-form-template" type="text/html">
+ <form action="search_result.html" id="search-box">
+ Search {{id}}:
+ <input type="text" name="search">
+ <input type="hidden" name="id" value="{{id}}">
+ <input type="hidden" name="count" value="1">
+ <input type="submit" value="Search">
+ Search Archived Logs: <input type="checkbox" name="searchArchived" value="checked">
+ </form>
+</script>
+
+<script id="log-level-and-timeout" type="text/html" class="partials">
+ <tr id="logger-{{loggerId}}" class="{{cls}}">
+ {{#loggerName}}
+ <td>{{loggerName}}</td>
+ <input type="hidden" id="loggerName-{{loggerId}}" value="{{loggerName}}"/>
+ <input type="hidden" id="loggerRemove-{{loggerId}}" value="false"/>
+ {{/loggerName}}
+
+ {{#isNew}}
+ <td>
+ <input type="text" id="loggerName-{{loggerId}}" placeholder="com.your.organization.LoggerName"/>
+ </td>
+ {{/isNew}}
+
+ <td>
+ <select id="loggerLevel-{{loggerId}}">
+ {{#levels}}
+ <option value="{{name}}" {{levelSelected}}>{{name}}</option>
+ {{/levels}}
+ </select>
+ </td>
+ <td>
+ <input type="text" class="timeout_input" id="loggerTimeout-{{loggerId}}" placeholder="30" value="{{timeout}}"/>
+ </td>
+ <td>
+ {{absoluteTimeout}}
+ </td>
+ <td>
+ {{#isNew}}
+ <input type="button" value="Add" name="clear" onClick='sendLoggerLevel({{loggerId}})' class="btn btn-secondary"/>
+ {{/isNew}}
+ {{#loggerName}}
+ <input type="button" value="Apply" name="clear" onClick='sendLoggerLevel({{loggerId}})' class="btn btn-secondary"/>
+ {{#canClear}}
+ <input type="button" value="Clear" name="clear" onClick='clearLoggerLevel({{loggerId}})' class="btn btn-secondary"/>
+ {{/canClear}}
+ {{/loggerName}}
+ </td>
+ </tr>
+</script>
+
+<script id="topology-change-log-level-template" type="text/html">
+ <div id="change-log-level">
+ <h3>Change Log Level</h3>
+ Modify the logger levels for topology. Note that applying a setting restarts the timer in the workers. To configure the root logger, use the name ROOT.
+ <table class="table table-striped compact">
+ <thead>
+ <tr>
+ <th class="header">Logger</th>
+ <th class="header">Level</th>
+ <th class="header">Timeout (sec)</th>
+ <th class="header">Expires at</th>
+ <th class="header">Actions</th>
+ </tr>
+ </thead>
+ {{#loggers}}
+ {{ > log-level-and-timeout }}
+ {{/loggers}}
+ </table>
+ </div>
+</script>
+
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/user-template.html
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/user-template.html b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/user-template.html
new file mode 100644
index 0000000..853f0c9
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/templates/user-template.html
@@ -0,0 +1,38 @@
+<!--
+ 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.
+-->
+<script id="user-template" type="text/html">
+ <div class="ui-user">
+ {{#central-log-url}}
+ <span data-toggle="tooltip" data-placement="bottom" data-original-title="Link to Central Logging">
+ <a href="{{central-log-url}}" target="_blank"><image src="/images/statistic.png" class="image_pre_format"/></a>
+ </span>
+ {{/central-log-url}}
+ {{#bugtracker-url}}
+ <span data-toggle="tooltip" data-placement="bottom" data-original-title="Submit BUG for Help and tracking the issue.">
+ <a href="{{bugtracker-url}}" target="_blank"><image src="/images/bug.png" class="image_pre_format"/></a>
+ </span>
+ {{/bugtracker-url}}
+ <span data-toggle="tooltip" data-placement="bottom" data-original-title="Search through all logs for any topology.">
+ <a href="/deep_search_result.html" target="_blank"><image src="/images/search.png" class="image_pre_format"/></a>
+ </span>
+ {{#user}}
+ <span data-toggle="tooltip" data-placement="bottom" data-original-title="This should be you.">
+ User: {{user}}
+ </span>
+ {{/user}}
+ </div>
+</script>
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/topology.html
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/topology.html b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/topology.html
new file mode 100644
index 0000000..0250242
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/topology.html
@@ -0,0 +1,463 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!--
+ 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.
+-->
+
+<html><head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Storm UI</title>
+<link href="/css/bootstrap-3.3.1.min.css" rel="stylesheet" type="text/css">
+<link href="/css/jquery.dataTables.1.10.4.min.css" rel="stylesheet" type="text/css">
+<link href="/css/dataTables.bootstrap.css" rel="stylesheet" type="text/css">
+<link href="/css/jsonFormatter.min.css" rel="stylesheet" type="text/css">
+<link href="/css/style.css?_ts=${packageTimestamp}" rel="stylesheet" type="text/css">
+<script src="/js/jquery-1.11.1.min.js" type="text/javascript"></script>
+<script src="/js/jquery.dataTables.1.10.4.min.js" type="text/javascript"></script>
+<script src="/js/jquery.cookies.2.2.0.min.js" type="text/javascript"></script>
+<script src="/js/jquery.mustache.js" type="text/javascript"></script>
+<script src="/js/url.min.js" type="text/javascript"></script>
+<script src="/js/bootstrap-3.3.1.min.js" type="text/javascript"></script>
+<script src="/js/jquery.blockUI.min.js" type="text/javascript"></script>
+<script src="/js/jsonFormatter.min.js" type="text/javascript"></script>
+<script src="/js/script.js?_ts=${packageTimestamp}" type="text/javascript"></script>
+<script src="/js/dataTables.bootstrap.min.js" type="text/javascript"></script>
+</head>
+<body>
+<div class="container-fluid">
+ <div class="row">
+ <div class="col-md-11">
+ <h1><a href="/">Storm UI</a></h1>
+ </div>
+ <div id="ui-user" class="col-md-1"></div>
+ </div>
+ <div class="row">
+ <div class="col-md-12" id="search-form">
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Topology summary</h2>
+ <div id="topology-summary"></div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <h2 id="topology-resources-header">Topology resources</h2>
+ <div id="topology-resources"></div>
+ </div>
+ </div>
+ <div class="row">
+ <div id="topology-actions" class="col-md-12"></div>
+ </div>
+ <div class="row">
+ <div id="topology-stats" class="col-md-12"></div>
+ </div>
+ <div class="row">
+ <div id="topology-spouts-lag" class="col-md-12"></div>
+ </div>
+ <div class="row">
+ <div id="spout-stats" class="col-md-12"></div>
+ </div>
+ <div class="row">
+ <div id="bolt-stats" class="col-md-12"></div>
+ </div>
+ <div class="row">
+ <div id="worker-stats" class="col-md-12"></div>
+ </div>
+ <div class="row">
+ <div id="topology-visualization" class="col-md-12"></div>
+ </div>
+ <div class="row">
+ <div id="topology-configuration" class="col-md-12"></div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <p id="toggle-switch" style="display: block;" class="js-only"></p>
+ </div>
+ </div>
+ <div class="row">
+ <div id="json-response-error" class="col-md-12"></div>
+ </div>
+ <div>
+ <p id="page-rendered-at-timestamp"></p>
+ </div>
+</div>
+</body>
+<script>
+
+var toggleChangeLogLevel;
+
+function closeChangeLogLevel (){
+ var container = $("#change-log-level");
+ container.hide();
+}
+
+function clearLoggerLevel(id){
+ $("#loggerRemove-" + id).val("true");
+ sendLoggerLevel(id);
+ $("#logger-" + id).remove();
+}
+
+function sendLoggerLevel(id){
+ var topologyId = $.url("?id");
+ var shouldRemove = $("#loggerRemove-" + id).val() === "true";
+ var level = $("#loggerLevel-" + id).val();
+ var timeout = parseInt($("#loggerTimeout-" + id).val());
+ timeout = isNaN(timeout) ? 0 : timeout;
+ var loggerName = $("#loggerName-" + id).val();
+ if (level === 'Pick Level'){
+ alert ('Please pick a valid log level');
+ return;
+ }
+ var levelBelowInfo = level === 'DEBUG';
+
+ if (!shouldRemove && levelBelowInfo && timeout <= 0){
+ timeout = parseInt (
+ prompt ("You must provide a timeout > 0 for DEBUG log level. What timeout would you like (secs)?", 30));
+ if (!timeout){
+ return;
+ }
+ }
+ var data = {};
+ var loggerSetting;
+
+ if (id === 0) {
+ data["namedLoggerLevels"] = {};
+ data["namedLoggerLevels"]["ROOT"] = {};
+ loggerSetting = data["namedLoggerLevels"]["ROOT"];
+ } else {
+ data["namedLoggerLevels"] = {};
+ data["namedLoggerLevels"][loggerName] = {};
+ loggerSetting = data["namedLoggerLevels"][loggerName];
+ }
+
+ loggerSetting.target_level = shouldRemove ? null : level;
+ loggerSetting.reset_level = "INFO";
+ loggerSetting.timeout = timeout;
+
+ sendRequest (topologyId, "logconfig", null, data, toggleChangeLogLevel);
+};
+
+function renderLogLevelForm (template, responseData){
+ var topologyId = $.url("?id");
+ var container = $("#change-log-level");
+
+ var levels = [
+ {name: "Pick Level"},
+ {name: "ALL"},
+ {name: "TRACE"},
+ {name: "DEBUG"},
+ {name: "INFO" },
+ {name: "WARN" },
+ {name: "ERROR"},
+ {name: "FATAL"},
+ {name: "OFF"}
+ ];
+ var partialTemplates = $(template).filter('.partials');
+ var partials = {};
+
+ $.each(partialTemplates, function (ix, partial){
+ var obj = $(partial);
+ partials [obj.attr('id')] = obj.html();
+ });
+
+ var logLevelTemplate = $(template).filter("#topology-change-log-level-template").html();
+
+ var calcAbsoluteTimeout = function (timeout_epoch) {
+ var absoluteTimeout = "";
+ if (timeout_epoch) {
+ var d = new Date(0);
+ d.setUTCSeconds(timeout_epoch / 1000);
+ absoluteTimeout = d.toLocaleDateString() + " " + d.toLocaleTimeString();
+ }
+ return absoluteTimeout;
+ };
+ var renderImpl = function (data){
+ var loggers = [];
+ var loggerCount = 1;
+ var obj = data.namedLoggerLevels;
+ if (!obj) {
+ obj = {};
+ data.namedLoggerLevels = obj;
+ }
+
+ var sortedLoggers = Object.keys(obj).sort(function (l1, l2){
+ if (l1 === "ROOT") return -1;
+ if (l2 === "ROOT") return 1;
+ return l1 > l2;
+ });
+
+ sortedLoggers.forEach (function (l){
+ var obj = data.namedLoggerLevels[l];
+ obj.loggerId = loggerCount++;
+ obj.loggerName = l;
+ obj.named = l != "ROOT";
+ obj.cls = "namedLoggers";
+ obj.levelSelected = function (obj){
+ return function (){
+ return this.name === obj.target_level ? "selected" : "";
+ }
+ }(obj);
+ obj.absoluteTimeout = calcAbsoluteTimeout (obj.timeout_epoch);
+ obj.canClear = true;
+ loggers.push(obj);
+ });
+
+ loggers.push({
+ loggerId: loggerCount,
+ isNew: true,
+ cls: 'newLogger'
+ });
+
+ var tmplData = {
+ loggers: loggers,
+ levels: levels
+ };
+
+ container.html(Mustache.render(logLevelTemplate, tmplData, partials));
+ container.show('fast');
+ };
+ if (!responseData) {
+ var topologyId = $.url("?id");
+ $.get('/api/v1/topology/' + topologyId + '/logconfig', renderImpl);
+ } else {
+ renderImpl (responseData);
+ }
+}
+$(document).ajaxStop($.unblockUI);
+$(document).ajaxStart(function(){
+ if ($("#topology-visualization").children().size() == 0) {
+ $.blockUI({ message: '<img src="images/spinner.gif" /> <h3>Loading topology summary...</h3>'});
+ }
+});
+$(document).ready(function() {
+ var topologyId = $.url("?id");
+ var tableStateKey = ":".concat(topologyId);
+ var window = $.url("?window");
+ var sys = $.cookies.get("sys") || "false";
+ var url = "/api/v1/topology/"+topologyId+"?sys="+sys;
+ if(window) url += "&window="+window;
+ $.getJSON("/api/v1/cluster/configuration",function(response,status,jqXHR) {
+ $.extend( $.fn.dataTable.defaults, {
+ stateSave: true,
+ stateSaveCallback: function (oSettings, oData) {
+ sessionStorage.setItem( oSettings.sTableId.concat(tableStateKey), JSON.stringify(oData) );
+ },
+ stateLoadCallback: function (oSettings) {
+ return JSON.parse( sessionStorage.getItem(oSettings.sTableId.concat(tableStateKey)) );
+ },
+ lengthMenu: [[20,40,60,100,-1], [20, 40, 60, 100, "All"]],
+ pageLength: response["ui.pagination"]
+ });
+ });
+
+ renderToggleSys($("#toggle-switch"));
+ $.ajaxSetup({
+ "error":function(jqXHR,textStatus,response) {
+ var errorJson = jQuery.parseJSON(jqXHR.responseText);
+ getStatic("/templates/json-error-template.html", function(template) {
+ $("#json-response-error").append(Mustache.render($(template).filter("#json-error-template").html(),errorJson));
+ });
+ }
+ });
+
+ $.getJSON(url,function(response,status,jqXHR) {
+ var uiUser = $("#ui-user");
+ getStatic("/templates/user-template.html", function(template) {
+ uiUser.append(Mustache.render($(template).filter("#user-template").html(),response));
+ $('#ui-user [data-toggle="tooltip"]').tooltip();
+ });
+
+ var topologySummary = $("#topology-summary");
+ var topologyResources = $("#topology-resources");
+ var topologyStats = $("#topology-stats");
+ var topologySpoutsLag = $("#topology-spouts-lag");
+ var spoutStats = $("#spout-stats");
+ var boltStats = $("#bolt-stats");
+ var workerStats = $("#worker-stats");
+ var config = $("#topology-configuration");
+ var topologyActions = $("#topology-actions");
+ var topologyVisualization = $("#topology-visualization")
+ var searchForm = $("#search-form")
+ var formattedConfig = formatConfigData(response["configuration"]);
+ var buttonJsonData = topologyActionJson(response["id"],response["encodedId"],response["name"],response["status"]
+ ,response["msgTimeout"],response["configuration"]["topology.eventlogger.executors"],response["debug"],response["samplingPct"]);
+ $.ajax ({url: "/templates/topology-page-template.html", success: function(template) {
+ toggleChangeLogLevel = function (data) {
+ renderLogLevelForm (template, data);
+ }
+ searchForm.append(Mustache.render($(template).filter("#search-form-template").html(),{id: topologyId}));
+ topologySummary.append(Mustache.render($(template).filter("#topology-summary-template").html(),response));
+ topologyResources.append(Mustache.render($(template).filter("#topology-resources-template").html(),response));
+ var displayResource = response["schedulerDisplayResource"];
+ if (!displayResource){
+ $('#topology-resources-header').hide();
+ $('#topology-resources').hide();
+ }
+ topologyActions.append(Mustache.render($(template).filter("#topology-actions-template").html(),buttonJsonData));
+ topologyStats.append(Mustache.render($(template).filter("#topology-stats-template").html(),response));
+ //window, emitted, transferred, complete latency, acked, failed
+ $("#topology-stats-table").DataTable({
+ paging: false,
+ info: false,
+ searching: false,
+ columnDefs: [
+ {type: "num", targets: [1, 2, 3, 4, 5]},
+ {type: "time-str", targets: [0]}
+ ]
+ });
+
+ spoutStats.append(Mustache.render($(template).filter("#spout-stats-template").html(),response));
+ dtAutoPage("#spout-stats-table", {
+ columnDefs: [
+ {type: "num", targets: 'table-num'}
+ ]
+ });
+
+ boltStats.append(Mustache.render($(template).filter("#bolt-stats-template").html(),response));
+ dtAutoPage("#bolt-stats-table", {
+ columnDefs: [
+ {type: "num", targets: 'table-num'}
+ ]
+ });
+
+ jsError(function() {
+ workerStats.append(Mustache.render($(template).filter("#worker-stats-template").html(),response));
+ makeTopologyWorkerStatsTable (response, '#worker-stats-table', '#worker-stats');
+ });
+
+ jsError(function() {
+ topologyVisualization.append(Mustache.render($(template).filter("#topology-visualization-template").html(), response));
+ var sys = $.cookies.get("sys") || "false";
+ $("#show-hide-visualization").click(function () { show_visualization(sys) });
+ $("#open-visualization").click(function() { open_visualization(sys); });
+
+ config.append(Mustache.render($(template).filter("#topology-configuration-template").html(),formattedConfig));
+ $('#topology-configuration td').jsonFormatter()
+ //key, value
+ dtAutoPage("#topology-configuration-table", {});
+
+ var errorCells = document.getElementsByClassName("errorSpan");
+ for (i =0; i < errorCells.length; i++)
+ {
+ var timeLapsedInSecs = errorCells[i].id;
+ if (parseInt(timeLapsedInSecs) < 1800) {
+ errorCells[i].style.color = "#9d261d";
+ errorCells[i].style.borderBottomColor = "#9d261d";
+ }
+ errorCells[i].style.whiteSpace = "pre";
+ }
+
+ var errorTime = document.getElementsByClassName("errorTime");
+ for (i=0; i < errorTime.length; i++)
+ {
+ if((errorTime[i].id))
+ {
+ var a = new Date(parseInt(errorTime[i].id) * 1000);
+ var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
+ var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat'];
+ var year = a.getFullYear();
+ var month = months[a.getMonth()];
+ var date = a.getDate();
+ var hour = a.getHours();
+ var min = a.getMinutes();
+ var sec = a.getSeconds();
+ var day = days[a.getDay()];
+ if (hour < 10) {hour = "0"+hour;}
+ if (min < 10) {min = "0"+min;}
+ if (sec < 10) {sec = "0"+sec;}
+ var time = day + ', '+date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec;
+
+ errorTime[i].innerHTML = time;
+ var sec_num = parseInt(errorTime[i].title, 10);
+ var hours = Math.floor(sec_num / 3600);
+ var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
+ var seconds = sec_num - (hours * 3600) - (minutes * 60);
+ if (hours < 10) {hours = "0"+hours;}
+ if (minutes < 10) {minutes = "0"+minutes;}
+ if (seconds < 10) {seconds = "0"+seconds;}
+ var time = hours+':'+minutes+':'+seconds;
+ errorTime[i].title = "Elapsed Time Since Error: " + time;
+ }
+ }
+ $('#topology-summary [data-toggle="tooltip"]').tooltip();
+ $('#topology-stats [data-toggle="tooltip"]').tooltip();
+ $('#spout-stats [data-toggle="tooltip"]').tooltip();
+ $('#bolt-stats [data-toggle="tooltip"]').tooltip();
+ $('#topology-configuration [data-toggle="tooltip"]').tooltip();
+ $('#topology-actions [data-toggle="tooltip"]').tooltip();
+ $('#topology-visualization [data-toggle="tooltip"]').tooltip();
+
+ var lagUrl = "/api/v1/topology/"+topologyId+"/lag";
+ $.getJSON(lagUrl,function(lagResponse,status,jqXHR) {
+ if (lagResponse !== null && lagResponse !== undefined) {
+ var kafkaSpoutsLagTemplate = $(template).filter("#topology-kafka-spouts-lag-template").html();
+ var spoutsErrorTemplate = $(template).filter("#topology-spouts-lag-error-template").html();
+
+ var data = {};
+ data.kafkaSpoutsLagResults = [];
+ data.spoutsLagErrorResults = [];
+ for (var spoutId in lagResponse) {
+ var spout = lagResponse[spoutId];
+ var spoutType = spout.spoutType;
+ if (spoutType !== "KAFKA") {
+ continue;
+ }
+ var spoutLagResult = spout.spoutLagResult;
+ var errorInfo = spout.errorInfo;
+ if (spoutLagResult !== undefined) {
+ for (var topicName in spoutLagResult) {
+ var topicLagResult = spoutLagResult[topicName];
+ for (var partitionId in topicLagResult) {
+ var partitionLagResult = topicLagResult[partitionId];
+ data.kafkaSpoutsLagResults.push({
+ id: spoutId,
+ topic: topicName,
+ partition: partitionId,
+ logHeadOffset: partitionLagResult.logHeadOffset,
+ consumerCommittedOffset: partitionLagResult.consumerCommittedOffset,
+ lag: partitionLagResult.lag
+ });
+ }
+ }
+ } else if (errorInfo !== undefined) {
+ data.spoutsLagErrorResults.push({
+ spoutId: spoutId,
+ spoutType: spout.spoutType,
+ errorInfo: errorInfo
+ });
+ }
+ }
+
+ if (data.kafkaSpoutsLagResults.length > 0) {
+ topologySpoutsLag.append(Mustache.render(kafkaSpoutsLagTemplate, data));
+ }
+ if (data.spoutsLagErrorResults.length > 0) {
+ topologySpoutsLag.append(Mustache.render(spoutsErrorTemplate, data));
+ }
+ }
+ });
+ });
+ }});
+ });
+ });
+
+getPageRenderedTimestamp("page-rendered-at-timestamp");
+
+</script>
+</html>
+
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/visualize.html
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/visualize.html b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/visualize.html
new file mode 100644
index 0000000..ec16544
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/visualize.html
@@ -0,0 +1,124 @@
+<html>
+<head>
+ <!--
+ 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.
+ -->
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Topology Visualization</title>
+ <link href="/css/bootstrap-3.3.1.min.css" rel="stylesheet" type="text/css">
+ <link href="/css/vis.min.css" rel="stylesheet" type="text/css" />
+ <link href="/css/style.css?_ts=${packageTimestamp}" rel="stylesheet" type="text/css">
+ <script src="/js/jquery-1.11.1.min.js" type="text/javascript"></script>
+ <script src="/js/jquery.mustache.js" type="text/javascript"></script>
+ <script src="/js/url.min.js" type="text/javascript"></script>
+ <script src="/js/vis.min.js" type="text/javascript"></script>
+ <script src="/js/visualization.js" type="text/javascript"></script>
+</head>
+<body>
+<div id="visualization">
+ <!-- Slide out for stream selection -->
+ <div id="streams_slideout">
+ <div id="streams_slideout_inner">
+ <img src="/images/streams.png" alt="Streams" style="float: right;"/>
+ <ul id="available-streams">
+ </ul>
+ </div>
+ </div>
+
+ <!-- Slide out for bolt stats -->
+ <div id="bolt_slideout">
+ <div id="bolt_slideout_inner">
+ <img src="/images/component.png" alt="Component Info" class="header" style="float: left;"/>
+ <ul id="bolt-details"></ul>
+ </div>
+ </div>
+
+ <div id="mynetwork"></div>
+
+ <!-- template for stream selector checkbox -->
+ <script id="stream_selector_template" type="text/template">
+ <li>
+ <label>
+ <input type="checkbox" id="stream-{{streamNameSanitized}}" class="stream_checkbox" onclick="checkStream(this);" {{checked}}>{{streamName}}
+ </label>
+ </li>
+ </script>
+
+ <!-- template for bolt info -->
+ <script id="bolt_info_template" type="text/template">
+ <!-- top level component details -->
+ <li>Id: <a href="{{:link}}" target="_blank">{{:id}}</a> ◳</li>
+ <li>Type: {{:type}}</li>
+ <li>Latency: {{:latency}} ms</li>
+ <li>Capacity: {{:capacity}}</li>
+ <li>Transferred: {{:transferred}}</li>
+
+ <!-- Inputs to Component -->
+ <li>
+ <details>
+ <summary>{{:inputs_length}} Inputs</summary>
+ <ul id="bolt-inputs">
+ <!-- Start loop over inputs -->
+ {{#:inputs}}
+ <li>
+ <details>
+ <summary>
+ {{#:show_link}}
+ <a href="#" onclick="network.selectNodes(['{{:component}}']); handleNodeClickEvent('{{:component}}'); return false;">{{:component}}</a>
+ {{/:show_link}}
+ {{^:show_link}}
+ {{:component}}
+ {{/:show_link}}
+ </summary>
+ <ul>
+ <li>Stream: {{:stream}}</li>
+ <li>Grouping: {{:grouping}}</li>
+ </ul>
+ </details>
+ </li>
+ {{/:inputs}}
+ </ul>
+ </details>
+ </li>
+
+ <!-- Instance Details -->
+ <li>
+ <details>
+ <summary>
+ {{:stats_length}} Instance(s)
+ </summary>
+ <ul id="bolt-instances">
+ <!-- Start loop over instances -->
+ {{#:stats}}
+ <li>
+ <details>
+ <summary>
+ {{:host}}:{{:port}}
+ </summary>
+ <ul>
+ <li>Uptime: {{:uptime_str}}</li>
+ </ul>
+ </details>
+ </li>
+ {{/:stats}}
+ </ul>
+ </details>
+ </li>
+ </script>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/AuthorizationExceptionMapper.java
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/AuthorizationExceptionMapper.java b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/AuthorizationExceptionMapper.java
new file mode 100644
index 0000000..5ee8ccb
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/AuthorizationExceptionMapper.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+package org.apache.storm.daemon.ui.exceptionmappers;
+
+import static org.apache.storm.daemon.ui.exceptionmappers.ExceptionMapperUtils.getResponse;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import org.apache.storm.generated.AuthorizationException;
+
+@Provider
+public class AuthorizationExceptionMapper implements ExceptionMapper<AuthorizationException> {
+
+ @Inject
+ public javax.inject.Provider<HttpServletRequest> request;
+
+ @Override
+ public Response toResponse(AuthorizationException e) {
+ return getResponse(e, request);
+ }
+}
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/DefaultExceptionMapper.java
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/DefaultExceptionMapper.java b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/DefaultExceptionMapper.java
new file mode 100644
index 0000000..73aeb05
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/DefaultExceptionMapper.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.storm.daemon.ui.exceptionmappers;
+
+import static org.apache.storm.daemon.ui.exceptionmappers.ExceptionMapperUtils.getResponse;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
+
+ @Inject
+ public javax.inject.Provider<HttpServletRequest> request;
+
+ /**
+ * toResponse.
+ * @param throwable
+ * @return response
+ */
+ @Override
+ public Response toResponse(Throwable throwable) {
+ if (throwable instanceof Exception) {
+ return getResponse((Exception) throwable, request);
+ } else {
+ return getResponse(new Exception(throwable.getMessage(), throwable), request);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/storm/blob/034ac677/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/ExceptionMapperUtils.java
----------------------------------------------------------------------
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/ExceptionMapperUtils.java b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/ExceptionMapperUtils.java
new file mode 100644
index 0000000..7d3627e
--- /dev/null
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/exceptionmappers/ExceptionMapperUtils.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package org.apache.storm.daemon.ui.exceptionmappers;
+
+import javax.inject.Provider;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
+
+import org.apache.storm.daemon.common.JsonResponseBuilder;
+import org.apache.storm.daemon.ui.UIHelpers;
+import org.apache.storm.daemon.ui.resources.StormApiResource;
+import org.apache.storm.generated.AuthorizationException;
+
+
+public class ExceptionMapperUtils {
+
+ /**
+ * getResponse.
+ * @param ex ex
+ * @param responseStatus responseStatus
+ * @return getResponse
+ */
+ public static Response getResponse(Exception ex, Response.Status responseStatus,
+ Provider<HttpServletRequest> request) {
+ String callback = null;
+ if (request.get().getParameterMap().containsKey(StormApiResource.callbackParameterName)) {
+ callback = String.valueOf(request.get().getParameterMap().get(StormApiResource.callbackParameterName));
+ }
+ return new JsonResponseBuilder().setData(
+ UIHelpers.exceptionToJson(ex, responseStatus.getStatusCode())).setCallback(callback)
+ .setStatus(responseStatus.getStatusCode()).build();
+ }
+
+ /**
+ * getResponse.
+ * @param ex ex
+ * @param request request
+ * @return getResponse
+ */
+ public static Response getResponse(AuthorizationException ex, Provider<HttpServletRequest> request) {
+ return getResponse(ex, Response.Status.UNAUTHORIZED, request);
+ }
+
+ /**
+ * getResponse.
+ * @param ex ex
+ * @return getResponse
+ */
+ public static Response getResponse(Exception ex, Provider<HttpServletRequest> request) {
+ return getResponse(ex, Response.Status.INTERNAL_SERVER_ERROR, request);
+ }
+
+
+}