Skip to content

Commit 7ff2bb2

Browse files
committed
Add Task 1 - Add Phases level metrics
Signed-off-by: Peng Huo <penghuo@gmail.com>
1 parent 820d757 commit 7ff2bb2

10 files changed

Lines changed: 72 additions & 49 deletions

File tree

core/src/main/java/org/opensearch/sql/calcite/utils/CalciteToolsHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
package org.opensearch.sql.calcite.utils;
2929

3030
import static java.util.Objects.requireNonNull;
31-
import static org.opensearch.sql.monitor.profile.MetricName.OPTIMIZE_TIME;
31+
import static org.opensearch.sql.monitor.profile.MetricName.OPTIMIZE;
3232

3333
import com.google.common.collect.ImmutableList;
3434
import java.lang.reflect.Type;
@@ -343,7 +343,7 @@ public static class OpenSearchRelRunners {
343343
* org.apache.calcite.tools.RelRunners#run(RelNode)}
344344
*/
345345
public static PreparedStatement run(CalcitePlanContext context, RelNode rel) {
346-
ProfileMetric optimizeTime = QueryProfiling.current().getOrCreateMetric(OPTIMIZE_TIME);
346+
ProfileMetric optimizeTime = QueryProfiling.current().getOrCreateMetric(OPTIMIZE);
347347
long startTime = System.nanoTime();
348348
final RelShuttle shuttle =
349349
new RelHomogeneousShuttle() {

core/src/main/java/org/opensearch/sql/executor/QueryService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void executeWithCalcite(
105105
try {
106106
ProfileContext profileContext =
107107
QueryProfiling.activate(QueryContext.isProfileEnabled());
108-
ProfileMetric metric = profileContext.getOrCreateMetric(MetricName.ANALYZE_TIME);
108+
ProfileMetric analyzeMetric = profileContext.getOrCreateMetric(MetricName.ANALYZE);
109109
long analyzeStart = System.nanoTime();
110110
CalcitePlanContext context =
111111
CalcitePlanContext.create(
@@ -114,7 +114,7 @@ public void executeWithCalcite(
114114
relNode = mergeAdjacentFilters(relNode);
115115
RelNode optimized = optimize(relNode, context);
116116
RelNode calcitePlan = convertToCalcitePlan(optimized);
117-
metric.set(System.nanoTime() - analyzeStart);
117+
analyzeMetric.set(System.nanoTime() - analyzeStart);
118118
executionEngine.execute(calcitePlan, context, listener);
119119
} catch (Throwable t) {
120120
if (isCalciteFallbackAllowed(t) && !(t instanceof NonFallbackCalciteException)) {

core/src/main/java/org/opensearch/sql/monitor/profile/DefaultMetricImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
final class DefaultMetricImpl implements ProfileMetric {
1212

1313
private final String name;
14-
private long value = 0;
14+
private final LongAdder value = new LongAdder();
1515

1616
/**
1717
* Construct a metric with the provided name.
@@ -29,17 +29,17 @@ public String name() {
2929

3030
@Override
3131
public long value() {
32-
return value;
32+
return value.sum();
3333
}
3434

3535
@Override
3636
public void add(long delta) {
37-
value += delta;
37+
value.add(delta);
3838
}
3939

4040
@Override
4141
public void set(long value) {
42-
this.value = 0;
43-
add(value);
42+
this.value.reset();
43+
this.value.add(value);
4444
}
4545
}

core/src/main/java/org/opensearch/sql/monitor/profile/MetricName.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77

88
/** Named metrics used by query profiling. */
99
public enum MetricName {
10-
ANALYZE_TIME,
11-
OPTIMIZE_TIME,
12-
OPENSEARCH_TIME,
13-
POST_EXEC_TIME,
14-
FORMAT_TIME
10+
ANALYZE,
11+
OPTIMIZE,
12+
EXECUTE,
13+
FORMAT
1514
}

core/src/main/java/org/opensearch/sql/monitor/profile/QueryProfile.java

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
package org.opensearch.sql.monitor.profile;
77

88
import com.google.gson.annotations.SerializedName;
9+
import java.util.LinkedHashMap;
10+
import java.util.Locale;
911
import java.util.Map;
1012
import java.util.Objects;
1113
import lombok.Getter;
@@ -14,31 +16,50 @@
1416
@Getter
1517
public final class QueryProfile {
1618

17-
/** Total elapsed milliseconds for the profiled query (rounded to two decimals). */
18-
@SerializedName("total_ms")
19-
private final double totalMillis;
19+
private final Summary summary;
2020

21-
/** Immutable metric values keyed by metric name in milliseconds (rounded to two decimals). */
22-
private final Map<String, Double> metrics;
21+
private final Map<String, Phase> phases;
2322

2423
/**
2524
* Create a new query profile snapshot.
2625
*
27-
* @param totalMillis total elapsed milliseconds for the query (rounded to two decimals)
28-
* @param metrics metric values keyed by {@link MetricName}
26+
* @param totalTimeMillis total elapsed milliseconds for the query (rounded to two decimals)
27+
* @param phases metric values keyed by {@link MetricName}
2928
*/
30-
public QueryProfile(double totalMillis, Map<MetricName, Double> metrics) {
31-
this.totalMillis = totalMillis;
32-
this.metrics = buildMetrics(metrics);
29+
public QueryProfile(double totalTimeMillis, Map<MetricName, Double> phases) {
30+
this.summary = new Summary(totalTimeMillis);
31+
this.phases = buildPhases(phases);
3332
}
3433

35-
private Map<String, Double> buildMetrics(Map<MetricName, Double> metrics) {
36-
Objects.requireNonNull(metrics, "metrics");
37-
Map<String, Double> ordered = new java.util.LinkedHashMap<>(metrics.size());
34+
private Map<String, Phase> buildPhases(Map<MetricName, Double> phases) {
35+
Objects.requireNonNull(phases, "phases");
36+
Map<String, Phase> ordered = new LinkedHashMap<>(MetricName.values().length);
3837
for (MetricName metricName : MetricName.values()) {
39-
Double value = metrics.getOrDefault(metricName, 0d);
40-
ordered.put(metricName.name() + "_MS", value);
38+
Double value = phases.getOrDefault(metricName, 0d);
39+
ordered.put(metricName.name().toLowerCase(Locale.ROOT), new Phase(value));
4140
}
4241
return ordered;
4342
}
43+
44+
@Getter
45+
public static final class Summary {
46+
47+
@SerializedName("total_time_ms")
48+
private final double totalTimeMillis;
49+
50+
private Summary(double totalTimeMillis) {
51+
this.totalTimeMillis = totalTimeMillis;
52+
}
53+
}
54+
55+
@Getter
56+
public static final class Phase {
57+
58+
@SerializedName("time_ms")
59+
private final double timeMillis;
60+
61+
private Phase(double timeMillis) {
62+
this.timeMillis = timeMillis;
63+
}
64+
}
4465
}

docs/user/ppl/interfaces/endpoint.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,14 @@ Expected output (trimmed):
172172
```json
173173
{
174174
"profile": {
175-
"total_ms": 25.77,
176-
"metrics": {
177-
"ANALYZE_TIME_MS": 5.77,
178-
"OPTIMIZE_TIME_MS": 13.51,
179-
"OPENSEARCH_TIME_MS": 4.31,
180-
"POST_EXEC_TIME_MS": 0.77,
181-
"FORMAT_TIME_MS": 0.04
175+
"summary": {
176+
"total_time_ms": 25.77
177+
},
178+
"phases": {
179+
"analyze": { "time_ms": 5.77 },
180+
"optimize": { "time_ms": 13.51 },
181+
"execute": { "time_ms": 0.77 },
182+
"format": { "time_ms": 0.04 }
182183
}
183184
}
184185
}

integ-test/src/yamlRestTest/resources/rest-api-spec/test/api/ppl.profile.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@ teardown:
4949
body:
5050
query: 'source=ppl_profile | fields message'
5151
profile: true
52-
- gt: {profile.total_ms: 0.0}
53-
- gt: {profile.metrics.ANALYZE_TIME_MS: 0.0}
54-
- gt: {profile.metrics.OPENSEARCH_TIME_MS: 0.0}
52+
- gt: {profile.summary.total_time_ms: 0.0}
53+
- gt: {profile.phases.analyze.time_ms: 0.0}
54+
- gt: {profile.phases.optimize.time_ms: 0.0}
55+
- gt: {profile.phases.execute.time_ms: 0.0}
56+
- gt: {profile.phases.format.time_ms: 0.0}
5557

5658
---
5759
"Profile ignored for explain api":

opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ private void buildResultSet(
221221
Integer querySizeLimit,
222222
ResponseListener<QueryResponse> listener)
223223
throws SQLException {
224-
ProfileMetric metric = QueryProfiling.current().getOrCreateMetric(MetricName.POST_EXEC_TIME);
225-
long postExecTime = System.nanoTime();
224+
ProfileMetric metric = QueryProfiling.current().getOrCreateMetric(MetricName.EXECUTE);
225+
long execTime = System.nanoTime();
226226
// Get the ResultSet metadata to know about columns
227227
ResultSetMetaData metaData = resultSet.getMetaData();
228228
int columnCount = metaData.getColumnCount();
@@ -267,7 +267,7 @@ private void buildResultSet(
267267
}
268268
Schema schema = new Schema(columns);
269269
QueryResponse response = new QueryResponse(schema, values, null);
270-
metric.set(System.nanoTime() - postExecTime);
270+
metric.add(System.nanoTime() - execTime);
271271
listener.onResponse(response);
272272
}
273273

opensearch/src/main/java/org/opensearch/sql/opensearch/request/OpenSearchQueryRequest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,8 @@ private OpenSearchResponse search(Function<SearchRequest, SearchResponse> search
209209
new OpenSearchResponse(
210210
SearchHits.empty(), exprValueFactory, includes, isCountAggRequest());
211211
} else {
212-
ProfileMetric metric = QueryProfiling.current().getOrCreateMetric(MetricName.OPENSEARCH_TIME);
213-
long engineStartTime = System.nanoTime();
212+
ProfileMetric metric = QueryProfiling.current().getOrCreateMetric(MetricName.EXECUTE);
213+
long executionStartTime = System.nanoTime();
214214
// Set afterKey to request, null for first round (afterKey is null in the beginning).
215215
if (this.sourceBuilder.aggregations() != null) {
216216
this.sourceBuilder.aggregations().getAggregatorFactories().stream()
@@ -243,7 +243,7 @@ private OpenSearchResponse search(Function<SearchRequest, SearchResponse> search
243243
searchDone = true;
244244
}
245245
needClean = searchDone;
246-
metric.set(System.nanoTime() - engineStartTime);
246+
metric.add(System.nanoTime() - executionStartTime);
247247
}
248248
return openSearchResponse;
249249
}
@@ -255,8 +255,8 @@ public OpenSearchResponse searchWithPIT(Function<SearchRequest, SearchResponse>
255255
new OpenSearchResponse(
256256
SearchHits.empty(), exprValueFactory, includes, isCountAggRequest());
257257
} else {
258-
ProfileMetric metric = QueryProfiling.current().getOrCreateMetric(MetricName.OPENSEARCH_TIME);
259-
long engineStartTime = System.nanoTime();
258+
ProfileMetric metric = QueryProfiling.current().getOrCreateMetric(MetricName.EXECUTE);
259+
long executionStartTime = System.nanoTime();
260260
this.sourceBuilder.pointInTimeBuilder(new PointInTimeBuilder(this.pitId));
261261
this.sourceBuilder.timeout(cursorKeepAlive);
262262
// check for search after
@@ -299,7 +299,7 @@ public OpenSearchResponse searchWithPIT(Function<SearchRequest, SearchResponse>
299299
LOG.debug(sourceBuilder);
300300
}
301301
}
302-
metric.add(System.nanoTime() - engineStartTime);
302+
metric.add(System.nanoTime() - executionStartTime);
303303
}
304304
return openSearchResponse;
305305
}

protocol/src/main/java/org/opensearch/sql/protocol/response/format/SimpleJsonResponseFormatter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public SimpleJsonResponseFormatter(Style style) {
4444

4545
@Override
4646
public Object buildJsonObject(QueryResult response) {
47-
ProfileMetric formatMetric = QueryProfiling.current().getOrCreateMetric(MetricName.FORMAT_TIME);
47+
ProfileMetric formatMetric = QueryProfiling.current().getOrCreateMetric(MetricName.FORMAT);
4848
long formatTime = System.nanoTime();
4949

5050
JsonResponse.JsonResponseBuilder json = JsonResponse.builder();

0 commit comments

Comments
 (0)