Skip to content

Commit a3a4058

Browse files
committed
Added integration test for snapshots metrics
Signed-off-by: Smit Patel <[email protected]>
1 parent 2ac18e9 commit a3a4058

File tree

6 files changed

+110
-31
lines changed

6 files changed

+110
-31
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ To disable exporting cluster settings use:
145145
prometheus.cluster.settings: false
146146
```
147147

148+
#### Snapshot metrics
149+
150+
To enable exporting snapshot metrics use:
151+
```
152+
prometheus.snapshots: true
153+
```
154+
148155
#### Nodes filter
149156

150157
Metrics include statistics about individual OpenSearch nodes.

build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import org.opensearch.gradle.PropertyNormalization
12
import org.opensearch.gradle.test.RestIntegTestTask
23

34
import java.util.regex.Matcher
@@ -124,8 +125,13 @@ tasks.named("check").configure { dependsOn(integTest) }
124125
// Temporary disable task :testingConventions
125126
testingConventions.enabled = false
126127

128+
// Directory for snapshot repository
129+
File repositoryDir = new File(project.buildDir, "shared-repository")
130+
127131
testClusters.all {
128132
numberOfNodes = 2
133+
// Configuring repo path for 'fs' type snapshot repository
134+
setting 'path.repo', "${repositoryDir.absolutePath}", PropertyNormalization.IGNORE_VALUE
129135

130136
// It seems cluster name can not be customized here. It gives an error:
131137
// Testclusters does not allow the following settings to be changed:[cluster.name] for node{::yamlRestTest-0}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,23 @@ public enum INDEX_FILTER_OPTIONS {
5555
static String PROMETHEUS_SELECTED_OPTION_KEY = "prometheus.indices_filter.selected_option";
5656

5757
/**
58-
* This setting is used configure weather to expose cluster settings metrics or not. The default value is true.
58+
* This setting is used configure whether to expose cluster settings metrics or not. The default value is true.
5959
* Can be configured in opensearch.yml file or update dynamically under key {@link #PROMETHEUS_CLUSTER_SETTINGS_KEY}.
6060
*/
6161
public static final Setting<Boolean> PROMETHEUS_CLUSTER_SETTINGS =
6262
Setting.boolSetting(PROMETHEUS_CLUSTER_SETTINGS_KEY, true,
6363
Setting.Property.Dynamic, Setting.Property.NodeScope);
6464

6565
/**
66-
* This setting is used configure weather to expose low level index metrics or not. The default value is true.
66+
* This setting is used configure whether to expose low level index metrics or not. The default value is true.
6767
* Can be configured in opensearch.yml file or update dynamically under key {@link #PROMETHEUS_INDICES_KEY}.
6868
*/
6969
public static final Setting<Boolean> PROMETHEUS_INDICES =
7070
Setting.boolSetting(PROMETHEUS_INDICES_KEY, true,
7171
Setting.Property.Dynamic, Setting.Property.NodeScope);
7272

7373
/**
74-
* This setting is used configure weather to expose snapshot metrics or not. The default value is false.
74+
* This setting is used configure whether to expose snapshot metrics or not. The default value is false.
7575
* Can be configured in opensearch.yml file or update dynamically under key {@link #PROMETHEUS_SNAPSHOTS_KEY}.
7676
*/
7777
public static final Setting<Boolean> PROMETHEUS_SNAPSHOTS =

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.opensearch.snapshots.SnapshotInfo;
2424

2525
import java.io.IOException;
26+
import java.util.ArrayList;
2627
import java.util.Collections;
2728
import java.util.List;
2829

@@ -39,16 +40,14 @@ public class SnapshotsResponse extends ActionResponse {
3940
*/
4041
public SnapshotsResponse(StreamInput in) throws IOException {
4142
super(in);
42-
snapshotInfos = in.readList(SnapshotInfo::new);
43+
snapshotInfos = Collections.synchronizedList(in.readList(SnapshotInfo::new));
4344
}
4445

4546
/**
4647
* A constructor.
47-
*
48-
* @param snapshotInfos A list of {@link SnapshotInfo} objects to initialize the instance with.
4948
*/
50-
public SnapshotsResponse(List<SnapshotInfo> snapshotInfos) {
51-
this.snapshotInfos = Collections.unmodifiableList(snapshotInfos);
49+
public SnapshotsResponse() {
50+
this.snapshotInfos = Collections.synchronizedList(new ArrayList<>());
5251
}
5352

5453
/**
@@ -64,11 +63,17 @@ public void writeTo(StreamOutput out) throws IOException {
6463

6564
/**
6665
* Getter for {@code snapshotInfos} list.
67-
* The returned list is unmodifiable to ensure immutability.
6866
*
6967
* @return the list of {@link SnapshotInfo} objects
7068
*/
7169
public List<SnapshotInfo> getSnapshotInfos() {
7270
return snapshotInfos;
7371
}
74-
}
72+
73+
/**
74+
* Adds {@code snapshotInfosToAdd} to the {@code snapshotInfos} list.
75+
*/
76+
public void addSnapshotInfos(List<SnapshotInfo> snapshotInfosToAdd) {
77+
snapshotInfos.addAll(snapshotInfosToAdd);
78+
}
79+
}

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

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,17 @@
4040
import org.opensearch.action.support.HandledTransportAction;
4141
import org.opensearch.client.Client;
4242
import org.opensearch.client.Requests;
43+
import org.opensearch.cluster.metadata.RepositoryMetadata;
4344
import org.opensearch.common.Nullable;
44-
import org.opensearch.common.action.ActionFuture;
4545
import org.opensearch.common.inject.Inject;
4646
import org.opensearch.common.settings.ClusterSettings;
4747
import org.opensearch.common.settings.Settings;
4848
import org.opensearch.core.action.ActionListener;
49-
import org.opensearch.snapshots.SnapshotInfo;
5049
import org.opensearch.tasks.Task;
5150
import org.opensearch.transport.TransportService;
5251

53-
import java.util.ArrayList;
54-
import java.util.List;
55-
import java.util.concurrent.ExecutionException;
52+
import java.util.Queue;
53+
import java.util.concurrent.ConcurrentLinkedQueue;
5654
import java.util.stream.Collectors;
5755

5856
/**
@@ -111,7 +109,8 @@ private class AsyncAction {
111109
private NodesStatsResponse nodesStatsResponse = null;
112110
private IndicesStatsResponse indicesStatsResponse = null;
113111
private ClusterStateResponse clusterStateResponse = null;
114-
private SnapshotsResponse snapshotsResponse = null;
112+
private final Queue<String> snapshotRepositories = new ConcurrentLinkedQueue<>();
113+
private final SnapshotsResponse snapshotsResponse = new SnapshotsResponse();
115114

116115
// read the state of prometheus dynamic settings only once at the beginning of the async request
117116
private final boolean isPrometheusIndices = prometheusSettings.getPrometheusIndices();
@@ -176,22 +175,14 @@ private void gatherRequests() {
176175
new ActionListener<GetRepositoriesResponse>() {
177176
@Override
178177
public void onResponse(GetRepositoriesResponse response) {
179-
List<ActionFuture<GetSnapshotsResponse>> snapshotsResponseFutures = response.repositories().stream()
180-
.map(metadata -> new GetSnapshotsRequest(metadata.name()))
181-
.map(snapshotsRequest -> client.admin().cluster().getSnapshots(snapshotsRequest))
182-
.collect(Collectors.toList());
183-
List<SnapshotInfo> snapshotInfos = new ArrayList<>();
184-
for (ActionFuture<GetSnapshotsResponse> snapshotsResponseFuture : snapshotsResponseFutures) {
185-
try {
186-
GetSnapshotsResponse getSnapshotsResponse = snapshotsResponseFuture.get();
187-
snapshotInfos.addAll(getSnapshotsResponse.getSnapshots());
188-
} catch (InterruptedException | ExecutionException e) {
189-
listener.onFailure(new OpenSearchException("Get snapshots request failed", e));
190-
return;
191-
}
178+
if (response.repositories().isEmpty()) {
179+
gatherRequests();
180+
return;
192181
}
193-
snapshotsResponse = new SnapshotsResponse(snapshotInfos);
194-
gatherRequests();
182+
snapshotRepositories.addAll(response.repositories().stream()
183+
.map(RepositoryMetadata::name).collect(Collectors.toList()));
184+
String snapshotRepository = snapshotRepositories.poll();
185+
client.admin().cluster().getSnapshots(new GetSnapshotsRequest(snapshotRepository), snapshotsResponseActionListener);
195186
}
196187

197188
@Override
@@ -200,6 +191,26 @@ public void onFailure(Exception e) {
200191
}
201192
};
202193

194+
private final ActionListener<GetSnapshotsResponse> snapshotsResponseActionListener =
195+
new ActionListener<GetSnapshotsResponse>() {
196+
@Override
197+
public void onResponse(GetSnapshotsResponse response) {
198+
snapshotsResponse.addSnapshotInfos(response.getSnapshots());
199+
if (snapshotRepositories.isEmpty()) {
200+
gatherRequests();
201+
return;
202+
}
203+
// Fetch the snapshots for the next repository in the queue
204+
String snapshotRepository = snapshotRepositories.poll();
205+
client.admin().cluster().getSnapshots(new GetSnapshotsRequest(snapshotRepository), snapshotsResponseActionListener);
206+
}
207+
208+
@Override
209+
public void onFailure(Exception e) {
210+
listener.onFailure(new OpenSearchException("Get snapshots request failed", e));
211+
}
212+
};
213+
203214
private final ActionListener<ClusterStateResponse> clusterStateResponseActionListener =
204215
new ActionListener<ClusterStateResponse>() {
205216
@Override
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
"Verify snapshots metrics enabled":
3+
4+
# Create 'fs' snapshot repository
5+
- do:
6+
snapshot.create_repository:
7+
repository: test_repo_get_1
8+
body:
9+
type: fs
10+
settings:
11+
location: "test_repo_get_1_loc"
12+
13+
- do:
14+
snapshot.get_repository: { }
15+
16+
- is_true: test_repo_get_1
17+
18+
# Enable snapshots metrics
19+
- do:
20+
cluster.put_settings:
21+
body:
22+
persistent:
23+
prometheus.snapshots: "true"
24+
flat_settings: true
25+
26+
- match: { persistent: { prometheus.snapshots: "true" } }
27+
28+
# Create snapshot
29+
- do:
30+
snapshot.create:
31+
repository: test_repo_get_1
32+
snapshot: test_snapshot_1
33+
wait_for_completion: true
34+
35+
- match: { snapshot.snapshot: test_snapshot_1 }
36+
- match: { snapshot.state : SUCCESS }
37+
38+
# Fetch and verify metrics
39+
- do:
40+
prometheus.metrics: {}
41+
42+
- match:
43+
$body: |
44+
/.*
45+
\# \s* HELP \s+ opensearch_min_snapshot_age \s+.*\n
46+
\# \s* TYPE \s+ opensearch_min_snapshot_age \s+ gauge\n
47+
opensearch_min_snapshot_age\{
48+
cluster="yamlRestTest",sm_policy="adhoc",
49+
\}\s+\d+\.\d+\n
50+
.*/

0 commit comments

Comments
 (0)