Skip to content

Commit 8c581c8

Browse files
committed
Added support for snapshot related metrics
1 parent 486ca19 commit 8c581c8

File tree

8 files changed

+215
-12
lines changed

8 files changed

+215
-12
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ dependencies {
101101

102102
restResources {
103103
restApi {
104-
includeCore '_common', 'cat', 'cluster', 'nodes', 'indices', 'index'
104+
includeCore '_common', 'cat', 'cluster', 'nodes', 'indices', 'index', 'snapshot'
105105
}
106106
}
107107

src/main/java/org/compuscene/metrics/prometheus/PrometheusMetricsCollector.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.compuscene.metrics.prometheus;
1919

2020
import org.opensearch.action.ClusterStatsData;
21+
import org.opensearch.action.SnapshotsResponse;
2122
import org.opensearch.action.admin.cluster.health.ClusterHealthResponse;
2223
import org.opensearch.action.admin.cluster.node.stats.NodeStats;
2324
import org.opensearch.action.admin.indices.stats.CommonStats;
@@ -37,6 +38,8 @@
3738
import org.opensearch.monitor.os.OsStats;
3839
import org.opensearch.monitor.process.ProcessStats;
3940
import org.opensearch.script.ScriptStats;
41+
import org.opensearch.snapshots.SnapshotInfo;
42+
import org.opensearch.snapshots.SnapshotState;
4043
import org.opensearch.threadpool.ThreadPoolStats;
4144
import org.opensearch.transport.TransportStats;
4245

@@ -54,19 +57,23 @@ public class PrometheusMetricsCollector {
5457

5558
private boolean isPrometheusClusterSettings;
5659
private boolean isPrometheusIndices;
60+
private boolean isPrometheusSnapshots;
5761
private PrometheusMetricsCatalog catalog;
5862

5963
/**
6064
* A constructor.
6165
* @param catalog {@link PrometheusMetricsCatalog}
6266
* @param isPrometheusIndices boolean flag for index level metric
67+
* @param isPrometheusSnapshots boolean flag for snapshots related metrics
6368
* @param isPrometheusClusterSettings boolean flag cluster settings metrics
6469
*/
6570
public PrometheusMetricsCollector(PrometheusMetricsCatalog catalog,
6671
boolean isPrometheusIndices,
72+
boolean isPrometheusSnapshots,
6773
boolean isPrometheusClusterSettings) {
6874
this.isPrometheusClusterSettings = isPrometheusClusterSettings;
6975
this.isPrometheusIndices = isPrometheusIndices;
76+
this.isPrometheusSnapshots = isPrometheusSnapshots;
7077
this.catalog = catalog;
7178
}
7279

@@ -80,6 +87,7 @@ public void registerMetrics() {
8087
registerNodeMetrics();
8188
registerIndicesMetrics();
8289
registerPerIndexMetrics();
90+
registerSnapshotMetrics();
8391
registerTransportMetrics();
8492
registerHTTPMetrics();
8593
registerThreadPoolMetrics();
@@ -465,6 +473,30 @@ private void updatePerIndexMetrics(@Nullable ClusterHealthResponse chr, @Nullabl
465473
}
466474
}
467475

476+
@SuppressWarnings("checkstyle:LineLength")
477+
private void registerSnapshotMetrics() {
478+
catalog.registerClusterGauge("min_snapshot_age", "Time elapsed in milliseconds since the most recent successful snapshot's start time", "sm_policy");
479+
}
480+
481+
private void updateSnapshotsMetrics(@Nullable SnapshotsResponse snapshotsResponse) {
482+
if (snapshotsResponse == null) {
483+
return;
484+
}
485+
Map<String, Long> smPolicyMinSnapshotAge = new HashMap<>();
486+
for (SnapshotInfo snapshotInfo : snapshotsResponse.getSnapshotInfos()) {
487+
// emit snapshot_age metric only for successful snapshots
488+
if (snapshotInfo.state() != SnapshotState.SUCCESS) {
489+
continue;
490+
}
491+
String smPolicy = snapshotInfo.userMetadata() == null ? "adhoc" : snapshotInfo.userMetadata().getOrDefault("sm_policy", "adhoc").toString();
492+
long snapshotAge = System.currentTimeMillis() - snapshotInfo.startTime();
493+
smPolicyMinSnapshotAge.compute(smPolicy, (key, oldValue) -> oldValue == null ? snapshotAge : Math.min(oldValue, snapshotAge));
494+
}
495+
for(Map.Entry<String, Long> entry : smPolicyMinSnapshotAge.entrySet()) {
496+
catalog.setClusterGauge("min_snapshot_age", entry.getValue(), entry.getKey());
497+
}
498+
}
499+
468500
@SuppressWarnings("checkstyle:LineLength")
469501
private void updatePerIndexContextMetrics(String indexName, String context, CommonStats idx) {
470502
catalog.setClusterGauge("index_doc_number", idx.getDocs().getCount(), indexName, context);
@@ -920,12 +952,14 @@ private void updateESSettings(@Nullable ClusterStatsData stats) {
920952
* @param nodeStats NodeStats filtered using nodes filter
921953
* @param indicesStats IndicesStatsResponse
922954
* @param clusterStatsData ClusterStatsData
955+
* @param snapshotsResponse SnapshotsResponse
923956
*/
924957
public void updateMetrics(String originNodeName, String originNodeId,
925958
@Nullable ClusterHealthResponse clusterHealthResponse,
926959
NodeStats[] nodeStats,
927960
@Nullable IndicesStatsResponse indicesStats,
928-
@Nullable ClusterStatsData clusterStatsData) {
961+
@Nullable ClusterStatsData clusterStatsData,
962+
@Nullable SnapshotsResponse snapshotsResponse) {
929963
Summary.Timer timer = catalog.startSummaryTimer(
930964
new Tuple<>(originNodeName, originNodeId),
931965
"metrics_generate_time_seconds");
@@ -956,7 +990,9 @@ public void updateMetrics(String originNodeName, String originNodeId,
956990
if (isPrometheusClusterSettings) {
957991
updateESSettings(clusterStatsData);
958992
}
959-
993+
if (isPrometheusSnapshots) {
994+
updateSnapshotsMetrics(snapshotsResponse);
995+
}
960996
timer.observeDuration();
961997
}
962998

src/main/java/org/compuscene/metrics/prometheus/PrometheusSettings.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public enum INDEX_FILTER_OPTIONS {
4949

5050
static String PROMETHEUS_CLUSTER_SETTINGS_KEY = "prometheus.cluster.settings";
5151
static String PROMETHEUS_INDICES_KEY = "prometheus.indices";
52+
static String PROMETHEUS_SNAPSHOTS_KEY = "prometheus.snapshots";
5253
static String PROMETHEUS_NODES_FILTER_KEY = "prometheus.nodes.filter";
5354
static String PROMETHEUS_SELECTED_INDICES_KEY = "prometheus.indices_filter.selected_indices";
5455
static String PROMETHEUS_SELECTED_OPTION_KEY = "prometheus.indices_filter.selected_option";
@@ -69,6 +70,14 @@ public enum INDEX_FILTER_OPTIONS {
6970
Setting.boolSetting(PROMETHEUS_INDICES_KEY, true,
7071
Setting.Property.Dynamic, Setting.Property.NodeScope);
7172

73+
/**
74+
* This setting is used configure weather to expose snapshot metrics or not. The default value is false.
75+
* Can be configured in opensearch.yml file or update dynamically under key {@link #PROMETHEUS_SNAPSHOTS_KEY}.
76+
*/
77+
public static final Setting<Boolean> PROMETHEUS_SNAPSHOTS =
78+
Setting.boolSetting(PROMETHEUS_SNAPSHOTS_KEY, false,
79+
Setting.Property.Dynamic, Setting.Property.NodeScope);
80+
7281
/**
7382
* This setting is used configure which cluster nodes to gather metrics from. The default value is _local.
7483
* Can be configured in opensearch.yml file or update dynamically under key {@link #PROMETHEUS_NODES_FILTER_KEY}.
@@ -97,6 +106,7 @@ public enum INDEX_FILTER_OPTIONS {
97106

98107
private volatile boolean clusterSettings;
99108
private volatile boolean indices;
109+
private volatile boolean snapshots;
100110
private volatile String nodesFilter;
101111
private volatile String selectedIndices;
102112
private volatile INDEX_FILTER_OPTIONS selectedOption;
@@ -109,11 +119,13 @@ public enum INDEX_FILTER_OPTIONS {
109119
public PrometheusSettings(Settings settings, ClusterSettings clusterSettings) {
110120
setPrometheusClusterSettings(PROMETHEUS_CLUSTER_SETTINGS.get(settings));
111121
setPrometheusIndices(PROMETHEUS_INDICES.get(settings));
122+
setPrometheusSnapshots(PROMETHEUS_SNAPSHOTS.get(settings));
112123
setPrometheusNodesFilter(PROMETHEUS_NODES_FILTER.get(settings));
113124
setPrometheusSelectedIndices(PROMETHEUS_SELECTED_INDICES.get(settings));
114125
setPrometheusSelectedOption(PROMETHEUS_SELECTED_OPTION.get(settings));
115126
clusterSettings.addSettingsUpdateConsumer(PROMETHEUS_CLUSTER_SETTINGS, this::setPrometheusClusterSettings);
116127
clusterSettings.addSettingsUpdateConsumer(PROMETHEUS_INDICES, this::setPrometheusIndices);
128+
clusterSettings.addSettingsUpdateConsumer(PROMETHEUS_SNAPSHOTS, this::setPrometheusSnapshots);
117129
clusterSettings.addSettingsUpdateConsumer(PROMETHEUS_NODES_FILTER, this::setPrometheusNodesFilter);
118130
clusterSettings.addSettingsUpdateConsumer(PROMETHEUS_SELECTED_INDICES, this::setPrometheusSelectedIndices);
119131
clusterSettings.addSettingsUpdateConsumer(PROMETHEUS_SELECTED_OPTION, this::setPrometheusSelectedOption);
@@ -127,6 +139,10 @@ private void setPrometheusIndices(boolean flag) {
127139
this.indices = flag;
128140
}
129141

142+
private void setPrometheusSnapshots(boolean flag) {
143+
this.snapshots = flag;
144+
}
145+
130146
private void setPrometheusNodesFilter(String filter) { this.nodesFilter = filter; }
131147

132148
private void setPrometheusSelectedIndices(String selectedIndices) {
@@ -153,6 +169,14 @@ public boolean getPrometheusIndices() {
153169
return this.indices;
154170
}
155171

172+
/**
173+
* Get value of settings key {@link #PROMETHEUS_SNAPSHOTS_KEY}.
174+
* @return boolean value of the key
175+
*/
176+
public boolean getPrometheusSnapshots() {
177+
return this.snapshots;
178+
}
179+
156180
/**
157181
* Get value of settings key {@link #PROMETHEUS_NODES_FILTER_KEY}.
158182
* @return boolean value of the key

src/main/java/org/opensearch/action/NodePrometheusMetricsResponse.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class NodePrometheusMetricsResponse extends ActionResponse {
4343
private final NodeStats[] nodeStats;
4444
@Nullable private final IndicesStatsResponse indicesStats;
4545
private ClusterStatsData clusterStatsData = null;
46+
@Nullable private final SnapshotsResponse snapshotsResponse;
4647

4748
/**
4849
* A constructor that materialize the instance from inputStream.
@@ -56,6 +57,7 @@ public NodePrometheusMetricsResponse(StreamInput in) throws IOException {
5657
nodeStats = in.readArray(NodeStats::new, NodeStats[]::new);
5758
indicesStats = PackageAccessHelper.createIndicesStatsResponse(in);
5859
clusterStatsData = new ClusterStatsData(in);
60+
snapshotsResponse = new SnapshotsResponse(in);
5961
}
6062

6163
/**
@@ -65,6 +67,7 @@ public NodePrometheusMetricsResponse(StreamInput in) throws IOException {
6567
* @param nodesStats NodesStats
6668
* @param indicesStats IndicesStats
6769
* @param clusterStateResponse ClusterStateResponse
70+
* @param snapshotsResponse SnapshotsResponse
6871
* @param settings Settings
6972
* @param clusterSettings ClusterSettings
7073
*/
@@ -73,6 +76,7 @@ public NodePrometheusMetricsResponse(ClusterHealthResponse clusterHealth,
7376
NodeStats[] nodesStats,
7477
@Nullable IndicesStatsResponse indicesStats,
7578
@Nullable ClusterStateResponse clusterStateResponse,
79+
@Nullable SnapshotsResponse snapshotsResponse,
7680
Settings settings,
7781
ClusterSettings clusterSettings) {
7882
this.clusterHealth = clusterHealth;
@@ -82,6 +86,7 @@ public NodePrometheusMetricsResponse(ClusterHealthResponse clusterHealth,
8286
if (clusterStateResponse != null) {
8387
this.clusterStatsData = new ClusterStatsData(clusterStateResponse, settings, clusterSettings);
8488
}
89+
this.snapshotsResponse = snapshotsResponse;
8590
}
8691

8792
/**
@@ -106,6 +111,15 @@ public NodeStats[] getNodeStats() {
106111
return this.nodeStats;
107112
}
108113

114+
/**
115+
* Get internal {@link SnapshotsResponse} object.
116+
* @return SnapshotsResponse object
117+
*/
118+
@Nullable
119+
public SnapshotsResponse getSnapshotsResponse() {
120+
return this.snapshotsResponse;
121+
}
122+
109123
/**
110124
* Get internal {@link IndicesStatsResponse} object.
111125
* @return IndicesStatsResponse object
@@ -131,5 +145,6 @@ public void writeTo(StreamOutput out) throws IOException {
131145
out.writeArray(nodeStats);
132146
out.writeOptionalWriteable(indicesStats);
133147
clusterStatsData.writeTo(out);
148+
snapshotsResponse.writeTo(out);
134149
}
135150
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright [2018] [Vincent VAN HOLLEBEKE]
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package org.opensearch.action;
19+
20+
import org.opensearch.core.action.ActionResponse;
21+
import org.opensearch.core.common.io.stream.StreamInput;
22+
import org.opensearch.core.common.io.stream.StreamOutput;
23+
import org.opensearch.snapshots.SnapshotInfo;
24+
25+
import java.io.IOException;
26+
import java.util.Collections;
27+
import java.util.List;
28+
29+
/**
30+
* Represents a container class for holding response data related to snapshots.
31+
*/
32+
public class SnapshotsResponse extends ActionResponse {
33+
private final List<SnapshotInfo> snapshotInfos;
34+
35+
/**
36+
* A constructor.
37+
* @param in A streamInput to materialize the instance from
38+
* @throws IOException if there is an exception reading from inputStream
39+
*/
40+
public SnapshotsResponse(StreamInput in) throws IOException {
41+
super(in);
42+
snapshotInfos = in.readList(SnapshotInfo::new);
43+
}
44+
45+
/**
46+
* A constructor.
47+
*
48+
* @param snapshotInfos A list of {@link SnapshotInfo} objects to initialize the instance with.
49+
*/
50+
public SnapshotsResponse(List<SnapshotInfo> snapshotInfos) {
51+
this.snapshotInfos = Collections.unmodifiableList(snapshotInfos);
52+
}
53+
54+
/**
55+
* Writes the instance into {@link StreamOutput}.
56+
*
57+
* @param out the output stream to which the instance is to be written
58+
* @throws IOException if there is an exception writing to the output stream
59+
*/
60+
@Override
61+
public void writeTo(StreamOutput out) throws IOException {
62+
out.writeCollection(snapshotInfos);
63+
}
64+
65+
/**
66+
* Getter for {@code snapshotInfos} list.
67+
* The returned list is unmodifiable to ensure immutability.
68+
*
69+
* @return the list of {@link SnapshotInfo} objects
70+
*/
71+
public List<SnapshotInfo> getSnapshotInfos() {
72+
return snapshotInfos;
73+
}
74+
}

0 commit comments

Comments
 (0)