mirror of https://github.com/apache/lucene.git
SOLR-13244: Nodes view fails when a node is temporarily down
This commit is contained in:
parent
571b307266
commit
8f29d1eaad
|
@ -120,6 +120,8 @@ Bug Fixes
|
|||
* SOLR-13284: NullPointerException with 500 http status on omitted or wrong wt param.
|
||||
It's fixed by fallback to json (Munendra S N via Mikhail Khludnev)
|
||||
|
||||
* SOLR-13244: Admin UI Nodes view fails and is empty when a node is temporarily down (janhoy)
|
||||
|
||||
Improvements
|
||||
----------------------
|
||||
* SOLR-12999: Index replication could delete segments before downloading segments from master if there is not enough
|
||||
|
|
|
@ -535,6 +535,17 @@ limitations under the License.
|
|||
color: red;
|
||||
}
|
||||
|
||||
#content #cloud #nodes-content .node-down
|
||||
{
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#content #cloud #nodes-content .dead-node
|
||||
{
|
||||
background-color: salmon;
|
||||
}
|
||||
|
||||
/* Styling of reload and details buttons */
|
||||
#content #cloud #controls,
|
||||
#content #cloud #frame #zk-status-content #zk-controls
|
||||
|
|
|
@ -107,6 +107,10 @@ function isNumeric(n) {
|
|||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
}
|
||||
|
||||
function coreNameToLabel(name) {
|
||||
return name.replace(/(.*?)_shard((\d+_?)+)_replica_?[ntp]?(\d+)/, '\$1_s\$2r\$4');
|
||||
}
|
||||
|
||||
var nodesSubController = function($scope, Collections, System, Metrics) {
|
||||
$scope.pageSize = 10;
|
||||
$scope.showNodes = true;
|
||||
|
@ -160,6 +164,17 @@ var nodesSubController = function($scope, Collections, System, Metrics) {
|
|||
return nodesInHost[0] === node;
|
||||
};
|
||||
|
||||
// Returns the first live node for this host, to make sure we pick host-level metrics from a live node
|
||||
$scope.firstLiveNodeForHost = function(key) {
|
||||
var hostName = key.split(":")[0];
|
||||
var liveNodesInHost = $scope.filteredNodes.filter(function (key) {
|
||||
return key.startsWith(hostName);
|
||||
}).filter(function (key) {
|
||||
return $scope.live_nodes.includes(key);
|
||||
});
|
||||
return liveNodesInHost.length > 0 ? liveNodesInHost[0] : key;
|
||||
};
|
||||
|
||||
// Initializes the cluster state, list of nodes, collections etc
|
||||
$scope.initClusterState = function() {
|
||||
var nodes = {};
|
||||
|
@ -183,6 +198,7 @@ var nodesSubController = function($scope, Collections, System, Metrics) {
|
|||
for (var replicaName in replicas) {
|
||||
var core = replicas[replicaName];
|
||||
core.name = replicaName;
|
||||
core.label = coreNameToLabel(core['core']);
|
||||
core.collection = collection.name;
|
||||
core.shard = shard.name;
|
||||
core.shard_state = shard.state;
|
||||
|
@ -320,7 +336,15 @@ var nodesSubController = function($scope, Collections, System, Metrics) {
|
|||
nodesToShow = nodesToShow.concat(hosts[hostName]['nodes']);
|
||||
}
|
||||
}
|
||||
nodesParam = nodesToShow.join(',');
|
||||
nodesParam = nodesToShow.filter(function (node) {
|
||||
return live_nodes.includes(node);
|
||||
}).join(',');
|
||||
var deadNodes = nodesToShow.filter(function (node) {
|
||||
return !live_nodes.includes(node);
|
||||
});
|
||||
deadNodes.forEach(function (node) {
|
||||
nodes[node]['dead'] = true;
|
||||
});
|
||||
$scope.nextEnabled = $scope.from + pageSize < filteredHosts.length;
|
||||
$scope.prevEnabled = $scope.from - pageSize >= 0;
|
||||
nodesToShow.sort();
|
||||
|
@ -410,7 +434,6 @@ var nodesSubController = function($scope, Collections, System, Metrics) {
|
|||
size = (typeof size !== 'undefined') ? size : 0;
|
||||
core['sizeInBytes'] = size;
|
||||
core['size'] = bytesToSize(size);
|
||||
core['label'] = core['core'].replace(/(.*?)_shard((\d+_?)+)_replica_?[ntp]?(\d+)/, '\$1_s\$2r\$4');
|
||||
if (core['shard_state'] !== 'active' || core['state'] !== 'active') {
|
||||
// If core state is not active, display the real state, or if shard is inactive, display that
|
||||
var labelState = (core['state'] !== 'active') ? core['state'] : core['shard_state'];
|
||||
|
|
|
@ -149,88 +149,92 @@ limitations under the License.
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="key in nodesToShow | orderBy:'key.order'" ng-init="n = nodes[key]">
|
||||
<td rowspan="{{hosts[n.host].nodes.length}}" ng-show="isFirstNodeForHost(key)">
|
||||
<div class="host-name">{{n.host}}</div>
|
||||
<span class="host-spec" ng-show="!showDetails[n.host]">
|
||||
<span title="{{n.system.system.uptime}}">{{n.system.system.name}}</span>
|
||||
<span title="free: {{n.memFree}}">{{n.memTotal}}</span>
|
||||
<span title="{{n.system.jvm.name}} {{n.system.jvm.version}}">Java {{n.system.jvm.spec.version}}</span>
|
||||
<br/>Load: {{n.loadAvg}}
|
||||
<tr ng-repeat="key in nodesToShow | orderBy:'key.order'" ng-init="n = nodes[key]; h = nodes[firstLiveNodeForHost(key)]">
|
||||
<td rowspan="{{hosts[h.host].nodes.length}}" ng-show="isFirstNodeForHost(key)">
|
||||
<div class="host-name">{{h.host}}</div>
|
||||
<span class="host-spec" ng-show="!showDetails[h.host]">
|
||||
<span title="{{h.system.system.uptime}}">{{h.system.system.name}}</span>
|
||||
<span title="free: {{h.memFree}}">{{h.memTotal}}</span>
|
||||
<span title="{{h.system.jvm.name}} {{h.system.jvm.version}}">Java {{h.system.jvm.spec.version}}</span>
|
||||
<br/>Load: {{h.loadAvg}}
|
||||
</span>
|
||||
<div class="host-spec" ng-show="showDetails[n.host]">
|
||||
{{n.system.system.name}} {{n.system.system.version}}, {{n.system.system.availableProcessors}}cpu<br/>
|
||||
Uptime: {{n.uptime}}<br/>
|
||||
<span title="Used: {{n.memUsed}} - includes OS file-cache, and it is normal for it to approach 100%">Memory: {{n.memTotal}}</span><br/>
|
||||
File descriptors: {{n.openFileDescriptorCount}}/{{n.maxFileDescriptorCount}}<br/>
|
||||
Disk: <span class="{{n.diskUsedPctStyle}}" title="Nodes may use other disks too">{{n.diskTotal}} used: {{n.diskUsedPct}}%</span><br/>
|
||||
Load: {{n.loadAvg}}
|
||||
<div class="host-spec" ng-show="showDetails[h.host]">
|
||||
{{h.system.system.name}} {{h.system.system.version}}, {{h.system.system.availableProcessors}}cpu<br/>
|
||||
Uptime: {{h.uptime}}<br/>
|
||||
<span title="Used: {{h.memUsed}} - includes OS file-cache, and it is normal for it to approach 100%">Memory: {{h.memTotal}}</span><br/>
|
||||
File descriptors: {{h.openFileDescriptorCount}}/{{h.maxFileDescriptorCount}}<br/>
|
||||
Disk: <span class="{{h.diskUsedPctStyle}}" title="Nodes may use other disks too">{{h.diskTotal}} used: {{h.diskUsedPct}}%</span><br/>
|
||||
Load: {{h.loadAvg}}
|
||||
</div>
|
||||
<div class="node-spec" ng-click="toggleHostDetails(n.host)">
|
||||
<a ng-show="showDetails[n.host]">hide details...</a>
|
||||
<a ng-show="!showDetails[n.host]">show details...</a>
|
||||
<div class="node-spec" ng-click="toggleHostDetails(h.host)">
|
||||
<a ng-show="showDetails[h.host]">hide details...</a>
|
||||
<a ng-show="!showDetails[h.host]">show details...</a>
|
||||
</div>
|
||||
</td>
|
||||
<td><div class="node-name"><a href="{{n.base_url}}">{{key.replace(n.host+':', '')}}</a></div>
|
||||
Uptime: {{n.jvmUptime}}<br/>
|
||||
<div class="node-spec" ng-show="showDetails[key]">
|
||||
Java <span title="{{n.system.jvm.jre.vendor}}">{{n.system.jvm.jre.version}}</span><br/>
|
||||
Solr {{n.system.lucene['solr-impl-version'].split(" ")[0]}}<br>
|
||||
</div>
|
||||
<div class="node-spec" ng-click="toggleDetails(key)">
|
||||
<a ng-show="showDetails[key]">hide details...</a>
|
||||
<a ng-show="!showDetails[key]">show details...</a>
|
||||
<td ng-class="{'dead-node': n.dead}"><div class="node-name"><a href="{{n.base_url}}">{{key.replace(n.host+':', '')}}</a></div>
|
||||
<div ng-show="n.dead" class="node-down">(DEAD)</div>
|
||||
<div ng-show="!n.dead">
|
||||
Uptime: {{n.jvmUptime}}<br/>
|
||||
<div class="node-spec" ng-show="showDetails[key]">
|
||||
Java <span title="{{n.system.jvm.jre.vendor}}">{{n.system.jvm.jre.version}}</span><br/>
|
||||
Solr {{n.system.lucene['solr-impl-version'].split(" ")[0]}}<br>
|
||||
</div>
|
||||
<div class="node-spec" ng-click="toggleDetails(key)">
|
||||
<a ng-show="showDetails[key]">hide details...</a>
|
||||
<a ng-show="!showDetails[key]">show details...</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="node-cpu">
|
||||
<td ng-class="{'dead-node': n.dead}">
|
||||
<div class="node-cpu" ng-show="!n.dead">
|
||||
<span class="{{n.cpuPctStyle}}">{{n.cpuPct}}%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="node-heap" title="total: {{n.heapTotal}} free: {{n.heapFree}} used%: {{n.heapUsedPct}}%">
|
||||
<td ng-class="{'dead-node': n.dead}">
|
||||
<div class="node-heap" title="total: {{n.heapTotal}} free: {{n.heapFree}} used%: {{n.heapUsedPct}}%" ng-show="!n.dead">
|
||||
<span class="{{n.heapUsedPctStyle}}">{{n.heapUsedPct}}%</span>
|
||||
</div>
|
||||
<div class="node-spec" ng-show="showDetails[key]">
|
||||
<div class="node-spec" ng-show="showDetails[key] && !n.dead">
|
||||
Max: {{n.heapTotal}}<br/>
|
||||
Used: {{n.heapUsed}}
|
||||
</div>
|
||||
</td>
|
||||
<td class="scroll-height-250">
|
||||
<td class="scroll-height-250" ng-class="{'dead-node': n.dead}">
|
||||
<div>
|
||||
<div class="node-disk" title="Available disk: {{n.diskTotal}} free: {{n.diskFree}} used by this node: {{n.size}}">
|
||||
<div class="node-disk" title="Available disk: {{n.diskTotal}} free: {{n.diskFree}} used by this node: {{n.size}}" ng-show="!n.dead">
|
||||
{{n.size}}
|
||||
</div>
|
||||
<div class="node-spec" ng-show="showDetails[key]">
|
||||
<div class="node-spec" ng-show="showDetails[key] && !n.dead">
|
||||
Total #docs: {{n.numDocs}}<br/>
|
||||
Avg size/doc: {{n.sizePerDoc}}
|
||||
</div>
|
||||
<div id="chart{{n.id}}" ng-show="showDetails[key]"></div>
|
||||
<div id="chart{{n.id}}" ng-show="showDetails[key] && !n.dead"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td><div class="node-requests" title="1minRate: {{n.req1minRate}} 5minRate: {{n.req5minRate}} 15minRate: {{n.req15minRate}} p75: {{n.reqp75_ms}} p99: {{n.reqp99_ms}}">
|
||||
<td ng-class="{'dead-node': n.dead}"><div class="node-requests" title="1minRate: {{n.req1minRate}} 5minRate: {{n.req5minRate}} 15minRate: {{n.req15minRate}} p75: {{n.reqp75_ms}} p99: {{n.reqp99_ms}}" ng-show="!n.dead">
|
||||
RPM: {{n.req15minRate}}<br/>p95: {{n.reqp95_ms}}ms</div>
|
||||
</td>
|
||||
<td>
|
||||
<td ng-class="{'dead-node': n.dead}">
|
||||
<div ng-show="!n.collections">(none)</div>
|
||||
<div ng-repeat="c in n.collections | limitTo:showDetails[key]?999:2 track by $index">
|
||||
<a href="{{n.base_url + '/#/~collections/' + c}}">{{ c }}</a>
|
||||
<a href="{{h.base_url + '/#/~collections/' + c}}">{{ c }}</a>
|
||||
</div>
|
||||
<div class="more" ng-show="n.collections.length > 2 && !showDetails[key]">
|
||||
<a ng-click="toggleDetails(key)">({{n.collections.length - 2}} more...)</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="scroll-height-250">
|
||||
<td class="scroll-height-250" ng-class="{'dead-node': n.dead}">
|
||||
<div ng-show="!n.cores">(none)</div>
|
||||
<div ng-repeat="core in n.cores | limitTo:showDetails[key]?999:2 track by $index">
|
||||
<a class="{{core.leader ? 'leader' : 'replica'}}" href="{{core.base_url + '/#/' + core.core}}">{{ core.label }}</a> ({{core.numDocsHuman}} docs)
|
||||
<ul class="core-details" ng-show="showDetails[key]">
|
||||
<div ng-show="!n.dead"><a class="{{core.leader ? 'leader' : 'replica'}}" href="{{core.base_url + '/#/' + core.core + '/core-overview'}}">{{ core.label }}</a> ({{core.numDocsHuman}} docs)</div>
|
||||
<div ng-show="n.dead">{{ core.label }}</div>
|
||||
<ul class="core-details" ng-show="showDetails[key] && !n.dead" >
|
||||
<li>deleted: {{core.deletedDocsHuman}}</li>
|
||||
<li>warmupTime: {{core.warmupTime}}</li>
|
||||
<li ng-show="core.numDocs > 0">avg size/doc: {{core.avgSizePerDoc}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="more" ng-show="n.cores.length > 2 && !showDetails[key]">
|
||||
<div class="more" ng-show="n.cores.length > 2 && !showDetails[key] && !n.dead">
|
||||
<a ng-click="toggleDetails(key)">({{n.cores.length - 2}} more...)</a>
|
||||
</div>
|
||||
</td>
|
||||
|
|
Loading…
Reference in New Issue