Add the 'recovery' _cat API endpoint
This addes the _cat/recovery/{index} API endpoint, which displays information about the status of recovering shards. An example of the output: index shard node target recovered % test2 0 Fwo7c_6MSdWM0uM1Ho4t-g 147304414 19236101 13.1% test 0 Fwo7c_6MSdWM0uM1Ho4t-g 145891423 119640535 82.0% Fixes #3969
This commit is contained in:
parent
b1b52b641d
commit
e3db12bf50
|
@ -69,10 +69,7 @@ import org.elasticsearch.rest.action.admin.indices.warmer.delete.RestDeleteWarme
|
|||
import org.elasticsearch.rest.action.admin.indices.warmer.get.RestGetWarmerAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.warmer.put.RestPutWarmerAction;
|
||||
import org.elasticsearch.rest.action.bulk.RestBulkAction;
|
||||
import org.elasticsearch.rest.action.cat.RestIndicesAction;
|
||||
import org.elasticsearch.rest.action.cat.RestMasterAction;
|
||||
import org.elasticsearch.rest.action.cat.RestNodesAction;
|
||||
import org.elasticsearch.rest.action.cat.RestShardsAction;
|
||||
import org.elasticsearch.rest.action.cat.*;
|
||||
import org.elasticsearch.rest.action.count.RestCountAction;
|
||||
import org.elasticsearch.rest.action.delete.RestDeleteAction;
|
||||
import org.elasticsearch.rest.action.deletebyquery.RestDeleteByQueryAction;
|
||||
|
@ -200,6 +197,7 @@ public class RestActionModule extends AbstractModule {
|
|||
bind(RestIndicesAction.class).asEagerSingleton();
|
||||
// Fully qualified to prevent interference with rest.action.count.RestCountAction
|
||||
bind(org.elasticsearch.rest.action.cat.RestCountAction.class).asEagerSingleton();
|
||||
bind(RestClearScrollAction.class).asEagerSingleton();;
|
||||
bind(RestClearScrollAction.class).asEagerSingleton();
|
||||
bind(RestRecoveryAction.class).asEagerSingleton();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch 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.elasticsearch.rest.action.cat;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.indices.status.IndicesStatusRequest;
|
||||
import org.elasticsearch.action.admin.indices.status.IndicesStatusResponse;
|
||||
import org.elasticsearch.action.admin.indices.status.ShardStatus;
|
||||
import org.elasticsearch.action.support.broadcast.BroadcastOperationThreading;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.Table;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.shard.IndexShardState;
|
||||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.support.RestTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
|
||||
/**
|
||||
* RestRecoveryAction provides information about the status of replica recovery
|
||||
* in a string format, designed to be used at the command line. An Index can
|
||||
* be specified to limit output to a particular index or indices.
|
||||
*/
|
||||
public class RestRecoveryAction extends BaseRestHandler {
|
||||
|
||||
@Inject
|
||||
protected RestRecoveryAction(Settings settings, Client client, RestController restController) {
|
||||
super(settings, client);
|
||||
restController.registerHandler(GET, "/_cat/recovery", this);
|
||||
restController.registerHandler(GET, "/_cat/recovery/{index}", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRequest(final RestRequest request, final RestChannel channel) {
|
||||
String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
|
||||
IndicesStatusRequest indicesStatusRequest = new IndicesStatusRequest(indices);
|
||||
indicesStatusRequest.recovery(true);
|
||||
indicesStatusRequest.operationThreading(BroadcastOperationThreading.SINGLE_THREAD);
|
||||
|
||||
client.admin().indices().status(indicesStatusRequest, new ActionListener<IndicesStatusResponse>() {
|
||||
@Override
|
||||
public void onResponse(IndicesStatusResponse indicesStatusResponse) {
|
||||
Map<String, Long> primarySizes = new HashMap<String, Long>();
|
||||
Set<ShardStatus> replicas = new HashSet<ShardStatus>();
|
||||
|
||||
// Loop through all the shards in the index status, keeping
|
||||
// track of the primary shard size with a Map and the
|
||||
// recovering shards in a Set of ShardStatus objects
|
||||
for (ShardStatus shardStatus : indicesStatusResponse.getShards()) {
|
||||
if (shardStatus.getShardRouting().primary()) {
|
||||
primarySizes.put(shardStatus.getShardRouting().getIndex() + shardStatus.getShardRouting().getId(),
|
||||
shardStatus.getStoreSize().bytes());
|
||||
} else if (shardStatus.getState() == IndexShardState.RECOVERING) {
|
||||
replicas.add(shardStatus);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
channel.sendResponse(RestTable.buildResponse(buildRecoveryTable(primarySizes, replicas), request, channel));
|
||||
} catch (Throwable e) {
|
||||
try {
|
||||
channel.sendResponse(new XContentThrowableRestResponse(request, e));
|
||||
} catch (IOException e2) {
|
||||
logger.error("Unable to send recovery status response", e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
try {
|
||||
channel.sendResponse(new XContentThrowableRestResponse(request, e));
|
||||
} catch (IOException e1) {
|
||||
logger.error("Failed to send failure response", e1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* buildRecoveryTable will build a table of recovery information suitable
|
||||
* for displaying at the command line.
|
||||
* @param primarySizes A Map of {@code index + shardId} strings to store size for all primary shards.
|
||||
* @param recoveringReplicas A Set of {@link ShardStatus} objects for each recovering replica to be displayed.
|
||||
* @return A table containing index, shardId, node, target size, recovered size and percentage for each recovering replica
|
||||
*/
|
||||
public static Table buildRecoveryTable(Map<String, Long> primarySizes, Set<ShardStatus> recoveringReplicas) {
|
||||
Table t = new Table();
|
||||
t.startHeaders().addCell("index")
|
||||
.addCell("shard")
|
||||
.addCell("node")
|
||||
.addCell("target", "text-align:right;")
|
||||
.addCell("recovered", "text-align:right;")
|
||||
.addCell("%", "text-align:right;")
|
||||
.endHeaders();
|
||||
for (ShardStatus status : recoveringReplicas) {
|
||||
String index = status.getShardRouting().getIndex();
|
||||
int id = status.getShardId();
|
||||
long replicaSize = status.getStoreSize().bytes();
|
||||
Long primarySize = primarySizes.get(index + id);
|
||||
t.startRow();
|
||||
t.addCell(index);
|
||||
t.addCell(id);
|
||||
t.addCell(status.getShardRouting().currentNodeId());
|
||||
if (primarySize == null) {
|
||||
t.addCell("NaN");
|
||||
} else {
|
||||
t.addCell(primarySize);
|
||||
}
|
||||
t.addCell(replicaSize);
|
||||
if (primarySize == null) {
|
||||
t.addCell("NaN");
|
||||
} else {
|
||||
t.addCell(String.format("%1.1f%%", 100.0 * (float)replicaSize / primarySize));
|
||||
}
|
||||
t.endRow();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue