Skip to content

Commit f97cb0e

Browse files
committed
Add took time to request nodes stats
Signed-off-by: David Zane <davizane@amazon.com>
1 parent eb306d2 commit f97cb0e

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

server/src/main/java/org/opensearch/action/search/SearchRequestStats.java

+31
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
@PublicApi(since = "2.11.0")
2828
public final class SearchRequestStats extends SearchRequestOperationsListener {
2929
Map<SearchPhaseName, StatsHolder> phaseStatsMap = new EnumMap<>(SearchPhaseName.class);
30+
StatsHolder tookStatsHolder;
3031

3132
public static final String SEARCH_REQUEST_STATS_ENABLED_KEY = "search.request_stats_enabled";
3233
public static final Setting<Boolean> SEARCH_REQUEST_STATS_ENABLED = Setting.boolSetting(
@@ -40,6 +41,7 @@ public final class SearchRequestStats extends SearchRequestOperationsListener {
4041
public SearchRequestStats(ClusterSettings clusterSettings) {
4142
this.setEnabled(clusterSettings.get(SEARCH_REQUEST_STATS_ENABLED));
4243
clusterSettings.addSettingsUpdateConsumer(SEARCH_REQUEST_STATS_ENABLED, this::setEnabled);
44+
tookStatsHolder = new StatsHolder();
4345
for (SearchPhaseName searchPhaseName : SearchPhaseName.values()) {
4446
phaseStatsMap.put(searchPhaseName, new StatsHolder());
4547
}
@@ -57,6 +59,18 @@ public long getPhaseMetric(SearchPhaseName searchPhaseName) {
5759
return phaseStatsMap.get(searchPhaseName).timing.sum();
5860
}
5961

62+
public long getTookCurrent() {
63+
return tookStatsHolder.current.count();
64+
}
65+
66+
public long getTookTotal() {
67+
return tookStatsHolder.total.count();
68+
}
69+
70+
public long getTookMetric() {
71+
return tookStatsHolder.timing.sum();
72+
}
73+
6074
@Override
6175
protected void onPhaseStart(SearchPhaseContext context) {
6276
phaseStatsMap.get(context.getCurrentPhase().getSearchPhaseName()).current.inc();
@@ -75,6 +89,23 @@ protected void onPhaseFailure(SearchPhaseContext context, Throwable cause) {
7589
phaseStatsMap.get(context.getCurrentPhase().getSearchPhaseName()).current.dec();
7690
}
7791

92+
@Override
93+
protected void onRequestStart(SearchRequestContext searchRequestContext) {
94+
tookStatsHolder.current.inc();
95+
}
96+
97+
@Override
98+
protected void onRequestEnd(SearchPhaseContext context, SearchRequestContext searchRequestContext) {
99+
tookStatsHolder.current.dec();
100+
tookStatsHolder.total.inc();
101+
tookStatsHolder.timing.inc(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - searchRequestContext.getAbsoluteStartNanos()));
102+
}
103+
104+
@Override
105+
protected void onRequestFailure(SearchPhaseContext context, SearchRequestContext searchRequestContext) {
106+
tookStatsHolder.current.dec();
107+
}
108+
78109
/**
79110
* Holder of statistics values
80111
*

server/src/main/java/org/opensearch/index/search/stats/SearchStats.java

+23-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public void writeTo(StreamOutput out) throws IOException {
110110
}
111111

112112
/**
113-
* Holds requests stats for different phases.
113+
* Holds all requests stats.
114114
*
115115
* @opensearch.api
116116
*/
@@ -124,6 +124,7 @@ public Map<String, PhaseStatsLongHolder> getRequestStatsHolder() {
124124
}
125125

126126
RequestStatsLongHolder() {
127+
requestStatsHolder.put(Fields.TOOK, new PhaseStatsLongHolder());
127128
for (SearchPhaseName searchPhaseName : SearchPhaseName.values()) {
128129
requestStatsHolder.put(searchPhaseName.getName(), new PhaseStatsLongHolder());
129130
}
@@ -512,6 +513,15 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
512513
if (requestStatsLongHolder != null) {
513514
builder.startObject(Fields.REQUEST);
514515

516+
PhaseStatsLongHolder tookStatsLongHolder = requestStatsLongHolder.requestStatsHolder.get(Fields.TOOK);
517+
if (tookStatsLongHolder != null) {
518+
builder.startObject(Fields.TOOK);
519+
builder.humanReadableField(Fields.TIME_IN_MILLIS, Fields.TIME, new TimeValue(tookStatsLongHolder.timeInMillis));
520+
builder.field(Fields.CURRENT, tookStatsLongHolder.current);
521+
builder.field(Fields.TOTAL, tookStatsLongHolder.total);
522+
builder.endObject();
523+
}
524+
515525
for (SearchPhaseName searchPhaseName : SearchPhaseName.values()) {
516526
PhaseStatsLongHolder statsLongHolder = requestStatsLongHolder.requestStatsHolder.get(searchPhaseName.getName());
517527
if (statsLongHolder == null) {
@@ -545,6 +555,17 @@ public void setSearchRequestStats(SearchRequestStats searchRequestStats) {
545555
totalStats.requestStatsLongHolder = new RequestStatsLongHolder();
546556
}
547557

558+
// Set took stats
559+
totalStats.requestStatsLongHolder.requestStatsHolder.put(
560+
Fields.TOOK,
561+
new PhaseStatsLongHolder(
562+
searchRequestStats.getTookCurrent(),
563+
searchRequestStats.getTookTotal(),
564+
searchRequestStats.getTookMetric()
565+
)
566+
);
567+
568+
// Set phase stats
548569
for (SearchPhaseName searchPhaseName : SearchPhaseName.values()) {
549570
totalStats.requestStatsLongHolder.requestStatsHolder.put(
550571
searchPhaseName.getName(),
@@ -678,6 +699,7 @@ static final class Fields {
678699
static final String CURRENT = "current";
679700
static final String TOTAL = "total";
680701
static final String SEARCH_IDLE_REACTIVATE_COUNT_TOTAL = "search_idle_reactivate_count_total";
702+
static final String TOOK = "took";
681703

682704
}
683705

server/src/test/java/org/opensearch/action/search/SearchRequestStatsTests.java

+35
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,41 @@
2525
import static org.mockito.Mockito.when;
2626

2727
public class SearchRequestStatsTests extends OpenSearchTestCase {
28+
public void testSearchRequestStats_OnRequestFailure() {
29+
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
30+
SearchRequestStats testRequestStats = new SearchRequestStats(clusterSettings);
31+
SearchPhaseContext mockSearchPhaseContext = mock(SearchPhaseContext.class);
32+
SearchRequestContext mockSearchRequestContext = mock(SearchRequestContext.class);
33+
34+
testRequestStats.onRequestStart(mockSearchRequestContext);
35+
assertEquals(1, testRequestStats.getTookCurrent());
36+
testRequestStats.onRequestFailure(mockSearchPhaseContext, mockSearchRequestContext);
37+
assertEquals(0, testRequestStats.getTookCurrent());
38+
assertEquals(0, testRequestStats.getTookTotal());
39+
}
40+
41+
public void testSearchRequestStats_OnRequestEnd() {
42+
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
43+
SearchRequestStats testRequestStats = new SearchRequestStats(clusterSettings);
44+
SearchPhaseContext mockSearchPhaseContext = mock(SearchPhaseContext.class);
45+
SearchRequestContext mockSearchRequestContext = mock(SearchRequestContext.class);
46+
47+
// Start request
48+
testRequestStats.onRequestStart(mockSearchRequestContext);
49+
assertEquals(1, testRequestStats.getTookCurrent());
50+
51+
// Mock start time
52+
long tookTimeInMillis = randomIntBetween(1, 10);
53+
long startTimeInNanos = System.nanoTime() - TimeUnit.MILLISECONDS.toNanos(tookTimeInMillis);
54+
when(mockSearchRequestContext.getAbsoluteStartNanos()).thenReturn(startTimeInNanos);
55+
56+
// End request
57+
testRequestStats.onRequestEnd(mockSearchPhaseContext, mockSearchRequestContext);
58+
assertEquals(0, testRequestStats.getTookCurrent());
59+
assertEquals(1, testRequestStats.getTookTotal());
60+
assertThat(testRequestStats.getTookMetric(), greaterThanOrEqualTo(tookTimeInMillis));
61+
}
62+
2863
public void testSearchRequestPhaseFailure() {
2964
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
3065
SearchRequestStats testRequestStats = new SearchRequestStats(clusterSettings);

0 commit comments

Comments
 (0)