Skip to content

Commit 08c0a9c

Browse files
[Profiling] Add status API (elastic#96272)
With this commit we add a new REST API to the profiling plugin that allows to retrieve its current status. * Update docs/changelog/96272.yaml * Enhance response structure
1 parent 9cee43b commit 08c0a9c

File tree

5 files changed

+223
-6
lines changed

5 files changed

+223
-6
lines changed

docs/changelog/96272.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 96272
2+
summary: "[Profiling] Add status API"
3+
area: Application
4+
type: enhancement
5+
issues: []
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.profiler;
9+
10+
import org.elasticsearch.action.ActionRequestValidationException;
11+
import org.elasticsearch.action.ActionResponse;
12+
import org.elasticsearch.action.ActionType;
13+
import org.elasticsearch.action.support.master.AcknowledgedRequest;
14+
import org.elasticsearch.common.Strings;
15+
import org.elasticsearch.common.io.stream.StreamInput;
16+
import org.elasticsearch.common.io.stream.StreamOutput;
17+
import org.elasticsearch.xcontent.ToXContentObject;
18+
import org.elasticsearch.xcontent.XContentBuilder;
19+
20+
import java.io.IOException;
21+
import java.util.Objects;
22+
23+
public class GetStatusAction extends ActionType<GetStatusAction.Response> {
24+
public static final GetStatusAction INSTANCE = new GetStatusAction();
25+
public static final String NAME = "cluster:monitor/profiling/status/get";
26+
27+
protected GetStatusAction() {
28+
super(NAME, GetStatusAction.Response::new);
29+
}
30+
31+
public static class Response extends ActionResponse implements ToXContentObject {
32+
33+
private boolean profilingEnabled;
34+
private boolean resourceManagementEnabled;
35+
private boolean resourcesCreated;
36+
37+
public Response(StreamInput in) throws IOException {
38+
super(in);
39+
profilingEnabled = in.readBoolean();
40+
resourceManagementEnabled = in.readBoolean();
41+
resourcesCreated = in.readBoolean();
42+
}
43+
44+
public Response(boolean profilingEnabled, boolean resourceManagementEnabled, boolean resourcesCreated) {
45+
this.profilingEnabled = profilingEnabled;
46+
this.resourceManagementEnabled = resourceManagementEnabled;
47+
this.resourcesCreated = resourcesCreated;
48+
}
49+
50+
@Override
51+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
52+
builder.startObject();
53+
builder.startObject("profiling").field("enabled", profilingEnabled).endObject();
54+
builder.startObject("resource_management").field("enabled", resourceManagementEnabled).endObject();
55+
builder.startObject("resources").field("created", resourcesCreated).endObject();
56+
builder.endObject();
57+
return builder;
58+
}
59+
60+
@Override
61+
public void writeTo(StreamOutput out) throws IOException {
62+
out.writeBoolean(profilingEnabled);
63+
out.writeBoolean(resourceManagementEnabled);
64+
out.writeBoolean(resourcesCreated);
65+
}
66+
67+
@Override
68+
public boolean equals(Object o) {
69+
if (this == o) return true;
70+
if (o == null || getClass() != o.getClass()) return false;
71+
Response response = (Response) o;
72+
return profilingEnabled == response.profilingEnabled
73+
&& resourceManagementEnabled == response.resourceManagementEnabled
74+
&& resourcesCreated == response.resourcesCreated;
75+
}
76+
77+
@Override
78+
public int hashCode() {
79+
return Objects.hash(profilingEnabled, resourceManagementEnabled, resourcesCreated);
80+
}
81+
82+
@Override
83+
public String toString() {
84+
return Strings.toString(this, true, true);
85+
}
86+
87+
}
88+
89+
public static class Request extends AcknowledgedRequest<GetStatusAction.Request> {
90+
91+
public Request(StreamInput in) throws IOException {
92+
super(in);
93+
}
94+
95+
public Request() {}
96+
97+
@Override
98+
public ActionRequestValidationException validate() {
99+
return null;
100+
}
101+
102+
@Override
103+
public void writeTo(StreamOutput out) throws IOException {
104+
super.writeTo(out);
105+
}
106+
}
107+
}

x-pack/plugin/profiler/src/main/java/org/elasticsearch/xpack/profiler/ProfilingPlugin.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,12 @@
4040
import org.elasticsearch.xcontent.NamedXContentRegistry;
4141
import org.elasticsearch.xpack.core.XPackSettings;
4242

43+
import java.util.ArrayList;
4344
import java.util.Collection;
4445
import java.util.Collections;
4546
import java.util.List;
4647
import java.util.function.Supplier;
4748

48-
import static java.util.Collections.singletonList;
49-
5049
public class ProfilingPlugin extends Plugin implements ActionPlugin {
5150
private static final Logger logger = LogManager.getLogger(ProfilingPlugin.class);
5251
public static final Setting<Boolean> PROFILING_TEMPLATES_ENABLED = Setting.boolSetting(
@@ -117,11 +116,12 @@ public List<RestHandler> getRestHandlers(
117116
final IndexNameExpressionResolver indexNameExpressionResolver,
118117
final Supplier<DiscoveryNodes> nodesInCluster
119118
) {
119+
List<RestHandler> handlers = new ArrayList<>();
120+
handlers.add(new RestGetStatusAction());
120121
if (enabled) {
121-
return singletonList(new RestGetProfilingAction());
122-
} else {
123-
return Collections.emptyList();
122+
handlers.add(new RestGetProfilingAction());
124123
}
124+
return Collections.unmodifiableList(handlers);
125125
}
126126

127127
@Override
@@ -150,7 +150,10 @@ public static ExecutorBuilder<?> responseExecutorBuilder() {
150150

151151
@Override
152152
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
153-
return List.of(new ActionHandler<>(GetProfilingAction.INSTANCE, TransportGetProfilingAction.class));
153+
return List.of(
154+
new ActionHandler<>(GetProfilingAction.INSTANCE, TransportGetProfilingAction.class),
155+
new ActionHandler<>(GetStatusAction.INSTANCE, TransportGetStatusAction.class)
156+
);
154157
}
155158

156159
@Override
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.profiler;
9+
10+
import org.elasticsearch.client.internal.node.NodeClient;
11+
import org.elasticsearch.rest.BaseRestHandler;
12+
import org.elasticsearch.rest.RestRequest;
13+
import org.elasticsearch.rest.action.RestToXContentListener;
14+
15+
import java.util.List;
16+
17+
import static org.elasticsearch.rest.RestRequest.Method.GET;
18+
19+
public class RestGetStatusAction extends BaseRestHandler {
20+
21+
@Override
22+
public List<Route> routes() {
23+
return List.of(new Route(GET, "/_profiling/status"));
24+
}
25+
26+
@Override
27+
public String getName() {
28+
return "get_profiling_status_action";
29+
}
30+
31+
@Override
32+
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) {
33+
GetStatusAction.Request request = new GetStatusAction.Request();
34+
request.timeout(restRequest.paramAsTime("timeout", request.timeout()));
35+
request.masterNodeTimeout(restRequest.paramAsTime("master_timeout", request.masterNodeTimeout()));
36+
return channel -> client.execute(GetStatusAction.INSTANCE, request, new RestToXContentListener<>(channel));
37+
}
38+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.profiler;
9+
10+
import org.elasticsearch.action.ActionListener;
11+
import org.elasticsearch.action.support.ActionFilters;
12+
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
13+
import org.elasticsearch.cluster.ClusterState;
14+
import org.elasticsearch.cluster.block.ClusterBlockException;
15+
import org.elasticsearch.cluster.block.ClusterBlockLevel;
16+
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
17+
import org.elasticsearch.cluster.service.ClusterService;
18+
import org.elasticsearch.common.inject.Inject;
19+
import org.elasticsearch.tasks.Task;
20+
import org.elasticsearch.threadpool.ThreadPool;
21+
import org.elasticsearch.transport.TransportService;
22+
import org.elasticsearch.xpack.core.XPackSettings;
23+
24+
public class TransportGetStatusAction extends TransportMasterNodeAction<GetStatusAction.Request, GetStatusAction.Response> {
25+
26+
@Inject
27+
public TransportGetStatusAction(
28+
TransportService transportService,
29+
ClusterService clusterService,
30+
ThreadPool threadPool,
31+
ActionFilters actionFilters,
32+
IndexNameExpressionResolver indexNameExpressionResolver
33+
) {
34+
super(
35+
GetStatusAction.NAME,
36+
transportService,
37+
clusterService,
38+
threadPool,
39+
actionFilters,
40+
GetStatusAction.Request::new,
41+
indexNameExpressionResolver,
42+
GetStatusAction.Response::new,
43+
ThreadPool.Names.SAME
44+
);
45+
}
46+
47+
@Override
48+
protected void masterOperation(
49+
Task task,
50+
GetStatusAction.Request request,
51+
ClusterState state,
52+
ActionListener<GetStatusAction.Response> listener
53+
) {
54+
boolean pluginEnabled = XPackSettings.PROFILING_ENABLED.get(state.getMetadata().settings());
55+
boolean resourceManagementEnabled = ProfilingPlugin.PROFILING_TEMPLATES_ENABLED.get(state.getMetadata().settings());
56+
boolean resourcesCreated = ProfilingIndexTemplateRegistry.areAllTemplatesCreated(state);
57+
listener.onResponse(new GetStatusAction.Response(pluginEnabled, resourceManagementEnabled, resourcesCreated));
58+
}
59+
60+
@Override
61+
protected ClusterBlockException checkBlock(GetStatusAction.Request request, ClusterState state) {
62+
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
63+
}
64+
}

0 commit comments

Comments
 (0)