Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SLM metrics gathering and endpoint #45362

Merged
merged 8 commits into from
Aug 13, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
import org.elasticsearch.xpack.core.slm.action.DeleteSnapshotLifecycleAction;
import org.elasticsearch.xpack.core.slm.action.ExecuteSnapshotLifecycleAction;
import org.elasticsearch.xpack.core.slm.action.GetSnapshotLifecycleAction;
import org.elasticsearch.xpack.core.slm.action.GetSnapshotLifecycleStatsAction;
import org.elasticsearch.xpack.core.slm.action.PutSnapshotLifecycleAction;
import org.elasticsearch.xpack.core.spatial.SpatialFeatureSetUsage;
import org.elasticsearch.xpack.core.sql.SqlFeatureSetUsage;
Expand Down Expand Up @@ -378,6 +379,7 @@ public List<ActionType<? extends ActionResponse>> getClientActions() {
GetSnapshotLifecycleAction.INSTANCE,
DeleteSnapshotLifecycleAction.INSTANCE,
ExecuteSnapshotLifecycleAction.INSTANCE,
GetSnapshotLifecycleStatsAction.INSTANCE,
// Freeze
FreezeIndexAction.INSTANCE,
// Data Frame
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.xpack.core.ilm.OperationMode;
import org.elasticsearch.xpack.slm.SnapshotLifecycleStats;

import java.io.IOException;
import java.util.Collections;
Expand All @@ -38,36 +39,48 @@
public class SnapshotLifecycleMetadata implements MetaData.Custom {

public static final String TYPE = "snapshot_lifecycle";
public static final ParseField OPERATION_MODE_FIELD = new ParseField("operation_mode");
public static final ParseField POLICIES_FIELD = new ParseField("policies");

public static final SnapshotLifecycleMetadata EMPTY = new SnapshotLifecycleMetadata(Collections.emptyMap(), OperationMode.RUNNING);
private static final ParseField OPERATION_MODE_FIELD = new ParseField("operation_mode");
private static final ParseField POLICIES_FIELD = new ParseField("policies");
private static final ParseField STATS_FIELD = new ParseField("stats");

public static final SnapshotLifecycleMetadata EMPTY =
new SnapshotLifecycleMetadata(Collections.emptyMap(), OperationMode.RUNNING, new SnapshotLifecycleStats());

@SuppressWarnings("unchecked")
public static final ConstructingObjectParser<SnapshotLifecycleMetadata, Void> PARSER = new ConstructingObjectParser<>(TYPE,
a -> new SnapshotLifecycleMetadata(
((List<SnapshotLifecyclePolicyMetadata>) a[0]).stream()
.collect(Collectors.toMap(m -> m.getPolicy().getId(), Function.identity())),
OperationMode.valueOf((String) a[1])));
OperationMode.valueOf((String) a[1]),
(SnapshotLifecycleStats) a[2]));

static {
PARSER.declareNamedObjects(ConstructingObjectParser.constructorArg(), (p, c, n) -> SnapshotLifecyclePolicyMetadata.parse(p, n),
v -> {
throw new IllegalArgumentException("ordered " + POLICIES_FIELD.getPreferredName() + " are not supported");
}, POLICIES_FIELD);
PARSER.declareString(ConstructingObjectParser.constructorArg(), OPERATION_MODE_FIELD);
PARSER.declareObject(ConstructingObjectParser.constructorArg(), (v, o) -> SnapshotLifecycleStats.parse(v), STATS_FIELD);
}

private final Map<String, SnapshotLifecyclePolicyMetadata> snapshotConfigurations;
private final OperationMode operationMode;
private final SnapshotLifecycleStats slmStats;

public SnapshotLifecycleMetadata(Map<String, SnapshotLifecyclePolicyMetadata> snapshotConfigurations, OperationMode operationMode) {
public SnapshotLifecycleMetadata(Map<String, SnapshotLifecyclePolicyMetadata> snapshotConfigurations,
OperationMode operationMode,
SnapshotLifecycleStats slmStats) {
this.snapshotConfigurations = new HashMap<>(snapshotConfigurations);
this.operationMode = operationMode;
this.slmStats = slmStats;
}

public SnapshotLifecycleMetadata(StreamInput in) throws IOException {
this.snapshotConfigurations = in.readMap(StreamInput::readString, SnapshotLifecyclePolicyMetadata::new);
this.operationMode = in.readEnum(OperationMode.class);
// TODO: version qualify
dakrone marked this conversation as resolved.
Show resolved Hide resolved
this.slmStats = new SnapshotLifecycleStats(in);
}

public Map<String, SnapshotLifecyclePolicyMetadata> getSnapshotConfigurations() {
Expand All @@ -78,6 +91,10 @@ public OperationMode getOperationMode() {
return operationMode;
}

public SnapshotLifecycleStats getStats() {
return this.slmStats;
}

@Override
public EnumSet<MetaData.XContentContext> context() {
return MetaData.ALL_CONTEXTS;
Expand All @@ -102,12 +119,15 @@ public Version getMinimalSupportedVersion() {
public void writeTo(StreamOutput out) throws IOException {
out.writeMap(this.snapshotConfigurations, StreamOutput::writeString, (out1, value) -> value.writeTo(out1));
out.writeEnum(this.operationMode);
// TODO: version qualify
this.slmStats.writeTo(out);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.field(POLICIES_FIELD.getPreferredName(), this.snapshotConfigurations);
builder.field(OPERATION_MODE_FIELD.getPreferredName(), operationMode);
builder.field(STATS_FIELD.getPreferredName(), this.slmStats);
return builder;
}

Expand All @@ -118,7 +138,7 @@ public String toString() {

@Override
public int hashCode() {
return Objects.hash(this.snapshotConfigurations, this.operationMode);
return Objects.hash(this.snapshotConfigurations, this.operationMode, this.slmStats);
}

@Override
Expand All @@ -131,32 +151,37 @@ public boolean equals(Object obj) {
}
SnapshotLifecycleMetadata other = (SnapshotLifecycleMetadata) obj;
return this.snapshotConfigurations.equals(other.snapshotConfigurations) &&
this.operationMode.equals(other.operationMode);
this.operationMode.equals(other.operationMode) &&
this.slmStats.equals(other.slmStats);
}

public static class SnapshotLifecycleMetadataDiff implements NamedDiff<MetaData.Custom> {

final Diff<Map<String, SnapshotLifecyclePolicyMetadata>> lifecycles;
final OperationMode operationMode;
final SnapshotLifecycleStats slmStats;

SnapshotLifecycleMetadataDiff(SnapshotLifecycleMetadata before, SnapshotLifecycleMetadata after) {
this.lifecycles = DiffableUtils.diff(before.snapshotConfigurations, after.snapshotConfigurations,
DiffableUtils.getStringKeySerializer());
this.operationMode = after.operationMode;
this.slmStats = after.slmStats;
}

public SnapshotLifecycleMetadataDiff(StreamInput in) throws IOException {
this.lifecycles = DiffableUtils.readJdkMapDiff(in, DiffableUtils.getStringKeySerializer(),
SnapshotLifecyclePolicyMetadata::new,
SnapshotLifecycleMetadataDiff::readLifecyclePolicyDiffFrom);
this.operationMode = in.readEnum(OperationMode.class);
// TODO: version qualify this
this.slmStats = new SnapshotLifecycleStats(in);
}

@Override
public MetaData.Custom apply(MetaData.Custom part) {
TreeMap<String, SnapshotLifecyclePolicyMetadata> newLifecycles = new TreeMap<>(
lifecycles.apply(((SnapshotLifecycleMetadata) part).snapshotConfigurations));
return new SnapshotLifecycleMetadata(newLifecycles, this.operationMode);
return new SnapshotLifecycleMetadata(newLifecycles, this.operationMode, this.slmStats);
}

@Override
Expand All @@ -168,6 +193,8 @@ public String getWriteableName() {
public void writeTo(StreamOutput out) throws IOException {
lifecycles.writeTo(out);
out.writeEnum(this.operationMode);
// TODO: version qualify this
this.slmStats.writeTo(out);
}

static Diff<SnapshotLifecyclePolicyMetadata> readLifecyclePolicyDiffFrom(StreamInput in) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

package org.elasticsearch.xpack.core.slm.action;

import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.xpack.slm.SnapshotLifecycleStats;

import java.io.IOException;
import java.util.Objects;

/**
* This class represents the action of retriving the stats for snapshot lifecycle management.
* These are retrieved from the master's cluster state and contain numbers related to the count of
* snapshots taken or deleted, as well as retention runs and time spent deleting snapshots.
*/
public class GetSnapshotLifecycleStatsAction extends ActionType<GetSnapshotLifecycleStatsAction.Response> {
public static final GetSnapshotLifecycleStatsAction INSTANCE = new GetSnapshotLifecycleStatsAction();
public static final String NAME = "cluster:admin/slm/stats";

protected GetSnapshotLifecycleStatsAction() {
super(NAME, GetSnapshotLifecycleStatsAction.Response::new);
}

public static class Request extends AcknowledgedRequest<GetSnapshotLifecycleStatsAction.Request> {

public Request() { }

public Request(StreamInput in) throws IOException {
super(in);
}

@Override
public ActionRequestValidationException validate() {
return null;
}

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

public static class Response extends ActionResponse implements ToXContentObject {

private SnapshotLifecycleStats slmStats;

public Response() { }

public Response(SnapshotLifecycleStats slmStats) {
this.slmStats = slmStats;
}

public Response(StreamInput in) throws IOException {
this.slmStats = new SnapshotLifecycleStats(in);
}

@Override
public String toString() {
return Strings.toString(this);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return this.slmStats.toXContent(builder, params);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
this.slmStats.writeTo(out);
}

@Override
public int hashCode() {
return Objects.hash(this.slmStats);
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj.getClass() != getClass()) {
return false;
}
GetSnapshotLifecycleStatsAction.Response other = (GetSnapshotLifecycleStatsAction.Response) obj;
return this.slmStats.equals(other.slmStats);
}
}

}
Loading