Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions docs/changelog/116339.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 116339
summary: "Index stats enhancement: creation date and `tier_preference`"
area: Stats
type: feature
issues: []
5 changes: 5 additions & 0 deletions docs/changelog/116867.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 116867
summary: "Index stats enhancement: creation date and `tier_preference`"
area: Stats
type: feature
issues: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"Ensure index creation date and tier preference are exposed":
- requires:
cluster_features: ["stats.tier_creation_date"]
reason: index creation date and tier preference added to stats in 8.17

- do:
indices.create:
index: myindex
- do:
indices.stats: {}

- is_true: indices.myindex.creation_date
- is_true: indices.myindex.tier_preference
1 change: 1 addition & 0 deletions server/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@

provides org.elasticsearch.features.FeatureSpecification
with
org.elasticsearch.action.admin.indices.stats.IndicesStatsFeatures,
org.elasticsearch.action.bulk.BulkFeatures,
org.elasticsearch.features.FeatureInfrastructureFeatures,
org.elasticsearch.health.HealthFeatures,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ static TransportVersion def(int id) {
public static final TransportVersion VERTEX_AI_INPUT_TYPE_ADDED = def(8_790_00_0);
public static final TransportVersion SKIP_INNER_HITS_SEARCH_SOURCE = def(8_791_00_0);
public static final TransportVersion QUERY_RULES_LIST_INCLUDES_TYPES = def(8_792_00_0);
public static final TransportVersion INDEX_STATS_ADDITIONAL_FIELDS = def(8_793_00_0);

/*
* STOP! READ THIS FIRST! No, really,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.features.NodeFeature;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -21,6 +22,8 @@

public class IndexStats implements Iterable<IndexShardStats> {

public static final NodeFeature TIER_CREATION_DATE = new NodeFeature("stats.tier_creation_date");

private final String index;

private final String uuid;
Expand All @@ -29,19 +32,27 @@ public class IndexStats implements Iterable<IndexShardStats> {

private final IndexMetadata.State state;

private final List<String> tierPreference;

private final Long creationDate;

private final ShardStats shards[];

public IndexStats(
String index,
String uuid,
@Nullable ClusterHealthStatus health,
@Nullable IndexMetadata.State state,
@Nullable List<String> tierPreference,
@Nullable Long creationDate,
ShardStats[] shards
) {
this.index = index;
this.uuid = uuid;
this.health = health;
this.state = state;
this.tierPreference = tierPreference;
this.creationDate = creationDate;
this.shards = shards;
}

Expand All @@ -61,6 +72,14 @@ public IndexMetadata.State getState() {
return state;
}

public List<String> getTierPreference() {
return tierPreference;
}

public Long getCreationDate() {
return creationDate;
}

public ShardStats[] getShards() {
return this.shards;
}
Expand Down Expand Up @@ -129,13 +148,24 @@ public static class IndexStatsBuilder {
private final String uuid;
private final ClusterHealthStatus health;
private final IndexMetadata.State state;
private final List<String> tierPreference;
private final Long creationDate;
private final List<ShardStats> shards = new ArrayList<>();

public IndexStatsBuilder(String indexName, String uuid, @Nullable ClusterHealthStatus health, @Nullable IndexMetadata.State state) {
public IndexStatsBuilder(
String indexName,
String uuid,
@Nullable ClusterHealthStatus health,
@Nullable IndexMetadata.State state,
@Nullable List<String> tierPreference,
@Nullable Long creationDate
) {
this.indexName = indexName;
this.uuid = uuid;
this.health = health;
this.state = state;
this.tierPreference = tierPreference;
this.creationDate = creationDate;
}

public IndexStatsBuilder add(ShardStats shardStats) {
Expand All @@ -144,7 +174,15 @@ public IndexStatsBuilder add(ShardStats shardStats) {
}

public IndexStats build() {
return new IndexStats(indexName, uuid, health, state, shards.toArray(new ShardStats[shards.size()]));
return new IndexStats(
indexName,
uuid,
health,
state,
tierPreference,
creationDate,
shards.toArray(new ShardStats[shards.size()])
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.action.admin.indices.stats;

import org.elasticsearch.features.FeatureSpecification;
import org.elasticsearch.features.NodeFeature;

import java.util.Set;

public class IndicesStatsFeatures implements FeatureSpecification {

@Override
public Set<NodeFeature> getFeatures() {
return Set.of(IndexStats.TIER_CREATION_DATE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,34 @@ public class IndicesStatsResponse extends ChunkedBroadcastResponse {

private final Map<String, IndexMetadata.State> indexStateMap;

private final Map<String, List<String>> indexTierPreferenceMap;

private final Map<String, Long> indexCreationDateMap;

private final ShardStats[] shards;

private Map<ShardRouting, ShardStats> shardStatsMap;

IndicesStatsResponse(StreamInput in) throws IOException {
super(in);
shards = in.readArray(ShardStats::new, ShardStats[]::new);
if (in.getTransportVersion().onOrAfter(TransportVersions.V_8_1_0)) {
if (in.getTransportVersion().onOrAfter(TransportVersions.INDEX_STATS_ADDITIONAL_FIELDS)) {
indexHealthMap = in.readMap(ClusterHealthStatus::readFrom);
indexStateMap = in.readMap(IndexMetadata.State::readFrom);
indexTierPreferenceMap = in.readMap(StreamInput::readStringCollectionAsList);
indexCreationDateMap = in.readMap(StreamInput::readLong);
} else if (in.getTransportVersion().onOrAfter(TransportVersions.V_8_1_0)) {
// Between 8.1 and INDEX_STATS_ADDITIONAL_FIELDS, we had a different format for the response
// where we only had health and state available.
indexHealthMap = in.readMap(ClusterHealthStatus::readFrom);
indexStateMap = in.readMap(IndexMetadata.State::readFrom);
indexTierPreferenceMap = Map.of();
indexCreationDateMap = Map.of();
} else {
indexHealthMap = Map.of();
indexStateMap = Map.of();
indexTierPreferenceMap = Map.of();
indexCreationDateMap = Map.of();
}
}

Expand All @@ -79,6 +94,8 @@ public class IndicesStatsResponse extends ChunkedBroadcastResponse {
Objects.requireNonNull(shards);
Map<String, ClusterHealthStatus> indexHealthModifiableMap = new HashMap<>();
Map<String, IndexMetadata.State> indexStateModifiableMap = new HashMap<>();
Map<String, List<String>> indexTierPreferenceModifiableMap = new HashMap<>();
Map<String, Long> indexCreationDateModifiableMap = new HashMap<>();
for (ShardStats shard : shards) {
Index index = shard.getShardRouting().index();
IndexMetadata indexMetadata = metadata.index(index);
Expand All @@ -88,10 +105,14 @@ public class IndicesStatsResponse extends ChunkedBroadcastResponse {
ignored -> new ClusterIndexHealth(indexMetadata, routingTable.index(index)).getStatus()
);
indexStateModifiableMap.computeIfAbsent(index.getName(), ignored -> indexMetadata.getState());
indexTierPreferenceModifiableMap.computeIfAbsent(index.getName(), ignored -> indexMetadata.getTierPreference());
indexCreationDateModifiableMap.computeIfAbsent(index.getName(), ignored -> indexMetadata.getCreationDate());
}
}
indexHealthMap = unmodifiableMap(indexHealthModifiableMap);
indexStateMap = unmodifiableMap(indexStateModifiableMap);
indexTierPreferenceMap = unmodifiableMap(indexTierPreferenceModifiableMap);
indexCreationDateMap = unmodifiableMap(indexCreationDateModifiableMap);
}

public Map<ShardRouting, ShardStats> asMap() {
Expand Down Expand Up @@ -129,7 +150,14 @@ public Map<String, IndexStats> getIndices() {
Index index = shard.getShardRouting().index();
IndexStatsBuilder indexStatsBuilder = indexToIndexStatsBuilder.computeIfAbsent(
index.getName(),
k -> new IndexStatsBuilder(k, index.getUUID(), indexHealthMap.get(index.getName()), indexStateMap.get(index.getName()))
k -> new IndexStatsBuilder(
k,
index.getUUID(),
indexHealthMap.get(index.getName()),
indexStateMap.get(index.getName()),
indexTierPreferenceMap.get(index.getName()),
indexCreationDateMap.get(index.getName())
)
);
indexStatsBuilder.add(shard);
}
Expand Down Expand Up @@ -174,7 +202,13 @@ public CommonStats getPrimaries() {
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeArray(shards);
if (out.getTransportVersion().onOrAfter(TransportVersions.V_8_1_0)) {
if (out.getTransportVersion().onOrAfter(TransportVersions.INDEX_STATS_ADDITIONAL_FIELDS)) {
out.writeMap(indexHealthMap, StreamOutput::writeWriteable);
out.writeMap(indexStateMap, StreamOutput::writeWriteable);
out.writeMap(indexTierPreferenceMap, StreamOutput::writeStringCollection);
out.writeMap(indexCreationDateMap, StreamOutput::writeLong);

} else if (out.getTransportVersion().onOrAfter(TransportVersions.V_8_1_0)) {
out.writeMap(indexHealthMap, StreamOutput::writeWriteable);
out.writeMap(indexStateMap, StreamOutput::writeWriteable);
}
Expand Down Expand Up @@ -203,6 +237,12 @@ protected Iterator<ToXContent> customXContentChunks(ToXContent.Params params) {
if (indexStats.getState() != null) {
builder.field("status", indexStats.getState().toString().toLowerCase(Locale.ROOT));
}
if (indexStats.getTierPreference() != null) {
builder.field("tier_preference", indexStats.getTierPreference());
}
if (indexStats.getCreationDate() != null) {
builder.field("creation_date", indexStats.getCreationDate());
}
builder.startObject("primaries");
indexStats.getPrimaries().toXContent(builder, p);
builder.endObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# License v3.0 only", or the "Server Side Public License, v 1".
#

org.elasticsearch.action.admin.indices.stats.IndicesStatsFeatures
org.elasticsearch.action.bulk.BulkFeatures
org.elasticsearch.features.FeatureInfrastructureFeatures
org.elasticsearch.health.HealthFeatures
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,10 @@ public void testNoShardStats() {
shardStats[0] = sStats;

mockXPackInfo(true, true);
mockIndexStatsCall(indexName, new IndexStats(indexName, "uuid", ClusterHealthStatus.GREEN, IndexMetadata.State.OPEN, shardStats));
mockIndexStatsCall(
indexName,
new IndexStats(indexName, "uuid", ClusterHealthStatus.GREEN, IndexMetadata.State.OPEN, null, null, shardStats)
);

final SetOnce<Boolean> conditionMetHolder = new SetOnce<>();
final SetOnce<ToXContentObject> stepInfoHolder = new SetOnce<>();
Expand Down Expand Up @@ -289,7 +292,7 @@ private IndexStats randomIndexStats(boolean isLeaderIndex, int numOfShards) {
for (int i = 0; i < numOfShards; i++) {
shardStats[i] = randomShardStats(isLeaderIndex);
}
return new IndexStats(randomAlphaOfLength(5), randomAlphaOfLength(10), null, null, shardStats);
return new IndexStats(randomAlphaOfLength(5), randomAlphaOfLength(10), null, null, null, null, shardStats);
}

private ShardStats randomShardStats(boolean isLeaderIndex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public void setUp() throws Exception {
"dcvO5uZATE-EhIKc3tk9Bg",
null,
null,
null,
null,
new ShardStats[] {
// Primaries
new ShardStats(mockShardRouting(true), mockShardPath(), mockCommonStats(), null, null, null, false, 0),
Expand Down