Skip to content

Commit 6500b0c

Browse files
authored
Expose retention leases in shard stats (#37991)
This commit exposes retention leases via shard-level stats.
1 parent c468b2f commit 6500b0c

File tree

15 files changed

+401
-44
lines changed

15 files changed

+401
-44
lines changed

server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.elasticsearch.common.io.stream.StreamOutput;
3838
import org.elasticsearch.index.IndexService;
3939
import org.elasticsearch.index.engine.CommitStats;
40+
import org.elasticsearch.index.seqno.RetentionLeaseStats;
4041
import org.elasticsearch.index.seqno.SeqNoStats;
4142
import org.elasticsearch.index.shard.IndexShard;
4243
import org.elasticsearch.indices.IndicesService;
@@ -101,21 +102,25 @@ protected ClusterStatsNodeResponse nodeOperation(ClusterStatsNodeRequest nodeReq
101102
// only report on fully started shards
102103
CommitStats commitStats;
103104
SeqNoStats seqNoStats;
105+
RetentionLeaseStats retentionLeaseStats;
104106
try {
105107
commitStats = indexShard.commitStats();
106108
seqNoStats = indexShard.seqNoStats();
107-
} catch (AlreadyClosedException e) {
109+
retentionLeaseStats = indexShard.getRetentionLeaseStats();
110+
} catch (final AlreadyClosedException e) {
108111
// shard is closed - no stats is fine
109112
commitStats = null;
110113
seqNoStats = null;
114+
retentionLeaseStats = null;
111115
}
112116
shardsStats.add(
113-
new ShardStats(
114-
indexShard.routingEntry(),
115-
indexShard.shardPath(),
116-
new CommonStats(indicesService.getIndicesQueryCache(), indexShard, SHARD_STATS_FLAGS),
117-
commitStats,
118-
seqNoStats));
117+
new ShardStats(
118+
indexShard.routingEntry(),
119+
indexShard.shardPath(),
120+
new CommonStats(indicesService.getIndicesQueryCache(), indexShard, SHARD_STATS_FLAGS),
121+
commitStats,
122+
seqNoStats,
123+
retentionLeaseStats));
119124
}
120125
}
121126
}

server/src/main/java/org/elasticsearch/action/admin/indices/stats/ShardStats.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,37 +26,58 @@
2626
import org.elasticsearch.common.io.stream.StreamOutput;
2727
import org.elasticsearch.common.io.stream.Streamable;
2828
import org.elasticsearch.common.io.stream.Writeable;
29-
import org.elasticsearch.common.xcontent.ToXContent.Params;
3029
import org.elasticsearch.common.xcontent.ToXContentFragment;
3130
import org.elasticsearch.common.xcontent.XContentBuilder;
3231
import org.elasticsearch.index.engine.CommitStats;
32+
import org.elasticsearch.index.seqno.RetentionLeaseStats;
3333
import org.elasticsearch.index.seqno.SeqNoStats;
3434
import org.elasticsearch.index.shard.ShardPath;
3535

3636
import java.io.IOException;
3737

3838
public class ShardStats implements Streamable, Writeable, ToXContentFragment {
39+
3940
private ShardRouting shardRouting;
4041
private CommonStats commonStats;
4142
@Nullable
4243
private CommitStats commitStats;
4344
@Nullable
4445
private SeqNoStats seqNoStats;
46+
47+
@Nullable
48+
private RetentionLeaseStats retentionLeaseStats;
49+
50+
/**
51+
* Gets the current retention lease stats.
52+
*
53+
* @return the current retention lease stats
54+
*/
55+
public RetentionLeaseStats getRetentionLeaseStats() {
56+
return retentionLeaseStats;
57+
}
58+
4559
private String dataPath;
4660
private String statePath;
4761
private boolean isCustomDataPath;
4862

4963
ShardStats() {
5064
}
5165

52-
public ShardStats(ShardRouting routing, ShardPath shardPath, CommonStats commonStats, CommitStats commitStats, SeqNoStats seqNoStats) {
66+
public ShardStats(
67+
final ShardRouting routing,
68+
final ShardPath shardPath,
69+
final CommonStats commonStats,
70+
final CommitStats commitStats,
71+
final SeqNoStats seqNoStats,
72+
final RetentionLeaseStats retentionLeaseStats) {
5373
this.shardRouting = routing;
5474
this.dataPath = shardPath.getRootDataPath().toString();
5575
this.statePath = shardPath.getRootStatePath().toString();
5676
this.isCustomDataPath = shardPath.isCustomDataPath();
5777
this.commitStats = commitStats;
5878
this.commonStats = commonStats;
5979
this.seqNoStats = seqNoStats;
80+
this.retentionLeaseStats = retentionLeaseStats;
6081
}
6182

6283
/**
@@ -109,6 +130,9 @@ public void readFrom(StreamInput in) throws IOException {
109130
if (in.getVersion().onOrAfter(Version.V_6_0_0_alpha1)) {
110131
seqNoStats = in.readOptionalWriteable(SeqNoStats::new);
111132
}
133+
if (in.getVersion().onOrAfter(Version.V_7_0_0)) {
134+
retentionLeaseStats = in.readOptionalWriteable(RetentionLeaseStats::new);
135+
}
112136
}
113137

114138
@Override
@@ -122,6 +146,9 @@ public void writeTo(StreamOutput out) throws IOException {
122146
if (out.getVersion().onOrAfter(Version.V_6_0_0_alpha1)) {
123147
out.writeOptionalWriteable(seqNoStats);
124148
}
149+
if (out.getVersion().onOrAfter(Version.V_7_0_0)) {
150+
out.writeOptionalWriteable(retentionLeaseStats);
151+
}
125152
}
126153

127154
@Override
@@ -140,6 +167,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
140167
if (seqNoStats != null) {
141168
seqNoStats.toXContent(builder, params);
142169
}
170+
if (retentionLeaseStats != null) {
171+
retentionLeaseStats.toXContent(builder, params);
172+
}
143173
builder.startObject(Fields.SHARD_PATH);
144174
builder.field(Fields.STATE_PATH, statePath);
145175
builder.field(Fields.DATA_PATH, dataPath);
@@ -159,4 +189,5 @@ static final class Fields {
159189
static final String NODE = "node";
160190
static final String RELOCATING_NODE = "relocating_node";
161191
}
192+
162193
}

server/src/main/java/org/elasticsearch/action/admin/indices/stats/TransportIndicesStatsAction.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.elasticsearch.common.io.stream.StreamInput;
3535
import org.elasticsearch.index.IndexService;
3636
import org.elasticsearch.index.engine.CommitStats;
37+
import org.elasticsearch.index.seqno.RetentionLeaseStats;
3738
import org.elasticsearch.index.seqno.SeqNoStats;
3839
import org.elasticsearch.index.shard.IndexShard;
3940
import org.elasticsearch.index.shard.ShardNotFoundException;
@@ -106,15 +107,23 @@ protected ShardStats shardOperation(IndicesStatsRequest request, ShardRouting sh
106107
CommonStats commonStats = new CommonStats(indicesService.getIndicesQueryCache(), indexShard, request.flags());
107108
CommitStats commitStats;
108109
SeqNoStats seqNoStats;
110+
RetentionLeaseStats retentionLeaseStats;
109111
try {
110112
commitStats = indexShard.commitStats();
111113
seqNoStats = indexShard.seqNoStats();
112-
} catch (AlreadyClosedException e) {
114+
retentionLeaseStats = indexShard.getRetentionLeaseStats();
115+
} catch (final AlreadyClosedException e) {
113116
// shard is closed - no stats is fine
114117
commitStats = null;
115118
seqNoStats = null;
119+
retentionLeaseStats = null;
116120
}
117-
return new ShardStats(indexShard.routingEntry(), indexShard.shardPath(), commonStats,
118-
commitStats, seqNoStats);
121+
return new ShardStats(
122+
indexShard.routingEntry(),
123+
indexShard.shardPath(),
124+
commonStats,
125+
commitStats,
126+
seqNoStats,
127+
retentionLeaseStats);
119128
}
120129
}

server/src/main/java/org/elasticsearch/index/seqno/RetentionLease.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
import java.util.Collection;
2929
import java.util.Collections;
3030
import java.util.Locale;
31+
import java.util.Map;
3132
import java.util.Objects;
33+
import java.util.function.Function;
3234
import java.util.stream.Collectors;
3335

3436
/**
@@ -242,4 +244,14 @@ public String toString() {
242244
'}';
243245
}
244246

247+
/**
248+
* A utility method to convert a collection of retention leases to a map from retention lease ID to retention lease.
249+
*
250+
* @param leases the leases
251+
* @return the map from retention lease ID to retention lease
252+
*/
253+
static Map<String, RetentionLease> toMap(final Collection<RetentionLease> leases) {
254+
return leases.stream().collect(Collectors.toMap(RetentionLease::id, Function.identity()));
255+
}
256+
245257
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.seqno;
21+
22+
import org.elasticsearch.common.io.stream.StreamInput;
23+
import org.elasticsearch.common.io.stream.StreamOutput;
24+
import org.elasticsearch.common.io.stream.Writeable;
25+
import org.elasticsearch.common.xcontent.ToXContentFragment;
26+
import org.elasticsearch.common.xcontent.XContentBuilder;
27+
28+
import java.io.IOException;
29+
import java.util.Collection;
30+
import java.util.Objects;
31+
32+
/**
33+
* Represents retention lease stats.
34+
*/
35+
public final class RetentionLeaseStats implements ToXContentFragment, Writeable {
36+
37+
private final Collection<RetentionLease> leases;
38+
39+
/**
40+
* The underlying retention leases backing this stats object.
41+
*
42+
* @return the leases
43+
*/
44+
public Collection<RetentionLease> leases() {
45+
return leases;
46+
}
47+
48+
/**
49+
* Constructs a new retention lease stats object from the specified leases.
50+
*
51+
* @param leases the leases
52+
*/
53+
public RetentionLeaseStats(final Collection<RetentionLease> leases) {
54+
this.leases = Objects.requireNonNull(leases);
55+
}
56+
57+
/**
58+
* Constructs a new retention lease stats object from a stream. The retention lease stats should have been written via
59+
* {@link #writeTo(StreamOutput)}.
60+
*
61+
* @param in the stream to construct the retention lease stats from
62+
* @throws IOException if an I/O exception occurs reading from the stream
63+
*/
64+
public RetentionLeaseStats(final StreamInput in) throws IOException {
65+
leases = in.readList(RetentionLease::new);
66+
}
67+
68+
/**
69+
* Writes a retention lease stats object to a stream in a manner suitable for later reconstruction via
70+
* {@link #RetentionLeaseStats(StreamInput)} (StreamInput)}.
71+
*
72+
* @param out the stream to write the retention lease stats to
73+
* @throws IOException if an I/O exception occurs writing to the stream
74+
*/
75+
@Override
76+
public void writeTo(final StreamOutput out) throws IOException {
77+
out.writeCollection(leases);
78+
}
79+
80+
/**
81+
* Converts the retention lease stats to {@link org.elasticsearch.common.xcontent.XContent} using the specified builder and pararms.
82+
*
83+
* @param builder the builder
84+
* @param params the params
85+
* @return the builder that these retention leases were converted to {@link org.elasticsearch.common.xcontent.XContent} into
86+
* @throws IOException if an I/O exception occurs writing to the builder
87+
*/
88+
@Override
89+
public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
90+
builder.startObject("retention_leases");
91+
{
92+
builder.startArray("leases");
93+
{
94+
for (final RetentionLease retentionLease : leases) {
95+
builder.startObject();
96+
{
97+
builder.field("id", retentionLease.id());
98+
builder.field("retaining_seq_no", retentionLease.retainingSequenceNumber());
99+
builder.field("timestamp", retentionLease.timestamp());
100+
builder.field("source", retentionLease.source());
101+
}
102+
builder.endObject();
103+
}
104+
}
105+
builder.endArray();
106+
}
107+
builder.endObject();
108+
return builder;
109+
}
110+
111+
@Override
112+
public boolean equals(Object o) {
113+
if (this == o) return true;
114+
if (o == null || getClass() != o.getClass()) return false;
115+
final RetentionLeaseStats that = (RetentionLeaseStats) o;
116+
return Objects.equals(leases, that.leases);
117+
}
118+
119+
@Override
120+
public int hashCode() {
121+
return Objects.hash(leases);
122+
}
123+
124+
}

server/src/main/java/org/elasticsearch/index/shard/IndexShard.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
import org.elasticsearch.index.search.stats.ShardSearchStats;
109109
import org.elasticsearch.index.seqno.ReplicationTracker;
110110
import org.elasticsearch.index.seqno.RetentionLease;
111+
import org.elasticsearch.index.seqno.RetentionLeaseStats;
111112
import org.elasticsearch.index.seqno.SeqNoStats;
112113
import org.elasticsearch.index.seqno.SequenceNumbers;
113114
import org.elasticsearch.index.shard.PrimaryReplicaSyncer.ResyncTask;
@@ -1895,6 +1896,11 @@ public Collection<RetentionLease> getRetentionLeases() {
18951896
return replicationTracker.getRetentionLeases();
18961897
}
18971898

1899+
public RetentionLeaseStats getRetentionLeaseStats() {
1900+
verifyNotClosed();
1901+
return new RetentionLeaseStats(getRetentionLeases());
1902+
}
1903+
18981904
/**
18991905
* Adds a new retention lease.
19001906
*

server/src/main/java/org/elasticsearch/indices/IndicesService.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
import org.elasticsearch.index.recovery.RecoveryStats;
9696
import org.elasticsearch.index.refresh.RefreshStats;
9797
import org.elasticsearch.index.search.stats.SearchStats;
98+
import org.elasticsearch.index.seqno.RetentionLeaseStats;
9899
import org.elasticsearch.index.seqno.RetentionLeaseSyncer;
99100
import org.elasticsearch.index.seqno.SeqNoStats;
100101
import org.elasticsearch.index.shard.IllegalIndexShardStateException;
@@ -367,23 +368,29 @@ IndexShardStats indexShardStats(final IndicesService indicesService, final Index
367368

368369
CommitStats commitStats;
369370
SeqNoStats seqNoStats;
371+
RetentionLeaseStats retentionLeaseStats;
370372
try {
371373
commitStats = indexShard.commitStats();
372374
seqNoStats = indexShard.seqNoStats();
375+
retentionLeaseStats = indexShard.getRetentionLeaseStats();
373376
} catch (AlreadyClosedException e) {
374377
// shard is closed - no stats is fine
375378
commitStats = null;
376379
seqNoStats = null;
380+
retentionLeaseStats = null;
377381
}
378382

379-
return new IndexShardStats(indexShard.shardId(),
380-
new ShardStats[] {
381-
new ShardStats(indexShard.routingEntry(),
382-
indexShard.shardPath(),
383-
new CommonStats(indicesService.getIndicesQueryCache(), indexShard, flags),
384-
commitStats,
385-
seqNoStats)
386-
});
383+
return new IndexShardStats(
384+
indexShard.shardId(),
385+
new ShardStats[]{
386+
new ShardStats(
387+
indexShard.routingEntry(),
388+
indexShard.shardPath(),
389+
new CommonStats(indicesService.getIndicesQueryCache(), indexShard, flags),
390+
commitStats,
391+
seqNoStats,
392+
retentionLeaseStats)
393+
});
387394
}
388395

389396
/**

server/src/test/java/org/elasticsearch/cluster/DiskUsageTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ public void testFillShardLevelInfo() {
113113
CommonStats commonStats1 = new CommonStats();
114114
commonStats1.store = new StoreStats(1000);
115115
ShardStats[] stats = new ShardStats[] {
116-
new ShardStats(test_0, new ShardPath(false, test0Path, test0Path, test_0.shardId()), commonStats0 , null, null),
117-
new ShardStats(test_1, new ShardPath(false, test1Path, test1Path, test_1.shardId()), commonStats1 , null, null)
116+
new ShardStats(test_0, new ShardPath(false, test0Path, test0Path, test_0.shardId()), commonStats0 , null, null, null),
117+
new ShardStats(test_1, new ShardPath(false, test1Path, test1Path, test_1.shardId()), commonStats1 , null, null, null)
118118
};
119119
ImmutableOpenMap.Builder<String, Long> shardSizes = ImmutableOpenMap.builder();
120120
ImmutableOpenMap.Builder<ShardRouting, String> routingToPath = ImmutableOpenMap.builder();

0 commit comments

Comments
 (0)