Skip to content

Commit c7b69a0

Browse files
committed
Add search task descriptions
Since we added ability to cancel searches it would be nice to see which searches we are actually cancelling.
1 parent 6940b2b commit c7b69a0

File tree

8 files changed

+126
-3
lines changed

8 files changed

+126
-3
lines changed

core/src/main/java/org/elasticsearch/action/search/SearchRequest.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@
2929
import org.elasticsearch.common.io.stream.StreamInput;
3030
import org.elasticsearch.common.io.stream.StreamOutput;
3131
import org.elasticsearch.common.unit.TimeValue;
32+
import org.elasticsearch.common.xcontent.ToXContent;
3233
import org.elasticsearch.search.Scroll;
3334
import org.elasticsearch.search.builder.SearchSourceBuilder;
3435
import org.elasticsearch.tasks.Task;
3536
import org.elasticsearch.tasks.TaskId;
3637

3738
import java.io.IOException;
3839
import java.util.Arrays;
40+
import java.util.Collections;
3941
import java.util.Objects;
4042

4143
/**
@@ -45,12 +47,15 @@
4547
* Note, the search {@link #source(org.elasticsearch.search.builder.SearchSourceBuilder)}
4648
* is required. The search source is the different search options, including aggregations and such.
4749
* </p>
50+
*
4851
* @see org.elasticsearch.client.Requests#searchRequest(String...)
4952
* @see org.elasticsearch.client.Client#search(SearchRequest)
5053
* @see SearchResponse
5154
*/
5255
public final class SearchRequest extends ActionRequest implements IndicesRequest.Replaceable {
5356

57+
private static final ToXContent.Params FORMAT_PARAMS = new ToXContent.MapParams(Collections.singletonMap("pretty", "false"));
58+
5459
private SearchType searchType = SearchType.DEFAULT;
5560

5661
private String[] indices = Strings.EMPTY_ARRAY;
@@ -279,7 +284,26 @@ public boolean isSuggestOnly() {
279284

280285
@Override
281286
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
282-
return new SearchTask(id, type, action, getDescription(), parentTaskId);
287+
// generating description in a lazy way since source can be quite big
288+
return new SearchTask(id, type, action, null, parentTaskId) {
289+
@Override
290+
public String getDescription() {
291+
StringBuilder sb = new StringBuilder();
292+
sb.append("indices[");
293+
Strings.arrayToDelimitedString(indices, ",", sb);
294+
sb.append("], ");
295+
sb.append("types[");
296+
Strings.arrayToDelimitedString(types, ",", sb);
297+
sb.append("], ");
298+
sb.append("search_type[").append(searchType).append("], ");
299+
if (source != null) {
300+
sb.append("source[").append(source.toString(FORMAT_PARAMS)).append("]");
301+
} else {
302+
sb.append("source[]");
303+
}
304+
return sb.toString();
305+
}
306+
};
283307
}
284308

285309
@Override

core/src/main/java/org/elasticsearch/action/search/SearchScrollRequest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,10 @@ public String toString() {
139139
", scroll=" + scroll +
140140
'}';
141141
}
142+
143+
@Override
144+
public String getDescription() {
145+
return "scrollId[" + scrollId + "], scroll[" + scroll + "]";
146+
}
147+
142148
}

core/src/main/java/org/elasticsearch/action/support/ToXContentToBytes.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,16 @@ public final BytesReference buildAsBytes(XContentType contentType) {
6969

7070
@Override
7171
public final String toString() {
72+
return toString(EMPTY_PARAMS);
73+
}
74+
75+
public final String toString(Params params) {
7276
try {
7377
XContentBuilder builder = XContentFactory.jsonBuilder();
74-
builder.prettyPrint();
75-
toXContent(builder, EMPTY_PARAMS);
78+
if (params.paramAsBoolean("pretty", true)) {
79+
builder.prettyPrint();
80+
}
81+
toXContent(builder, params);
7682
return builder.string();
7783
} catch (Exception e) {
7884
// So we have a stack trace logged somewhere

core/src/main/java/org/elasticsearch/search/fetch/ShardFetchRequest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,10 @@ public void writeTo(StreamOutput out) throws IOException {
114114
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
115115
return new SearchTask(id, type, action, getDescription(), parentTaskId);
116116
}
117+
118+
@Override
119+
public String getDescription() {
120+
return "id[" + id + "], size[" + size + "], lastEmittedDoc[" + lastEmittedDoc + "]";
121+
}
122+
117123
}

core/src/main/java/org/elasticsearch/search/internal/InternalScrollSearchRequest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,10 @@ public void writeTo(StreamOutput out) throws IOException {
7575
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
7676
return new SearchTask(id, type, action, getDescription(), parentTaskId);
7777
}
78+
79+
@Override
80+
public String getDescription() {
81+
return "id[" + id + "], scroll[" + scroll + "]";
82+
}
83+
7884
}

core/src/main/java/org/elasticsearch/search/internal/ShardSearchTransportRequest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,10 @@ public void rewrite(QueryShardContext context) throws IOException {
166166
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
167167
return new SearchTask(id, type, action, getDescription(), parentTaskId);
168168
}
169+
170+
@Override
171+
public String getDescription() {
172+
// Shard id is enough here, the request itself can be found by looking at the parent task description
173+
return "shardId[" + shardSearchLocalRequest.shardId() + "]";
174+
}
169175
}

core/src/main/java/org/elasticsearch/search/query/QuerySearchRequest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.elasticsearch.action.search.SearchRequest;
2525
import org.elasticsearch.action.search.SearchTask;
2626
import org.elasticsearch.action.support.IndicesOptions;
27+
import org.elasticsearch.common.Strings;
2728
import org.elasticsearch.common.io.stream.StreamInput;
2829
import org.elasticsearch.common.io.stream.StreamOutput;
2930
import org.elasticsearch.search.dfs.AggregatedDfs;
@@ -90,4 +91,16 @@ public void writeTo(StreamOutput out) throws IOException {
9091
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
9192
return new SearchTask(id, type, action, getDescription(), parentTaskId);
9293
}
94+
95+
public String getDescription() {
96+
StringBuilder sb = new StringBuilder();
97+
sb.append("id[");
98+
sb.append(id);
99+
sb.append("], ");
100+
sb.append("indices[");
101+
Strings.arrayToDelimitedString(originalIndices.indices(), ",", sb);
102+
sb.append("]");
103+
return sb.toString();
104+
}
105+
93106
}

core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TasksIT.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,17 @@
3838
import org.elasticsearch.action.get.GetResponse;
3939
import org.elasticsearch.action.index.IndexAction;
4040
import org.elasticsearch.action.index.IndexResponse;
41+
import org.elasticsearch.action.search.SearchAction;
4142
import org.elasticsearch.action.search.SearchResponse;
43+
import org.elasticsearch.action.search.SearchTransportService;
44+
import org.elasticsearch.action.support.WriteRequest;
4245
import org.elasticsearch.action.support.replication.ReplicationResponse;
4346
import org.elasticsearch.action.support.replication.TransportReplicationActionTests;
4447
import org.elasticsearch.cluster.node.DiscoveryNode;
4548
import org.elasticsearch.cluster.service.ClusterService;
4649
import org.elasticsearch.common.Strings;
4750
import org.elasticsearch.common.collect.Tuple;
51+
import org.elasticsearch.common.regex.Regex;
4852
import org.elasticsearch.common.settings.Settings;
4953
import org.elasticsearch.index.query.QueryBuilders;
5054
import org.elasticsearch.plugins.Plugin;
@@ -82,14 +86,22 @@
8286
import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds;
8387
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
8488
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
89+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
8590
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows;
8691
import static org.hamcrest.Matchers.allOf;
92+
import static org.hamcrest.Matchers.contains;
93+
import static org.hamcrest.Matchers.containsString;
8794
import static org.hamcrest.Matchers.empty;
8895
import static org.hamcrest.Matchers.emptyCollectionOf;
96+
import static org.hamcrest.Matchers.endsWith;
97+
import static org.hamcrest.Matchers.equalTo;
98+
import static org.hamcrest.Matchers.greaterThan;
8999
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
90100
import static org.hamcrest.Matchers.hasSize;
91101
import static org.hamcrest.Matchers.lessThanOrEqualTo;
92102
import static org.hamcrest.Matchers.not;
103+
import static org.hamcrest.Matchers.notNullValue;
104+
import static org.hamcrest.Matchers.startsWith;
93105

94106
/**
95107
* Integration tests for task management API
@@ -329,6 +341,50 @@ public void testTransportBulkTasks() {
329341
assertParentTask(findEvents(BulkAction.NAME + "[s][r]", Tuple::v1), shardTask);
330342
}
331343

344+
345+
public void testSearchTaskDescriptions() {
346+
registerTaskManageListeners(SearchAction.NAME); // main task
347+
registerTaskManageListeners(SearchAction.NAME + "[*]"); // shard task
348+
createIndex("test");
349+
ensureGreen("test"); // Make sure all shards are allocated to catch replication tasks
350+
client().prepareIndex("test", "doc", "test_id").setSource("{\"foo\": \"bar\"}")
351+
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).get();
352+
353+
assertSearchResponse(client().prepareSearch("test").setTypes("doc").setQuery(QueryBuilders.matchAllQuery()).get());
354+
355+
// the search operation should produce one main task
356+
List<TaskInfo> mainTask = findEvents(SearchAction.NAME, Tuple::v1);
357+
assertEquals(1, mainTask.size());
358+
assertThat(mainTask.get(0).getDescription(), startsWith("indices[test], types[doc], search_type["));
359+
assertThat(mainTask.get(0).getDescription(), containsString("\"query\":{\"match_all\""));
360+
361+
// check that if we have any shard-level requests they all have non-zero length description
362+
List<TaskInfo> shardTasks = findEvents(SearchAction.NAME + "[*]", Tuple::v1);
363+
for (TaskInfo taskInfo : shardTasks) {
364+
assertThat(taskInfo.getParentTaskId(), notNullValue());
365+
assertEquals(mainTask.get(0).getTaskId(), taskInfo.getParentTaskId());
366+
switch (taskInfo.getAction()) {
367+
case SearchTransportService.QUERY_ACTION_NAME:
368+
case SearchTransportService.QUERY_FETCH_ACTION_NAME:
369+
case SearchTransportService.DFS_ACTION_NAME:
370+
assertTrue(taskInfo.getDescription(), Regex.simpleMatch("shardId[[test][*]]", taskInfo.getDescription()));
371+
break;
372+
case SearchTransportService.QUERY_ID_ACTION_NAME:
373+
assertTrue(taskInfo.getDescription(), Regex.simpleMatch("id[*], indices[test]", taskInfo.getDescription()));
374+
break;
375+
case SearchTransportService.FETCH_ID_ACTION_NAME:
376+
assertTrue(taskInfo.getDescription(), Regex.simpleMatch("id[*], size[1], lastEmittedDoc[null]",
377+
taskInfo.getDescription()));
378+
break;
379+
default:
380+
fail("Unexpected action [" + taskInfo.getAction() + "] with description [" + taskInfo.getDescription() + "]");
381+
}
382+
// assert that all task descriptions have non-zero length
383+
assertThat(taskInfo.getDescription().length(), greaterThan(0));
384+
}
385+
386+
}
387+
332388
/**
333389
* Very basic "is it plugged in" style test that indexes a document and makes sure that you can fetch the status of the process. The
334390
* goal here is to verify that the large moving parts that make fetching task status work fit together rather than to verify any

0 commit comments

Comments
 (0)