Skip to content

Commit

Permalink
Top N Queries Implementation and Basic Query Insight Framework
Browse files Browse the repository at this point in the history
Signed-off-by: Chenyang Ji <[email protected]>
  • Loading branch information
ansjcy committed Dec 7, 2023
1 parent 69cc2a1 commit 1f3092e
Show file tree
Hide file tree
Showing 29 changed files with 2,011 additions and 1 deletion.
9 changes: 9 additions & 0 deletions server/src/main/java/org/opensearch/action/ActionModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
import org.opensearch.action.admin.cluster.decommission.awareness.put.TransportDecommissionAction;
import org.opensearch.action.admin.cluster.health.ClusterHealthAction;
import org.opensearch.action.admin.cluster.health.TransportClusterHealthAction;
import org.opensearch.action.admin.cluster.insights.top_queries.TopQueriesAction;
import org.opensearch.action.admin.cluster.insights.top_queries.TransportTopQueriesAction;
import org.opensearch.action.admin.cluster.node.hotthreads.NodesHotThreadsAction;
import org.opensearch.action.admin.cluster.node.hotthreads.TransportNodesHotThreadsAction;
import org.opensearch.action.admin.cluster.node.info.NodesInfoAction;
Expand Down Expand Up @@ -359,6 +361,7 @@
import org.opensearch.rest.action.admin.cluster.RestRestoreRemoteStoreAction;
import org.opensearch.rest.action.admin.cluster.RestRestoreSnapshotAction;
import org.opensearch.rest.action.admin.cluster.RestSnapshotsStatusAction;
import org.opensearch.rest.action.admin.cluster.RestTopQueriesAction;
import org.opensearch.rest.action.admin.cluster.RestVerifyRepositoryAction;
import org.opensearch.rest.action.admin.cluster.dangling.RestDeleteDanglingIndexAction;
import org.opensearch.rest.action.admin.cluster.dangling.RestImportDanglingIndexAction;
Expand Down Expand Up @@ -762,6 +765,9 @@ public <Request extends ActionRequest, Response extends ActionResponse> void reg
actions.register(GetSearchPipelineAction.INSTANCE, GetSearchPipelineTransportAction.class);
actions.register(DeleteSearchPipelineAction.INSTANCE, DeleteSearchPipelineTransportAction.class);

// Query Insight Actions
actions.register(TopQueriesAction.INSTANCE, TransportTopQueriesAction.class);

return unmodifiableMap(actions.getRegistry());
}

Expand Down Expand Up @@ -974,6 +980,9 @@ public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster) {
registerHandler.accept(new RestGetDecommissionStateAction());
registerHandler.accept(new RestRemoteStoreStatsAction());
registerHandler.accept(new RestRestoreRemoteStoreAction());

// Query insights API
registerHandler.accept(new RestTopQueriesAction());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

/** insights transport handlers. */
package org.opensearch.action.admin.cluster.insights;
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/


package org.opensearch.action.admin.cluster.insights.top_queries;

import org.opensearch.action.search.SearchQueryLatencyRecord;
import org.opensearch.action.support.nodes.BaseNodeResponse;
import org.opensearch.cluster.node.DiscoveryNode;
import org.opensearch.common.Nullable;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;
import org.opensearch.core.xcontent.ToXContent;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.List;

/**
* Top Queries by resource usage / latency on a node
* <p>
* Mainly used in the top N queries node response workflow.
*
* @opensearch.internal
*/
public class TopQueries extends BaseNodeResponse implements ToXContentObject {
/** The store to keep the top N queries with latency records */
@Nullable
private final List<SearchQueryLatencyRecord> latencyRecords;

public TopQueries(StreamInput in) throws IOException {
super(in);
latencyRecords = in.readList(SearchQueryLatencyRecord::new);
}

public TopQueries(
DiscoveryNode node,
@Nullable List<SearchQueryLatencyRecord> latencyRecords
) {
super(node);
this.latencyRecords = latencyRecords;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
if (latencyRecords != null) {
for (SearchQueryLatencyRecord record : latencyRecords) {
record.toXContent(builder, params);
}
}
return builder;
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
if (latencyRecords != null) {
out.writeList(latencyRecords);
}
}

/**
* Get all latency records
*
* @return the latency records in this node response
*/
public List<SearchQueryLatencyRecord> getLatencyRecords() {
return latencyRecords;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/


package org.opensearch.action.admin.cluster.insights.top_queries;

import org.opensearch.action.ActionType;

/**
* Transport action for cluster/node level top queries information.
*
* @opensearch.internal
*/
public class TopQueriesAction extends ActionType<TopQueriesResponse> {

public static final TopQueriesAction INSTANCE = new TopQueriesAction();
public static final String NAME = "cluster:monitor/insights/top_queries";

private TopQueriesAction() {
super(NAME, TopQueriesResponse::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/


package org.opensearch.action.admin.cluster.insights.top_queries;

import org.opensearch.action.support.nodes.BaseNodesRequest;
import org.opensearch.common.annotation.PublicApi;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
* A request to get cluster/node level top queries information.
*
* @opensearch.api
*/
@PublicApi(since = "1.0.0")
public class TopQueriesRequest extends BaseNodesRequest<TopQueriesRequest> {

Metric metricType = Metric.LATENCY;

/**
* Create a new TopQueriesRequest from a {@link StreamInput} object.
*
* @param in A stream input object.
* @throws IOException if the stream cannot be deserialized.
*/
public TopQueriesRequest(StreamInput in) throws IOException {
super(in);
setMetricType(in.readString());
}

/**
* Get top queries from nodes based on the nodes ids specified.
* If none are passed, cluster level top queries will be returned.
*/
public TopQueriesRequest(String... nodesIds) {
super(nodesIds);
}

/**
* Get the type of requested metrics
*/
public Metric getMetricType() {
return metricType;
}

/**
* Set the type of requested metrics
*/
public TopQueriesRequest setMetricType(String metricType) {
metricType = metricType.toUpperCase();
if (Metric.allMetrics().contains(metricType) == false) {
throw new IllegalStateException("Invalid metric used in top queries request: " + metricType);
}
this.metricType = Metric.valueOf(metricType);
return this;
}


@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeString(metricType.metricName());
}

/**
* ALl supported metrics for top queries
*/
public enum Metric {
LATENCY("LATENCY");

private final String metricName;

Metric(String name) {
this.metricName = name;
}

public String metricName() {
return this.metricName;
}

public static Set<String> allMetrics() {
return Arrays.stream(values()).map(Metric::metricName).collect(Collectors.toSet());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/


package org.opensearch.action.admin.cluster.insights.top_queries;

import org.opensearch.action.support.nodes.NodesOperationRequestBuilder;
import org.opensearch.client.OpenSearchClient;
import org.opensearch.common.annotation.PublicApi;

/**
* Builder class for requesting cluster/node level top queries information.
*
* @opensearch.api
*/
@PublicApi(since = "1.0.0")
public class TopQueriesRequestBuilder extends NodesOperationRequestBuilder<TopQueriesRequest, TopQueriesResponse, TopQueriesRequestBuilder> {

public TopQueriesRequestBuilder(OpenSearchClient client, TopQueriesAction action) {
super(client, action, new TopQueriesRequest());
}

/**
* set metric type for the request
*
* @param metric Name of metric as a string.
* @return This, for request chaining.
*/
public TopQueriesRequestBuilder setMetricType(String metric) {
request.setMetricType(metric);
return this;
}
}
Loading

0 comments on commit 1f3092e

Please sign in to comment.