-
Notifications
You must be signed in to change notification settings - Fork 25.5k
Add relevant attributes to shard search latency APM metrics #134798
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
Changes from all commits
7682f37
da04c59
b1413f6
c575028
a96f84f
5371640
0c0081a
77cc2b3
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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 134798 | ||
summary: Add relevant attributes to shard search latency APM metrics | ||
area: Search | ||
type: enhancement | ||
issues: [] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,8 @@ | |
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.elasticsearch.common.regex.Regex; | ||
import org.elasticsearch.common.util.concurrent.EsExecutors; | ||
import org.elasticsearch.core.TimeValue; | ||
import org.elasticsearch.index.query.BoolQueryBuilder; | ||
import org.elasticsearch.index.query.BoostingQueryBuilder; | ||
import org.elasticsearch.index.query.ConstantScoreQueryBuilder; | ||
|
@@ -20,6 +22,7 @@ | |
import org.elasticsearch.index.query.RangeQueryBuilder; | ||
import org.elasticsearch.search.SearchService; | ||
import org.elasticsearch.search.builder.SearchSourceBuilder; | ||
import org.elasticsearch.search.internal.ShardSearchRequest; | ||
import org.elasticsearch.search.sort.FieldSortBuilder; | ||
import org.elasticsearch.search.sort.ScoreSortBuilder; | ||
import org.elasticsearch.search.sort.SortBuilder; | ||
|
@@ -42,17 +45,37 @@ private SearchRequestAttributesExtractor() {} | |
|
||
/** | ||
* Introspects the provided search request and extracts metadata from it about some of its characteristics. | ||
* | ||
*/ | ||
public static Map<String, Object> extractAttributes(SearchRequest searchRequest, String[] localIndices) { | ||
return extractAttributes(searchRequest.source(), searchRequest.scroll(), localIndices); | ||
} | ||
|
||
/** | ||
* Introspects the provided shard search request and extracts metadata from it about some of its characteristics. | ||
*/ | ||
public static Map<String, Object> extractAttributes(ShardSearchRequest shardSearchRequest) { | ||
Map<String, Object> attributes = extractAttributes( | ||
shardSearchRequest.source(), | ||
shardSearchRequest.scroll(), | ||
shardSearchRequest.shardId().getIndexName() | ||
); | ||
boolean isSystem = ((EsExecutors.EsThread) Thread.currentThread()).isSystem(); | ||
attributes.put(SYSTEM_THREAD_ATTRIBUTE_NAME, isSystem); | ||
return attributes; | ||
} | ||
|
||
private static Map<String, Object> extractAttributes( | ||
SearchSourceBuilder searchSourceBuilder, | ||
TimeValue scroll, | ||
String... localIndices | ||
) { | ||
String target = extractIndices(localIndices); | ||
|
||
String pitOrScroll = null; | ||
if (searchRequest.scroll() != null) { | ||
if (scroll != null) { | ||
pitOrScroll = SCROLL; | ||
} | ||
|
||
SearchSourceBuilder searchSourceBuilder = searchRequest.source(); | ||
if (searchSourceBuilder == null) { | ||
return buildAttributesMap(target, ScoreSortBuilder.NAME, HITS_ONLY, false, false, false, pitOrScroll); | ||
} | ||
|
@@ -144,7 +167,7 @@ private static final class QueryMetadataBuilder { | |
private static final String TARGET_USER = "user"; | ||
private static final String ERROR = "error"; | ||
|
||
static String extractIndices(String[] indices) { | ||
static String extractIndices(String... indices) { | ||
try { | ||
// Note that indices are expected to be resolved, meaning wildcards are not handled on purpose | ||
// If indices resolve to data streams, the name of the data stream is returned as opposed to its backing indices | ||
|
@@ -213,6 +236,7 @@ static String extractPrimarySort(SortBuilder<?> primarySortBuilder) { | |
private static final String PIT = "pit"; | ||
private static final String SCROLL = "scroll"; | ||
|
||
public static final String SYSTEM_THREAD_ATTRIBUTE_NAME = "system_thread"; | ||
public static final Map<String, Object> SEARCH_SCROLL_ATTRIBUTES = Map.of(QUERY_TYPE_ATTRIBUTE, SCROLL); | ||
|
||
static String extractQueryType(SearchSourceBuilder searchSourceBuilder) { | ||
|
@@ -266,8 +290,18 @@ private static void introspectQueryBuilder(QueryBuilder queryBuilder, QueryMetad | |
break; | ||
case RangeQueryBuilder range: | ||
switch (range.fieldName()) { | ||
case TIMESTAMP -> queryMetadataBuilder.rangeOnTimestamp = true; | ||
case EVENT_INGESTED -> queryMetadataBuilder.rangeOnEventIngested = true; | ||
// don't track unbounded ranges, they translate to either match_none if the field does not exist | ||
// or match_all if the field is mapped | ||
case TIMESTAMP -> { | ||
if (range.to() != null || range.from() != null) { | ||
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 something I discovered as part of working on this chance: rewrite for range queries is a bit funky (I plan on fixing that as a follow-up). A range query may rewrite to one without bounds, if all data is within the range. In that case, it is equivalent to a match_all hence I don't report it as a range. I decided to rather report only "true" range queries at the shard level. |
||
queryMetadataBuilder.rangeOnTimestamp = true; | ||
} | ||
} | ||
case EVENT_INGESTED -> { | ||
if (range.to() != null || range.from() != null) { | ||
queryMetadataBuilder.rangeOnEventIngested = true; | ||
} | ||
} | ||
} | ||
break; | ||
case KnnVectorQueryBuilder knn: | ||
|
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.
The isSystem attribute I moved here from the ShardSearchPhaseAPMMetrics class.