diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java
index 8bfd8fe8ac0f3..80cee2c420ef3 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java
@@ -39,6 +39,8 @@
import org.elasticsearch.client.slm.ExecuteSnapshotLifecyclePolicyResponse;
import org.elasticsearch.client.slm.GetSnapshotLifecyclePolicyRequest;
import org.elasticsearch.client.slm.GetSnapshotLifecyclePolicyResponse;
+import org.elasticsearch.client.slm.GetSnapshotLifecycleStatsRequest;
+import org.elasticsearch.client.slm.GetSnapshotLifecycleStatsResponse;
import org.elasticsearch.client.slm.PutSnapshotLifecyclePolicyRequest;
import java.io.IOException;
@@ -464,4 +466,40 @@ public Cancellable executeSnapshotLifecyclePolicyAsync(
request, IndexLifecycleRequestConverters::executeSnapshotLifecyclePolicy,
options, ExecuteSnapshotLifecyclePolicyResponse::fromXContent, listener, emptySet());
}
+
+ /**
+ * Retrieve snapshot lifecycle statistics.
+ * See
+ * https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/
+ * java-rest-high-ilm-slm-get-snapshot-lifecycle-stats.html
+ *
+ * for more.
+ * @param request the request
+ * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+ * @return the response
+ * @throws IOException in case there is a problem sending the request or parsing back the response
+ */
+ public GetSnapshotLifecycleStatsResponse getSnapshotLifecycleStats(GetSnapshotLifecycleStatsRequest request,
+ RequestOptions options) throws IOException {
+ return restHighLevelClient.performRequestAndParseEntity(request, IndexLifecycleRequestConverters::getSnapshotLifecycleStats,
+ options, GetSnapshotLifecycleStatsResponse::fromXContent, emptySet());
+ }
+
+ /**
+ * Asynchronously retrieve snapshot lifecycle statistics.
+ * See
+ * https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/
+ * java-rest-high-ilm-slm-get-snapshot-lifecycle-stats.html
+ *
+ * for more.
+ * @param request the request
+ * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+ * @param listener the listener to be notified upon request completion
+ * @return cancellable that may be used to cancel the request
+ */
+ public Cancellable getSnapshotLifecycleStatsAsync(GetSnapshotLifecycleStatsRequest request, RequestOptions options,
+ ActionListener listener) {
+ return restHighLevelClient.performRequestAsyncAndParseEntity(request, IndexLifecycleRequestConverters::getSnapshotLifecycleStats,
+ options, GetSnapshotLifecycleStatsResponse::fromXContent, listener, emptySet());
+ }
}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleRequestConverters.java
index 6f4e991f0dbc7..563f178711e45 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleRequestConverters.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleRequestConverters.java
@@ -35,6 +35,7 @@
import org.elasticsearch.client.slm.DeleteSnapshotLifecyclePolicyRequest;
import org.elasticsearch.client.slm.ExecuteSnapshotLifecyclePolicyRequest;
import org.elasticsearch.client.slm.GetSnapshotLifecyclePolicyRequest;
+import org.elasticsearch.client.slm.GetSnapshotLifecycleStatsRequest;
import org.elasticsearch.client.slm.PutSnapshotLifecyclePolicyRequest;
import org.elasticsearch.common.Strings;
@@ -215,4 +216,14 @@ static Request executeSnapshotLifecyclePolicy(ExecuteSnapshotLifecyclePolicyRequ
request.addParameters(params.asMap());
return request;
}
+
+ static Request getSnapshotLifecycleStats(GetSnapshotLifecycleStatsRequest getSnapshotLifecycleStatsRequest) {
+ String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_slm/stats").build();
+ Request request = new Request(HttpGet.METHOD_NAME, endpoint);
+ RequestConverters.Params params = new RequestConverters.Params();
+ params.withMasterTimeout(getSnapshotLifecycleStatsRequest.masterNodeTimeout());
+ params.withTimeout(getSnapshotLifecycleStatsRequest.timeout());
+ request.addParameters(params.asMap());
+ return request;
+ }
}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/GetSnapshotLifecycleStatsRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/GetSnapshotLifecycleStatsRequest.java
new file mode 100644
index 0000000000000..285a179e3e612
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/GetSnapshotLifecycleStatsRequest.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.slm;
+
+import org.elasticsearch.client.TimedRequest;
+
+public class GetSnapshotLifecycleStatsRequest extends TimedRequest {
+
+ public GetSnapshotLifecycleStatsRequest() {
+ super();
+ }
+
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/GetSnapshotLifecycleStatsResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/GetSnapshotLifecycleStatsResponse.java
new file mode 100644
index 0000000000000..1aed51afc72fd
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/GetSnapshotLifecycleStatsResponse.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.slm;
+
+import org.elasticsearch.common.xcontent.ToXContentObject;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.Objects;
+
+public class GetSnapshotLifecycleStatsResponse implements ToXContentObject {
+
+ private final SnapshotLifecycleStats stats;
+
+ public GetSnapshotLifecycleStatsResponse(SnapshotLifecycleStats stats) {
+ this.stats = stats;
+ }
+
+ public SnapshotLifecycleStats getStats() {
+ return this.stats;
+ }
+
+ public static GetSnapshotLifecycleStatsResponse fromXContent(XContentParser parser) throws IOException {
+ return new GetSnapshotLifecycleStatsResponse(SnapshotLifecycleStats.parse(parser));
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ return stats.toXContent(builder, params);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ GetSnapshotLifecycleStatsResponse other = (GetSnapshotLifecycleStatsResponse) o;
+ return Objects.equals(this.stats, other.stats);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.stats);
+ }
+}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/SnapshotLifecyclePolicyMetadata.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/SnapshotLifecyclePolicyMetadata.java
index 9b967e8c33b07..d459069a2906e 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/SnapshotLifecyclePolicyMetadata.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/SnapshotLifecyclePolicyMetadata.java
@@ -42,6 +42,7 @@ public class SnapshotLifecyclePolicyMetadata implements ToXContentObject {
static final ParseField NEXT_EXECUTION_MILLIS = new ParseField("next_execution_millis");
static final ParseField NEXT_EXECUTION = new ParseField("next_execution");
static final ParseField SNAPSHOT_IN_PROGRESS = new ParseField("in_progress");
+ static final ParseField POLICY_STATS = new ParseField("stats");
private final SnapshotLifecyclePolicy policy;
private final long version;
@@ -53,6 +54,7 @@ public class SnapshotLifecyclePolicyMetadata implements ToXContentObject {
private final SnapshotInvocationRecord lastFailure;
@Nullable
private final SnapshotInProgress snapshotInProgress;
+ private final SnapshotLifecycleStats.SnapshotPolicyStats policyStats;
@SuppressWarnings("unchecked")
public static final ConstructingObjectParser PARSER =
@@ -65,8 +67,9 @@ public class SnapshotLifecyclePolicyMetadata implements ToXContentObject {
SnapshotInvocationRecord lastFailure = (SnapshotInvocationRecord) a[4];
long nextExecution = (long) a[5];
SnapshotInProgress sip = (SnapshotInProgress) a[6];
-
- return new SnapshotLifecyclePolicyMetadata(policy, version, modifiedDate, lastSuccess, lastFailure, nextExecution, sip);
+ SnapshotLifecycleStats.SnapshotPolicyStats stats = (SnapshotLifecycleStats.SnapshotPolicyStats) a[7];
+ return new SnapshotLifecyclePolicyMetadata(policy, version, modifiedDate, lastSuccess,
+ lastFailure, nextExecution, sip, stats);
});
static {
@@ -77,6 +80,9 @@ public class SnapshotLifecyclePolicyMetadata implements ToXContentObject {
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), SnapshotInvocationRecord::parse, LAST_FAILURE);
PARSER.declareLong(ConstructingObjectParser.constructorArg(), NEXT_EXECUTION_MILLIS);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), SnapshotInProgress::parse, SNAPSHOT_IN_PROGRESS);
+ PARSER.declareObject(ConstructingObjectParser.constructorArg(),
+ (p, c) -> SnapshotLifecycleStats.SnapshotPolicyStats.parse(p, "policy"), POLICY_STATS);
+
}
public static SnapshotLifecyclePolicyMetadata parse(XContentParser parser, String id) {
@@ -86,7 +92,8 @@ public static SnapshotLifecyclePolicyMetadata parse(XContentParser parser, Strin
public SnapshotLifecyclePolicyMetadata(SnapshotLifecyclePolicy policy, long version, long modifiedDate,
SnapshotInvocationRecord lastSuccess, SnapshotInvocationRecord lastFailure,
long nextExecution,
- @Nullable SnapshotInProgress snapshotInProgress) {
+ @Nullable SnapshotInProgress snapshotInProgress,
+ SnapshotLifecycleStats.SnapshotPolicyStats policyStats) {
this.policy = policy;
this.version = version;
this.modifiedDate = modifiedDate;
@@ -94,6 +101,7 @@ public SnapshotLifecyclePolicyMetadata(SnapshotLifecyclePolicy policy, long vers
this.lastFailure = lastFailure;
this.nextExecution = nextExecution;
this.snapshotInProgress = snapshotInProgress;
+ this.policyStats = policyStats;
}
public SnapshotLifecyclePolicy getPolicy() {
@@ -124,6 +132,10 @@ public long getNextExecution() {
return this.nextExecution;
}
+ public SnapshotLifecycleStats.SnapshotPolicyStats getPolicyStats() {
+ return this.policyStats;
+ }
+
@Nullable
public SnapshotInProgress getSnapshotInProgress() {
return this.snapshotInProgress;
@@ -145,13 +157,16 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
if (snapshotInProgress != null) {
builder.field(SNAPSHOT_IN_PROGRESS.getPreferredName(), snapshotInProgress);
}
+ builder.startObject(POLICY_STATS.getPreferredName());
+ this.policyStats.toXContent(builder, params);
+ builder.endObject();
builder.endObject();
return builder;
}
@Override
public int hashCode() {
- return Objects.hash(policy, version, modifiedDate, lastSuccess, lastFailure, nextExecution);
+ return Objects.hash(policy, version, modifiedDate, lastSuccess, lastFailure, nextExecution, policyStats);
}
@Override
@@ -168,7 +183,8 @@ public boolean equals(Object obj) {
Objects.equals(modifiedDate, other.modifiedDate) &&
Objects.equals(lastSuccess, other.lastSuccess) &&
Objects.equals(lastFailure, other.lastFailure) &&
- Objects.equals(nextExecution, other.nextExecution);
+ Objects.equals(nextExecution, other.nextExecution) &&
+ Objects.equals(policyStats, other.policyStats);
}
public static class SnapshotInProgress implements ToXContentObject {
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/SnapshotLifecycleStats.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/SnapshotLifecycleStats.java
new file mode 100644
index 0000000000000..fc54f74649b01
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/slm/SnapshotLifecycleStats.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.slm;
+
+import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.common.xcontent.ConstructingObjectParser;
+import org.elasticsearch.common.xcontent.ToXContentFragment;
+import org.elasticsearch.common.xcontent.ToXContentObject;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class SnapshotLifecycleStats implements ToXContentObject {
+
+ private final long retentionRunCount;
+ private final long retentionFailedCount;
+ private final long retentionTimedOut;
+ private final long retentionTimeMs;
+ private final Map policyStats;
+
+ public static final ParseField RETENTION_RUNS = new ParseField("retention_runs");
+ public static final ParseField RETENTION_FAILED = new ParseField("retention_failed");
+ public static final ParseField RETENTION_TIMED_OUT = new ParseField("retention_timed_out");
+ public static final ParseField RETENTION_TIME = new ParseField("retention_deletion_time");
+ public static final ParseField RETENTION_TIME_MILLIS = new ParseField("retention_deletion_time_millis");
+ public static final ParseField POLICY_STATS = new ParseField("policy_stats");
+ public static final ParseField TOTAL_TAKEN = new ParseField("total_snapshots_taken");
+ public static final ParseField TOTAL_FAILED = new ParseField("total_snapshots_failed");
+ public static final ParseField TOTAL_DELETIONS = new ParseField("total_snapshots_deleted");
+ public static final ParseField TOTAL_DELETION_FAILURES = new ParseField("total_snapshot_deletion_failures");
+
+
+ @SuppressWarnings("unchecked")
+ private static final ConstructingObjectParser PARSER =
+ new ConstructingObjectParser<>("snapshot_policy_stats", true,
+ a -> {
+ long runs = (long) a[0];
+ long failed = (long) a[1];
+ long timedOut = (long) a[2];
+ long timeMs = (long) a[3];
+ Map policyStatsMap = ((List) a[4]).stream()
+ .collect(Collectors.toMap(m -> m.policyId, Function.identity()));
+ return new SnapshotLifecycleStats(runs, failed, timedOut, timeMs, policyStatsMap);
+ });
+
+ static {
+ PARSER.declareLong(ConstructingObjectParser.constructorArg(), RETENTION_RUNS);
+ PARSER.declareLong(ConstructingObjectParser.constructorArg(), RETENTION_FAILED);
+ PARSER.declareLong(ConstructingObjectParser.constructorArg(), RETENTION_TIMED_OUT);
+ PARSER.declareLong(ConstructingObjectParser.constructorArg(), RETENTION_TIME_MILLIS);
+ PARSER.declareNamedObjects(ConstructingObjectParser.constructorArg(), (p, c, n) -> SnapshotPolicyStats.parse(p, n), POLICY_STATS);
+ }
+
+ // Package visible for testing
+ private SnapshotLifecycleStats(long retentionRuns, long retentionFailed, long retentionTimedOut, long retentionTimeMs,
+ Map policyStats) {
+ this.retentionRunCount = retentionRuns;
+ this.retentionFailedCount = retentionFailed;
+ this.retentionTimedOut = retentionTimedOut;
+ this.retentionTimeMs = retentionTimeMs;
+ this.policyStats = policyStats;
+ }
+
+ public static SnapshotLifecycleStats parse(XContentParser parser) {
+ return PARSER.apply(parser, null);
+ }
+
+ public long getRetentionRunCount() {
+ return retentionRunCount;
+ }
+
+ public long getRetentionFailedCount() {
+ return retentionFailedCount;
+ }
+
+ public long getRetentionTimedOut() {
+ return retentionTimedOut;
+ }
+
+ public long getRetentionTimeMillis() {
+ return retentionTimeMs;
+ }
+
+ /**
+ * @return a map of per-policy stats for each SLM policy
+ */
+ public Map getMetrics() {
+ return Collections.unmodifiableMap(this.policyStats);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject();
+ builder.field(RETENTION_RUNS.getPreferredName(), this.retentionRunCount);
+ builder.field(RETENTION_FAILED.getPreferredName(), this.retentionFailedCount);
+ builder.field(RETENTION_TIMED_OUT.getPreferredName(), this.retentionTimedOut);
+ TimeValue retentionTime = TimeValue.timeValueMillis(this.retentionTimeMs);
+ builder.field(RETENTION_TIME.getPreferredName(), retentionTime);
+ builder.field(RETENTION_TIME_MILLIS.getPreferredName(), retentionTime.millis());
+
+ Map metrics = getMetrics();
+ long totalTaken = metrics.values().stream().mapToLong(s -> s.snapshotsTaken).sum();
+ long totalFailed = metrics.values().stream().mapToLong(s -> s.snapshotsFailed).sum();
+ long totalDeleted = metrics.values().stream().mapToLong(s -> s.snapshotsDeleted).sum();
+ long totalDeleteFailures = metrics.values().stream().mapToLong(s -> s.snapshotDeleteFailures).sum();
+ builder.field(TOTAL_TAKEN.getPreferredName(), totalTaken);
+ builder.field(TOTAL_FAILED.getPreferredName(), totalFailed);
+ builder.field(TOTAL_DELETIONS.getPreferredName(), totalDeleted);
+ builder.field(TOTAL_DELETION_FAILURES.getPreferredName(), totalDeleteFailures);
+ builder.startObject(POLICY_STATS.getPreferredName());
+ for (Map.Entry policy : metrics.entrySet()) {
+ SnapshotPolicyStats perPolicyMetrics = policy.getValue();
+ builder.startObject(perPolicyMetrics.policyId);
+ perPolicyMetrics.toXContent(builder, params);
+ builder.endObject();
+ }
+ builder.endObject();
+ builder.endObject();
+ return builder;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(retentionRunCount, retentionFailedCount, retentionTimedOut, retentionTimeMs, policyStats);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (obj.getClass() != getClass()) {
+ return false;
+ }
+ SnapshotLifecycleStats other = (SnapshotLifecycleStats) obj;
+ return retentionRunCount == other.retentionRunCount &&
+ retentionFailedCount == other.retentionFailedCount &&
+ retentionTimedOut == other.retentionTimedOut &&
+ retentionTimeMs == other.retentionTimeMs &&
+ Objects.equals(policyStats, other.policyStats);
+ }
+
+ @Override
+ public String toString() {
+ return Strings.toString(this);
+ }
+
+ public static class SnapshotPolicyStats implements ToXContentFragment {
+ private final String policyId;
+ private final long snapshotsTaken;
+ private final long snapshotsFailed;
+ private final long snapshotsDeleted;
+ private final long snapshotDeleteFailures;
+
+ static final ParseField SNAPSHOTS_TAKEN = new ParseField("snapshots_taken");
+ static final ParseField SNAPSHOTS_FAILED = new ParseField("snapshots_failed");
+ static final ParseField SNAPSHOTS_DELETED = new ParseField("snapshots_deleted");
+ static final ParseField SNAPSHOT_DELETION_FAILURES = new ParseField("snapshot_deletion_failures");
+
+ private static final ConstructingObjectParser PARSER =
+ new ConstructingObjectParser<>("snapshot_policy_stats", true,
+ (a, id) -> {
+ long taken = (long) a[0];
+ long failed = (long) a[1];
+ long deleted = (long) a[2];
+ long deleteFailed = (long) a[3];
+ return new SnapshotPolicyStats(id, taken, failed, deleted, deleteFailed);
+ });
+
+ static {
+ PARSER.declareLong(ConstructingObjectParser.constructorArg(), SNAPSHOTS_TAKEN);
+ PARSER.declareLong(ConstructingObjectParser.constructorArg(), SNAPSHOTS_FAILED);
+ PARSER.declareLong(ConstructingObjectParser.constructorArg(), SNAPSHOTS_DELETED);
+ PARSER.declareLong(ConstructingObjectParser.constructorArg(), SNAPSHOT_DELETION_FAILURES);
+ }
+
+ public SnapshotPolicyStats(String policyId, long snapshotsTaken, long snapshotsFailed, long deleted, long failedDeletes) {
+ this.policyId = policyId;
+ this.snapshotsTaken = snapshotsTaken;
+ this.snapshotsFailed = snapshotsFailed;
+ this.snapshotsDeleted = deleted;
+ this.snapshotDeleteFailures = failedDeletes;
+ }
+
+ public static SnapshotPolicyStats parse(XContentParser parser, String policyId) {
+ return PARSER.apply(parser, policyId);
+ }
+
+ public long getSnapshotsTaken() {
+ return snapshotsTaken;
+ }
+
+ public long getSnapshotsFailed() {
+ return snapshotsFailed;
+ }
+
+ public long getSnapshotsDeleted() {
+ return snapshotsDeleted;
+ }
+
+ public long getSnapshotDeleteFailures() {
+ return snapshotDeleteFailures;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(policyId, snapshotsTaken, snapshotsFailed, snapshotsDeleted, snapshotDeleteFailures);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (obj.getClass() != getClass()) {
+ return false;
+ }
+ SnapshotPolicyStats other = (SnapshotPolicyStats) obj;
+ return Objects.equals(policyId, other.policyId) &&
+ snapshotsTaken == other.snapshotsTaken &&
+ snapshotsFailed == other.snapshotsFailed &&
+ snapshotsDeleted == other.snapshotsDeleted &&
+ snapshotDeleteFailures == other.snapshotDeleteFailures;
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.field(SnapshotPolicyStats.SNAPSHOTS_TAKEN.getPreferredName(), snapshotsTaken);
+ builder.field(SnapshotPolicyStats.SNAPSHOTS_FAILED.getPreferredName(), snapshotsFailed);
+ builder.field(SnapshotPolicyStats.SNAPSHOTS_DELETED.getPreferredName(), snapshotsDeleted);
+ builder.field(SnapshotPolicyStats.SNAPSHOT_DELETION_FAILURES.getPreferredName(), snapshotDeleteFailures);
+ return builder;
+ }
+ }
+}
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ILMDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ILMDocumentationIT.java
index 9c7e2b848df06..5d367430afbea 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ILMDocumentationIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ILMDocumentationIT.java
@@ -59,10 +59,13 @@
import org.elasticsearch.client.slm.ExecuteSnapshotLifecyclePolicyResponse;
import org.elasticsearch.client.slm.GetSnapshotLifecyclePolicyRequest;
import org.elasticsearch.client.slm.GetSnapshotLifecyclePolicyResponse;
+import org.elasticsearch.client.slm.GetSnapshotLifecycleStatsRequest;
+import org.elasticsearch.client.slm.GetSnapshotLifecycleStatsResponse;
import org.elasticsearch.client.slm.PutSnapshotLifecyclePolicyRequest;
import org.elasticsearch.client.slm.SnapshotInvocationRecord;
import org.elasticsearch.client.slm.SnapshotLifecyclePolicy;
import org.elasticsearch.client.slm.SnapshotLifecyclePolicyMetadata;
+import org.elasticsearch.client.slm.SnapshotLifecycleStats;
import org.elasticsearch.client.slm.SnapshotRetentionConfiguration;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.Strings;
@@ -89,6 +92,7 @@
import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
public class ILMDocumentationIT extends ESRestHighLevelClientTestCase {
@@ -937,6 +941,22 @@ public void onFailure(Exception e) {
// end::slm-execute-snapshot-lifecycle-policy-execute-async
latch.await(5, TimeUnit.SECONDS);
+ // tag::slm-get-snapshot-lifecycle-stats
+ GetSnapshotLifecycleStatsRequest getStatsRequest =
+ new GetSnapshotLifecycleStatsRequest();
+ // end::slm-get-snapshot-lifecycle-stats
+
+ // tag::slm-get-snapshot-lifecycle-stats-execute
+ GetSnapshotLifecycleStatsResponse statsResp = client.indexLifecycle()
+ .getSnapshotLifecycleStats(getStatsRequest, RequestOptions.DEFAULT);
+ SnapshotLifecycleStats stats = statsResp.getStats();
+ SnapshotLifecycleStats.SnapshotPolicyStats policyStats =
+ stats.getMetrics().get("policy_id");
+ // end::slm-get-snapshot-lifecycle-stats-execute
+ assertThat(
+ statsResp.getStats().getMetrics().get("policy_id").getSnapshotsTaken(),
+ greaterThanOrEqualTo(1L));
+
//////// DELETE
// tag::slm-delete-snapshot-lifecycle-policy
DeleteSnapshotLifecyclePolicyRequest deleteRequest =
diff --git a/docs/java-rest/high-level/ilm/get_snapshot_lifecycle_stats.asciidoc b/docs/java-rest/high-level/ilm/get_snapshot_lifecycle_stats.asciidoc
new file mode 100644
index 0000000000000..4f42b92ac64a7
--- /dev/null
+++ b/docs/java-rest/high-level/ilm/get_snapshot_lifecycle_stats.asciidoc
@@ -0,0 +1,35 @@
+--
+:api: slm-get-snapshot-lifecycle-stats
+:request: GetSnapshotLifecycleStatsRequest
+:response: GetSnapshotLifecycleStatsResponse
+--
+
+[id="{upid}-{api}"]
+=== Get Snapshot Lifecycle Stats API
+
+
+[id="{upid}-{api}-request"]
+==== Request
+
+The Get Snapshot Lifecycle Stats API allows you to retrieve statistics about snapshots taken or
+deleted, as well as retention runs by the snapshot lifecycle service.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+
+[id="{upid}-{api}-response"]
+==== Response
+
+The returned +{response}+ contains global statistics as well as a map of `SnapshotPolicyStats`,
+accessible by the id of the policy, which contains statistics about each policy.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+
+include::../execution.asciidoc[]
+
+
diff --git a/docs/reference/ilm/apis/slm-api.asciidoc b/docs/reference/ilm/apis/slm-api.asciidoc
index 97589149885ec..63a6a218a2f07 100644
--- a/docs/reference/ilm/apis/slm-api.asciidoc
+++ b/docs/reference/ilm/apis/slm-api.asciidoc
@@ -140,6 +140,12 @@ The output looks similar to the following:
},
"retention": {}
},
+ "stats": {
+ "snapshots_taken": 0,
+ "snapshots_failed": 0,
+ "snapshots_deleted": 0,
+ "snapshot_deletion_failures": 0
+ },
"next_execution": "2019-04-24T01:30:00.000Z", <3>
"next_execution_millis": 1556048160000
}
@@ -224,7 +230,13 @@ Which, in this case shows an error because the index did not exist:
"ignore_unavailable": false,
"include_global_state": false
},
- "retention": {},
+ "retention": {}
+ },
+ "stats": {
+ "snapshots_taken": 0,
+ "snapshots_failed": 1,
+ "snapshots_deleted": 0,
+ "snapshot_deletion_failures": 0
}
"last_failure": { <1>
"snapshot_name": "daily-snap-2019.04.02-lohisb5ith2n8hxacaq3mw",
@@ -310,6 +322,12 @@ Which now includes the successful snapshot information:
},
"retention": {}
},
+ "stats": {
+ "snapshots_taken": 1,
+ "snapshots_failed": 1,
+ "snapshots_deleted": 0,
+ "snapshot_deletion_failures": 0
+ },
"last_success": { <2>
"snapshot_name": "daily-snap-2019.04.24-tmtnyjtrsxkhbrrdcgg18a",
"time_string": "2019-04-24T16:43:49.316Z",
@@ -332,6 +350,47 @@ Which now includes the successful snapshot information:
It is a good idea to test policies using the execute API to ensure they work.
+[[slm-get-stats]]
+=== Get Snapshot Lifecycle Stats API
+
+SLM stores statistics on a global and per-policy level about actions taken. These stats can be
+retrieved by using the following API:
+
+==== Example
+
+[source,js]
+--------------------------------------------------
+GET /_slm/stats
+--------------------------------------------------
+// CONSOLE
+// TEST[continued]
+
+Which returns a response similar to:
+
+[source,js]
+--------------------------------------------------
+{
+ "retention_runs": 13,
+ "retention_failed": 0,
+ "retention_timed_out": 0,
+ "retention_deletion_time": "1.4s",
+ "retention_deletion_time_millis": 1404,
+ "policy_metrics": {
+ "daily-snapshots": {
+ "snapshots_taken": 1,
+ "snapshots_failed": 1,
+ "snapshots_deleted": 0,
+ "snapshot_deletion_failures": 0
+ }
+ },
+ "total_snapshots_taken": 1,
+ "total_snapshots_failed": 1,
+ "total_snapshots_deleted": 0,
+ "total_snapshot_deletion_failures": 0
+}
+--------------------------------------------------
+// TESTRESPONSE[s/runs": 13/runs": $body.retention_runs/ s/_failed": 0/_failed": $body.retention_failed/ s/_timed_out": 0/_timed_out": $body.retention_timed_out/ s/"1.4s"/$body.retention_deletion_time/ s/1404/$body.retention_deletion_time_millis/]
+
[[slm-api-delete]]
=== Delete Snapshot Lifecycle Policy API
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/SnapshotLifecyclePolicyItem.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/SnapshotLifecyclePolicyItem.java
index 25832ec1cfbed..9db4a0652e730 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/SnapshotLifecyclePolicyItem.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/slm/SnapshotLifecyclePolicyItem.java
@@ -6,6 +6,7 @@
package org.elasticsearch.xpack.core.slm;
+import org.elasticsearch.Version;
import org.elasticsearch.cluster.SnapshotsInProgress;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
@@ -17,6 +18,7 @@
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.snapshots.SnapshotId;
+import org.elasticsearch.xpack.slm.SnapshotLifecycleStats;
import java.io.IOException;
import java.util.Objects;
@@ -29,12 +31,14 @@
public class SnapshotLifecyclePolicyItem implements ToXContentFragment, Writeable {
private static final ParseField SNAPSHOT_IN_PROGRESS = new ParseField("in_progress");
+ private static final ParseField POLICY_STATS = new ParseField("stats");
private final SnapshotLifecyclePolicy policy;
private final long version;
private final long modifiedDate;
@Nullable
private final SnapshotInProgress snapshotInProgress;
+ private final SnapshotLifecycleStats.SnapshotPolicyStats policyStats;
@Nullable
private final SnapshotInvocationRecord lastSuccess;
@@ -42,13 +46,15 @@ public class SnapshotLifecyclePolicyItem implements ToXContentFragment, Writeabl
@Nullable
private final SnapshotInvocationRecord lastFailure;
public SnapshotLifecyclePolicyItem(SnapshotLifecyclePolicyMetadata policyMetadata,
- @Nullable SnapshotInProgress snapshotInProgress) {
+ @Nullable SnapshotInProgress snapshotInProgress,
+ @Nullable SnapshotLifecycleStats.SnapshotPolicyStats policyStats) {
this.policy = policyMetadata.getPolicy();
this.version = policyMetadata.getVersion();
this.modifiedDate = policyMetadata.getModifiedDate();
this.lastSuccess = policyMetadata.getLastSuccess();
this.lastFailure = policyMetadata.getLastFailure();
this.snapshotInProgress = snapshotInProgress;
+ this.policyStats = policyStats == null ? new SnapshotLifecycleStats.SnapshotPolicyStats(policy.getId()) : policyStats;
}
public SnapshotLifecyclePolicyItem(StreamInput in) throws IOException {
@@ -58,19 +64,26 @@ public SnapshotLifecyclePolicyItem(StreamInput in) throws IOException {
this.lastSuccess = in.readOptionalWriteable(SnapshotInvocationRecord::new);
this.lastFailure = in.readOptionalWriteable(SnapshotInvocationRecord::new);
this.snapshotInProgress = in.readOptionalWriteable(SnapshotInProgress::new);
+ if (in.getVersion().onOrAfter(Version.V_8_0_0)) {
+ this.policyStats = new SnapshotLifecycleStats.SnapshotPolicyStats(in);
+ } else {
+ this.policyStats = new SnapshotLifecycleStats.SnapshotPolicyStats(this.policy.getId());
+ }
}
// For testing
SnapshotLifecyclePolicyItem(SnapshotLifecyclePolicy policy, long version, long modifiedDate,
SnapshotInvocationRecord lastSuccess, SnapshotInvocationRecord lastFailure,
- @Nullable SnapshotInProgress snapshotInProgress) {
+ @Nullable SnapshotInProgress snapshotInProgress,
+ SnapshotLifecycleStats.SnapshotPolicyStats policyStats) {
this.policy = policy;
this.version = version;
this.modifiedDate = modifiedDate;
this.lastSuccess = lastSuccess;
this.lastFailure = lastFailure;
this.snapshotInProgress = snapshotInProgress;
+ this.policyStats = policyStats;
}
public SnapshotLifecyclePolicy getPolicy() {
return policy;
@@ -97,6 +110,10 @@ public SnapshotInProgress getSnapshotInProgress() {
return this.snapshotInProgress;
}
+ public SnapshotLifecycleStats.SnapshotPolicyStats getPolicyStats() {
+ return this.policyStats;
+ }
+
@Override
public void writeTo(StreamOutput out) throws IOException {
policy.writeTo(out);
@@ -105,11 +122,14 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeOptionalWriteable(lastSuccess);
out.writeOptionalWriteable(lastFailure);
out.writeOptionalWriteable(snapshotInProgress);
+ if (out.getVersion().onOrAfter(Version.V_8_0_0)) {
+ this.policyStats.writeTo(out);
+ }
}
@Override
public int hashCode() {
- return Objects.hash(policy, version, modifiedDate, lastSuccess, lastFailure);
+ return Objects.hash(policy, version, modifiedDate, lastSuccess, lastFailure, policyStats);
}
@Override
@@ -126,7 +146,8 @@ public boolean equals(Object obj) {
modifiedDate == other.modifiedDate &&
Objects.equals(lastSuccess, other.lastSuccess) &&
Objects.equals(lastFailure, other.lastFailure) &&
- Objects.equals(snapshotInProgress, other.snapshotInProgress);
+ Objects.equals(snapshotInProgress, other.snapshotInProgress) &&
+ Objects.equals(policyStats, other.policyStats);
}
@Override
@@ -147,6 +168,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
if (snapshotInProgress != null) {
builder.field(SNAPSHOT_IN_PROGRESS.getPreferredName(), snapshotInProgress);
}
+ builder.startObject(POLICY_STATS.getPreferredName());
+ this.policyStats.toXContent(builder, params);
+ builder.endObject();
builder.endObject();
return builder;
}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/slm/SnapshotLifecycleStats.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/slm/SnapshotLifecycleStats.java
index dcf4bfe502236..fa018abc6c43e 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/slm/SnapshotLifecycleStats.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/slm/SnapshotLifecycleStats.java
@@ -225,7 +225,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.startObject(POLICY_STATS.getPreferredName());
for (Map.Entry policy : metrics.entrySet()) {
SnapshotPolicyStats perPolicyMetrics = policy.getValue();
+ builder.startObject(perPolicyMetrics.policyId);
perPolicyMetrics.toXContent(builder, params);
+ builder.endObject();
}
builder.endObject();
builder.endObject();
@@ -288,11 +290,11 @@ public static class SnapshotPolicyStats implements Writeable, ToXContentFragment
PARSER.declareLong(ConstructingObjectParser.constructorArg(), SNAPSHOT_DELETION_FAILURES);
}
- SnapshotPolicyStats(String slmPolicy) {
+ public SnapshotPolicyStats(String slmPolicy) {
this.policyId = slmPolicy;
}
- SnapshotPolicyStats(String policyId, long snapshotsTaken, long snapshotsFailed, long deleted, long failedDeletes) {
+ public SnapshotPolicyStats(String policyId, long snapshotsTaken, long snapshotsFailed, long deleted, long failedDeletes) {
this.policyId = policyId;
this.snapshotsTaken.inc(snapshotsTaken);
this.snapshotsFailed.inc(snapshotsFailed);
@@ -300,7 +302,7 @@ public static class SnapshotPolicyStats implements Writeable, ToXContentFragment
this.snapshotDeleteFailures.inc(failedDeletes);
}
- SnapshotPolicyStats(StreamInput in) throws IOException {
+ public SnapshotPolicyStats(StreamInput in) throws IOException {
this.policyId = in.readString();
this.snapshotsTaken.inc(in.readVLong());
this.snapshotsFailed.inc(in.readVLong());
@@ -370,13 +372,11 @@ public boolean equals(Object obj) {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
- builder.startObject(policyId);
builder.field(SnapshotPolicyStats.SNAPSHOTS_TAKEN.getPreferredName(), snapshotsTaken.count());
builder.field(SnapshotPolicyStats.SNAPSHOTS_FAILED.getPreferredName(), snapshotsFailed.count());
builder.field(SnapshotPolicyStats.SNAPSHOTS_DELETED.getPreferredName(), snapshotsDeleted.count());
builder.field(SnapshotPolicyStats.SNAPSHOT_DELETION_FAILURES.getPreferredName(), snapshotDeleteFailures.count());
- builder.endObject();
- return null;
+ return builder;
}
}
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/slm/SnapshotLifecyclePolicyItemTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/slm/SnapshotLifecyclePolicyItemTests.java
index 738e4cf77cbcc..183b0141caa43 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/slm/SnapshotLifecyclePolicyItemTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/slm/SnapshotLifecyclePolicyItemTests.java
@@ -11,6 +11,7 @@
import org.elasticsearch.snapshots.SnapshotId;
import org.elasticsearch.test.AbstractWireSerializingTestCase;
import org.elasticsearch.test.ESTestCase;
+import org.elasticsearch.xpack.slm.SnapshotLifecycleStatsTests;
import static org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadataTests.randomSnapshotLifecyclePolicy;
import static org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadataTests.createRandomPolicyMetadata;
@@ -27,12 +28,14 @@ public static SnapshotLifecyclePolicyItem.SnapshotInProgress randomSnapshotInPro
@Override
protected SnapshotLifecyclePolicyItem createTestInstance() {
- return new SnapshotLifecyclePolicyItem(createRandomPolicyMetadata(randomAlphaOfLengthBetween(5, 10)), randomSnapshotInProgress());
+ String policyId = randomAlphaOfLengthBetween(5, 10);
+ return new SnapshotLifecyclePolicyItem(createRandomPolicyMetadata(policyId), randomSnapshotInProgress(),
+ SnapshotLifecycleStatsTests.randomPolicyStats(policyId));
}
@Override
protected SnapshotLifecyclePolicyItem mutateInstance(SnapshotLifecyclePolicyItem instance) {
- switch (between(0, 5)) {
+ switch (between(0, 6)) {
case 0:
String newPolicyId = randomValueOtherThan(instance.getPolicy().getId(), () -> randomAlphaOfLengthBetween(5, 10));
return new SnapshotLifecyclePolicyItem(randomSnapshotLifecyclePolicy(newPolicyId),
@@ -40,21 +43,24 @@ protected SnapshotLifecyclePolicyItem mutateInstance(SnapshotLifecyclePolicyItem
instance.getModifiedDate(),
instance.getLastSuccess(),
instance.getLastFailure(),
- instance.getSnapshotInProgress());
+ instance.getSnapshotInProgress(),
+ instance.getPolicyStats());
case 1:
return new SnapshotLifecyclePolicyItem(instance.getPolicy(),
randomValueOtherThan(instance.getVersion(), ESTestCase::randomNonNegativeLong),
instance.getModifiedDate(),
instance.getLastSuccess(),
instance.getLastFailure(),
- instance.getSnapshotInProgress());
+ instance.getSnapshotInProgress(),
+ instance.getPolicyStats());
case 2:
return new SnapshotLifecyclePolicyItem(instance.getPolicy(),
instance.getVersion(),
randomValueOtherThan(instance.getModifiedDate(), ESTestCase::randomNonNegativeLong),
instance.getLastSuccess(),
instance.getLastFailure(),
- instance.getSnapshotInProgress());
+ instance.getSnapshotInProgress(),
+ instance.getPolicyStats());
case 3:
return new SnapshotLifecyclePolicyItem(instance.getPolicy(),
instance.getVersion(),
@@ -62,7 +68,8 @@ protected SnapshotLifecyclePolicyItem mutateInstance(SnapshotLifecyclePolicyItem
randomValueOtherThan(instance.getLastSuccess(),
SnapshotInvocationRecordTests::randomSnapshotInvocationRecord),
instance.getLastFailure(),
- instance.getSnapshotInProgress());
+ instance.getSnapshotInProgress(),
+ instance.getPolicyStats());
case 4:
return new SnapshotLifecyclePolicyItem(instance.getPolicy(),
instance.getVersion(),
@@ -70,7 +77,8 @@ protected SnapshotLifecyclePolicyItem mutateInstance(SnapshotLifecyclePolicyItem
instance.getLastSuccess(),
randomValueOtherThan(instance.getLastFailure(),
SnapshotInvocationRecordTests::randomSnapshotInvocationRecord),
- instance.getSnapshotInProgress());
+ instance.getSnapshotInProgress(),
+ instance.getPolicyStats());
case 5:
return new SnapshotLifecyclePolicyItem(instance.getPolicy(),
instance.getVersion(),
@@ -78,7 +86,17 @@ protected SnapshotLifecyclePolicyItem mutateInstance(SnapshotLifecyclePolicyItem
instance.getLastSuccess(),
instance.getLastFailure(),
randomValueOtherThan(instance.getSnapshotInProgress(),
- SnapshotLifecyclePolicyItemTests::randomSnapshotInProgress));
+ SnapshotLifecyclePolicyItemTests::randomSnapshotInProgress),
+ instance.getPolicyStats());
+ case 6:
+ return new SnapshotLifecyclePolicyItem(instance.getPolicy(),
+ instance.getVersion(),
+ instance.getModifiedDate(),
+ instance.getLastSuccess(),
+ instance.getLastFailure(),
+ instance.getSnapshotInProgress(),
+ randomValueOtherThan(instance.getPolicyStats(),
+ () -> SnapshotLifecycleStatsTests.randomPolicyStats(instance.getPolicy().getId())));
default:
throw new AssertionError("failure, got illegal switch case");
}
diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/action/TransportGetSnapshotLifecycleAction.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/action/TransportGetSnapshotLifecycleAction.java
index d07e71e129fab..90d302eb403d2 100644
--- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/action/TransportGetSnapshotLifecycleAction.java
+++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/action/TransportGetSnapshotLifecycleAction.java
@@ -26,6 +26,7 @@
import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicy;
import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyItem;
import org.elasticsearch.xpack.core.slm.action.GetSnapshotLifecycleAction;
+import org.elasticsearch.xpack.slm.SnapshotLifecycleStats;
import java.io.IOException;
import java.util.Arrays;
@@ -86,6 +87,7 @@ protected void masterOperation(final Task task, final GetSnapshotLifecycleAction
}
final Set ids = new HashSet<>(Arrays.asList(request.getLifecycleIds()));
+ final SnapshotLifecycleStats slmStats = snapMeta.getStats();
List lifecycles = snapMeta.getSnapshotConfigurations().values().stream()
.filter(meta -> {
if (ids.isEmpty()) {
@@ -94,7 +96,9 @@ protected void masterOperation(final Task task, final GetSnapshotLifecycleAction
return ids.contains(meta.getPolicy().getId());
}
})
- .map(policyMeta -> new SnapshotLifecyclePolicyItem(policyMeta, inProgress.get(policyMeta.getPolicy().getId())))
+ .map(policyMeta ->
+ new SnapshotLifecyclePolicyItem(policyMeta, inProgress.get(policyMeta.getPolicy().getId()),
+ slmStats.getMetrics().get(policyMeta.getPolicy().getId())))
.collect(Collectors.toList());
listener.onResponse(new GetSnapshotLifecycleAction.Response(lifecycles));
}
diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/slm.get_stats.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/slm.get_stats.json
new file mode 100644
index 0000000000000..233d302baee0b
--- /dev/null
+++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/slm.get_stats.json
@@ -0,0 +1,19 @@
+{
+ "slm.get_stats":{
+ "documentation":{
+ "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current/slm-api.html"
+ },
+ "stability":"stable",
+ "url":{
+ "paths":[
+ {
+ "path":"/_slm/stats",
+ "methods":[
+ "GET"
+ ]
+ }
+ ]
+ },
+ "params":{}
+ }
+}