-
Notifications
You must be signed in to change notification settings - Fork 25.2k
ES-10063 Add multi-project support for more stats APIs #127650
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
Changes from 7 commits
5d90b35
2ceb353
7cc0618
e7ba94e
793c415
46d4aa4
73143f4
39eced1
635fd65
600bb6c
1df27b1
084d605
6e1f8a7
ba44688
23aa344
8ef9be4
d9a9a7f
7f60ef3
3bfafbf
1810bc4
c29f27d
1fcad79
466b2a0
ad08d50
e0fab44
43cde05
7ad66ab
7d16998
9d09783
8770871
3b3b02c
dab57e6
918c1f3
a95a3d2
d353627
5c50366
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,8 @@ | |
import org.elasticsearch.action.admin.indices.stats.CommonStats; | ||
import org.elasticsearch.action.admin.indices.stats.IndexShardStats; | ||
import org.elasticsearch.action.admin.indices.stats.ShardStats; | ||
import org.elasticsearch.cluster.metadata.Metadata; | ||
import org.elasticsearch.cluster.metadata.ProjectId; | ||
import org.elasticsearch.common.collect.Iterators; | ||
import org.elasticsearch.common.io.stream.StreamInput; | ||
import org.elasticsearch.common.io.stream.StreamOutput; | ||
|
@@ -55,6 +57,8 @@ | |
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* Global information on indices stats running on a specific node. | ||
*/ | ||
|
@@ -66,6 +70,7 @@ public class NodeIndicesStats implements Writeable, ChunkedToXContent { | |
private final CommonStats stats; | ||
private final Map<Index, List<IndexShardStats>> statsByShard; | ||
private final Map<Index, CommonStats> statsByIndex; | ||
private final Map<Index, ProjectId> projectsByIndex; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a shame we have to pass in this map ourselves (and (de)serialize it), as it's pretty much just the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think it's a lot more. It's adding one There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah right, the serialization works a bit different in this class, it doesn't just serialize a full map. Hm ok that makes it a lot less worse, indeed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I just realized I'm mixing things up. I was thinking of the serialization of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, it's every index on the node. I still think that |
||
|
||
public NodeIndicesStats(StreamInput in) throws IOException { | ||
stats = new CommonStats(in); | ||
|
@@ -87,20 +92,31 @@ public NodeIndicesStats(StreamInput in) throws IOException { | |
} else { | ||
statsByIndex = new HashMap<>(); | ||
} | ||
|
||
if (in.getTransportVersion().onOrAfter(TransportVersions.NODES_STATS_SUPPORTS_MULTI_PROJECT)) { | ||
projectsByIndex = in.readMap(Index::new, ProjectId::readFrom); | ||
} else { | ||
projectsByIndex = Map.of(); | ||
} | ||
} | ||
|
||
/** | ||
* Constructs an instance. The {@code projectsByIndex} map will be stored, and the project IDs will be prepended to the index names when | ||
* converting this instance to XContent (except when it is the default project). | ||
*/ | ||
public NodeIndicesStats( | ||
CommonStats oldStats, | ||
Map<Index, CommonStats> statsByIndex, | ||
Map<Index, List<IndexShardStats>> statsByShard, | ||
Map<Index, ProjectId> projectsByIndex, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, I like this approach of passing in the index to project map |
||
boolean includeShardsStats | ||
) { | ||
if (includeShardsStats) { | ||
this.statsByShard = Objects.requireNonNull(statsByShard); | ||
this.statsByShard = requireNonNull(statsByShard); | ||
} else { | ||
this.statsByShard = EMPTY_STATS_BY_SHARD; | ||
} | ||
this.statsByIndex = Objects.requireNonNull(statsByIndex); | ||
this.statsByIndex = requireNonNull(statsByIndex); | ||
|
||
// make a total common stats from old ones and current ones | ||
this.stats = oldStats; | ||
|
@@ -114,6 +130,7 @@ public NodeIndicesStats( | |
for (CommonStats indexStats : statsByIndex.values()) { | ||
stats.add(indexStats); | ||
} | ||
this.projectsByIndex = requireNonNull(projectsByIndex); | ||
} | ||
|
||
@Nullable | ||
|
@@ -228,19 +245,25 @@ public void writeTo(StreamOutput out) throws IOException { | |
if (out.getTransportVersion().onOrAfter(VERSION_SUPPORTING_STATS_BY_INDEX)) { | ||
out.writeMap(statsByIndex); | ||
} | ||
if (out.getTransportVersion().onOrAfter(TransportVersions.NODES_STATS_SUPPORTS_MULTI_PROJECT)) { | ||
out.writeMap(projectsByIndex); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
NodeIndicesStats that = (NodeIndicesStats) o; | ||
return stats.equals(that.stats) && statsByShard.equals(that.statsByShard) && statsByIndex.equals(that.statsByIndex); | ||
return stats.equals(that.stats) | ||
&& statsByShard.equals(that.statsByShard) | ||
&& statsByIndex.equals(that.statsByIndex) | ||
&& projectsByIndex.equals(that.projectsByIndex); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(stats, statsByShard, statsByIndex); | ||
return Objects.hash(stats, statsByShard, statsByIndex, projectsByIndex); | ||
} | ||
|
||
@Override | ||
|
@@ -260,7 +283,7 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerP | |
case INDICES -> ChunkedToXContentHelper.object( | ||
Fields.INDICES, | ||
Iterators.map(createCommonStatsByIndex().entrySet().iterator(), entry -> (builder, params) -> { | ||
builder.startObject(entry.getKey().getName()); | ||
builder.startObject(xContentKey(entry.getKey())); | ||
entry.getValue().toXContent(builder, outerParams); | ||
return builder.endObject(); | ||
}) | ||
|
@@ -271,7 +294,7 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerP | |
Iterators.flatMap( | ||
statsByShard.entrySet().iterator(), | ||
entry -> ChunkedToXContentHelper.array( | ||
entry.getKey().getName(), | ||
xContentKey(entry.getKey()), | ||
Iterators.flatMap( | ||
entry.getValue().iterator(), | ||
indexShardStats -> Iterators.concat( | ||
|
@@ -291,6 +314,23 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerP | |
); | ||
} | ||
|
||
private String xContentKey(Index index) { | ||
if (projectsByIndex.isEmpty()) { // mapping is not available if this instance came from an older node | ||
return index.getName(); | ||
} | ||
ProjectId projectId = projectsByIndex.get(index); | ||
if (projectId == null) { | ||
// This can happen if the stats were captured after the IndexService was created but before the state was updated. | ||
// It can also happen if this instance was constructed on a node older than VERSION_SUPPORTING_STATS_BY_INDEX. | ||
// The best we can do is handle it gracefully. | ||
return "<unknown>/" + index.getName(); | ||
} else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID)) { | ||
return index.getName(); | ||
} else { | ||
return projectId + "/" + index.getName(); | ||
} | ||
} | ||
|
||
private Map<Index, CommonStats> createCommonStatsByIndex() { | ||
Map<Index, CommonStats> statsMap = new HashMap<>(); | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.