-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EQL: Add option for returning results from the tail of the stream #64869
Changes from 5 commits
9259e29
a214fdf
5865c12
43ef5ef
faa4897
2209e92
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ public class EqlSearchRequest implements Validatable, ToXContentObject { | |
private QueryBuilder filter = null; | ||
private String timestampField = "@timestamp"; | ||
private String eventCategoryField = "event.category"; | ||
private String resultPosition = "head"; | ||
|
||
private int size = 10; | ||
private int fetchSize = 1000; | ||
|
@@ -57,6 +58,7 @@ public class EqlSearchRequest implements Validatable, ToXContentObject { | |
static final String KEY_SIZE = "size"; | ||
static final String KEY_FETCH_SIZE = "fetch_size"; | ||
static final String KEY_QUERY = "query"; | ||
static final String KEY_RESULT_POSITION = "result_position"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like this name; any suggestions? /cc @jrodewig. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is about oldest or newest sequences first. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is tricky. +1 to Andrei's idea of converting this to a Boolean with a param name of If we decide to keep this as an enum, here are some suggestions in order of preference:
I don't think there is a common phrase that encapsulates both the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Most recent / orientation suggests a different order. When one does tail the results are still ordered ASC but one gets the last X results not the first X. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That makes sense. Rather than forcing another term, it may be simpler and more intuitive to lean into that language:
It seems like the other options are too vague or confusing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forcing "head" or "tail" in the name of the parameter will implicitly assume the user knows about the purpose of head or tail and I like it. So, theoretically, there shouldn't be a concern about some implied ordering the user would assume. In Elasticsearch there are some settings that have technical terms in them and, unless one reads the documentation and knows something more about Elasticsearch, that setting will not make sense. And I think the events selection window (from start or end of the time stream) can be categorized as a more advanced feature that needs a bit more knowledge about EQL. One has to understand which events are selected and that the order in which these events are returned is always ascending. Also, since we assume the user knows about "head" and "tail" we can push this a bit more and add "default" and "pipe" to the name of the parameter and make it boolean: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Booleans are more akin to on/off switches. |
||
static final String KEY_WAIT_FOR_COMPLETION_TIMEOUT = "wait_for_completion_timeout"; | ||
static final String KEY_KEEP_ALIVE = "keep_alive"; | ||
static final String KEY_KEEP_ON_COMPLETION = "keep_on_completion"; | ||
|
@@ -79,6 +81,7 @@ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params par | |
builder.field(KEY_EVENT_CATEGORY_FIELD, eventCategoryField()); | ||
builder.field(KEY_SIZE, size()); | ||
builder.field(KEY_FETCH_SIZE, fetchSize()); | ||
builder.field(KEY_RESULT_POSITION, resultPosition()); | ||
|
||
builder.field(KEY_QUERY, query); | ||
if (waitForCompletionTimeout != null) { | ||
|
@@ -140,6 +143,19 @@ public EqlSearchRequest eventCategoryField(String eventCategoryField) { | |
return this; | ||
} | ||
|
||
public String resultPosition() { | ||
return resultPosition; | ||
} | ||
|
||
public EqlSearchRequest resultPosition(String position) { | ||
if ("head".equals(position) || "tail".equals(position)) { | ||
resultPosition = position; | ||
} else { | ||
throw new IllegalArgumentException("result position needs to be 'head' or 'tail', received '" + position + "'"); | ||
} | ||
return this; | ||
} | ||
|
||
public int size() { | ||
return this.size; | ||
} | ||
|
@@ -211,6 +227,7 @@ public boolean equals(Object o) { | |
EqlSearchRequest that = (EqlSearchRequest) o; | ||
return size == that.size && | ||
fetchSize == that.fetchSize && | ||
resultPosition == that.resultPosition && | ||
Arrays.equals(indices, that.indices) && | ||
Objects.equals(indicesOptions, that.indicesOptions) && | ||
Objects.equals(filter, that.filter) && | ||
|
@@ -237,6 +254,7 @@ public int hashCode() { | |
tiebreakerField, | ||
eventCategoryField, | ||
query, | ||
resultPosition, | ||
waitForCompletionTimeout, | ||
keepAlive, | ||
keepOnCompletion); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
package org.elasticsearch.test.eql; | ||
|
||
import org.apache.http.HttpHost; | ||
import org.apache.http.client.config.RequestConfig; | ||
import org.elasticsearch.client.EqlClient; | ||
import org.elasticsearch.client.Request; | ||
import org.elasticsearch.client.RequestOptions; | ||
|
@@ -118,11 +119,19 @@ protected EqlSearchResponse runQuery(String index, String query) throws Exceptio | |
// some queries return more than 10 results | ||
request.size(50); | ||
request.fetchSize(randomIntBetween(2, 50)); | ||
request.resultPosition(randomBoolean() ? "head" : "tail"); | ||
return runRequest(eqlClient(), request); | ||
} | ||
|
||
protected EqlSearchResponse runRequest(EqlClient eqlClient, EqlSearchRequest request) throws IOException { | ||
return eqlClient.search(request, RequestOptions.DEFAULT); | ||
int timeout = Math.toIntExact(timeout().millis()); | ||
|
||
RequestConfig config = RequestConfig.copy(RequestConfig.DEFAULT) | ||
.setConnectionRequestTimeout(timeout) | ||
.setConnectTimeout(timeout) | ||
.setSocketTimeout(timeout) | ||
.build(); | ||
return eqlClient.search(request, RequestOptions.DEFAULT.toBuilder().setRequestConfig(config).build()); | ||
Comment on lines
126
to
+134
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a timeout setting (which is not straight-forward) to the base test. |
||
} | ||
|
||
protected EqlClient eqlClient() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've kept the existing default for now to not make this PR even bigger or complicate backporting to 7.10.
I'll follow-up with a separate PR for changing the values themselves.