Skip to content

Commit

Permalink
[8.x] Add source mode stats to MappingStats (elastic#117694)
Browse files Browse the repository at this point in the history
Backporting elastic#117463 to 8.x branch.
  • Loading branch information
martijnvg authored Nov 28, 2024
1 parent 911728b commit 4b3ecd3
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 12 deletions.
5 changes: 4 additions & 1 deletion docs/reference/cluster/stats.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -1644,7 +1644,10 @@ The API returns the following response:
"total_deduplicated_mapping_size": "0b",
"total_deduplicated_mapping_size_in_bytes": 0,
"field_types": [],
"runtime_field_types": []
"runtime_field_types": [],
"source_modes" : {
"stored": 0
}
},
"analysis": {
"char_filter_types": [],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
test source modes:
- requires:
cluster_features: ["cluster.stats.source_modes"]
reason: requires source modes features

- do:
indices.create:
index: test-synthetic
body:
settings:
index:
mapping:
source.mode: synthetic

- do:
indices.create:
index: test-stored

- do:
indices.create:
index: test-disabled
body:
settings:
index:
mapping:
source.mode: disabled

- do:
bulk:
refresh: true
body:
- '{ "create": { "_index": "test-synthetic" } }'
- '{ "name": "aaaa", "some_string": "AaAa", "some_int": 1000, "some_double": 123.456789, "some_bool": true }'
- '{ "create": { "_index": "test-stored" } }'
- '{ "name": "bbbb", "some_string": "BbBb", "some_int": 2000, "some_double": 321.987654, "some_bool": false }'
- '{ "create": { "_index": "test-disabled" } }'
- '{ "name": "cccc", "some_string": "CcCc", "some_int": 3000, "some_double": 421.484654, "some_bool": false }'

- do:
search:
index: test-*
- match: { hits.total.value: 3 }

- do:
cluster.stats: { }

- match: { indices.mappings.source_modes.disabled: 1 }
- match: { indices.mappings.source_modes.stored: 1 }
- match: { indices.mappings.source_modes.synthetic: 1 }
3 changes: 2 additions & 1 deletion server/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,8 @@
org.elasticsearch.search.SearchFeatures,
org.elasticsearch.script.ScriptFeatures,
org.elasticsearch.search.retriever.RetrieversFeatures,
org.elasticsearch.reservedstate.service.FileSettingsFeatures;
org.elasticsearch.reservedstate.service.FileSettingsFeatures,
org.elasticsearch.action.admin.cluster.stats.ClusterStatsFeatures;

uses org.elasticsearch.plugins.internal.SettingsExtension;
uses RestExtension;
Expand Down
3 changes: 3 additions & 0 deletions server/src/main/java/org/elasticsearch/TransportVersions.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,13 @@ static TransportVersion def(int id) {
public static final TransportVersion ESQL_ENRICH_RUNTIME_WARNINGS = def(8_796_00_0);
public static final TransportVersion INGEST_PIPELINE_CONFIGURATION_AS_MAP = def(8_797_00_0);
public static final TransportVersion LOGSDB_TELEMETRY_CUSTOM_CUTOFF_DATE_FIX_8_17 = def(8_797_00_1);
public static final TransportVersion SOURCE_MODE_TELEMETRY_FIX_8_17 = def(8_797_00_2);
public static final TransportVersion INDEXING_PRESSURE_THROTTLING_STATS = def(8_798_00_0);
public static final TransportVersion REINDEX_DATA_STREAMS = def(8_799_00_0);
public static final TransportVersion ESQL_REMOVE_NODE_LEVEL_PLAN = def(8_800_00_0);
public static final TransportVersion LOGSDB_TELEMETRY_CUSTOM_CUTOFF_DATE = def(8_801_00_0);
public static final TransportVersion SOURCE_MODE_TELEMETRY = def(8_802_00_0);

/*
* STOP! READ THIS FIRST! No, really,
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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.cluster.stats;

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

import java.util.Set;

/**
* Spec for cluster stats features.
*/
public class ClusterStatsFeatures implements FeatureSpecification {

@Override
public Set<NodeFeature> getFeatures() {
return Set.of(MappingStats.SOURCE_MODES_FEATURE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

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

import org.elasticsearch.TransportVersion;
import org.elasticsearch.TransportVersions;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.MappingMetadata;
Expand All @@ -19,6 +20,8 @@
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.features.NodeFeature;
import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.xcontent.ToXContentFragment;
import org.elasticsearch.xcontent.XContentBuilder;

Expand All @@ -31,6 +34,7 @@
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.OptionalLong;
Expand All @@ -44,6 +48,8 @@
*/
public final class MappingStats implements ToXContentFragment, Writeable {

static final NodeFeature SOURCE_MODES_FEATURE = new NodeFeature("cluster.stats.source_modes");

private static final Pattern DOC_PATTERN = Pattern.compile("doc[\\[.]");
private static final Pattern SOURCE_PATTERN = Pattern.compile("params\\._source");

Expand All @@ -53,6 +59,8 @@ public final class MappingStats implements ToXContentFragment, Writeable {
public static MappingStats of(Metadata metadata, Runnable ensureNotCancelled) {
Map<String, FieldStats> fieldTypes = new HashMap<>();
Set<String> concreteFieldNames = new HashSet<>();
// Account different source modes based on index.mapping.source.mode setting:
Map<String, Integer> sourceModeUsageCount = new HashMap<>();
Map<String, RuntimeFieldStats> runtimeFieldTypes = new HashMap<>();
final Map<MappingMetadata, Integer> mappingCounts = new IdentityHashMap<>(metadata.getMappingsByHash().size());
for (IndexMetadata indexMetadata : metadata) {
Expand All @@ -62,6 +70,9 @@ public static MappingStats of(Metadata metadata, Runnable ensureNotCancelled) {
continue;
}
AnalysisStats.countMapping(mappingCounts, indexMetadata);

var sourceMode = SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING.get(indexMetadata.getSettings());
sourceModeUsageCount.merge(sourceMode.toString().toLowerCase(Locale.ENGLISH), 1, Integer::sum);
}
final AtomicLong totalFieldCount = new AtomicLong();
final AtomicLong totalDeduplicatedFieldCount = new AtomicLong();
Expand Down Expand Up @@ -175,12 +186,14 @@ public static MappingStats of(Metadata metadata, Runnable ensureNotCancelled) {
for (MappingMetadata mappingMetadata : metadata.getMappingsByHash().values()) {
totalMappingSizeBytes += mappingMetadata.source().compressed().length;
}

return new MappingStats(
totalFieldCount.get(),
totalDeduplicatedFieldCount.get(),
totalMappingSizeBytes,
fieldTypes.values(),
runtimeFieldTypes.values()
runtimeFieldTypes.values(),
sourceModeUsageCount
);
}

Expand Down Expand Up @@ -215,17 +228,20 @@ private static int countOccurrences(String script, Pattern pattern) {

private final List<FieldStats> fieldTypeStats;
private final List<RuntimeFieldStats> runtimeFieldStats;
private final Map<String, Integer> sourceModeUsageCount;

MappingStats(
long totalFieldCount,
long totalDeduplicatedFieldCount,
long totalMappingSizeBytes,
Collection<FieldStats> fieldTypeStats,
Collection<RuntimeFieldStats> runtimeFieldStats
Collection<RuntimeFieldStats> runtimeFieldStats,
Map<String, Integer> sourceModeUsageCount
) {
this.totalFieldCount = totalFieldCount;
this.totalDeduplicatedFieldCount = totalDeduplicatedFieldCount;
this.totalMappingSizeBytes = totalMappingSizeBytes;
this.sourceModeUsageCount = sourceModeUsageCount;
List<FieldStats> stats = new ArrayList<>(fieldTypeStats);
stats.sort(Comparator.comparing(IndexFeatureStats::getName));
this.fieldTypeStats = Collections.unmodifiableList(stats);
Expand All @@ -246,6 +262,10 @@ private static int countOccurrences(String script, Pattern pattern) {
}
fieldTypeStats = in.readCollectionAsImmutableList(FieldStats::new);
runtimeFieldStats = in.readCollectionAsImmutableList(RuntimeFieldStats::new);
var transportVersion = in.getTransportVersion();
sourceModeUsageCount = canReadOrWriteSourceModeTelemetry(transportVersion)
? in.readImmutableMap(StreamInput::readString, StreamInput::readVInt)
: Map.of();
}

@Override
Expand All @@ -257,6 +277,15 @@ public void writeTo(StreamOutput out) throws IOException {
}
out.writeCollection(fieldTypeStats);
out.writeCollection(runtimeFieldStats);
var transportVersion = out.getTransportVersion();
if (canReadOrWriteSourceModeTelemetry(transportVersion)) {
out.writeMap(sourceModeUsageCount, StreamOutput::writeVInt);
}
}

private static boolean canReadOrWriteSourceModeTelemetry(TransportVersion version) {
return version.isPatchFrom(TransportVersions.SOURCE_MODE_TELEMETRY_FIX_8_17)
|| version.onOrAfter(TransportVersions.SOURCE_MODE_TELEMETRY);
}

private static OptionalLong ofNullable(Long l) {
Expand Down Expand Up @@ -300,6 +329,10 @@ public List<RuntimeFieldStats> getRuntimeFieldStats() {
return runtimeFieldStats;
}

public Map<String, Integer> getSourceModeUsageCount() {
return sourceModeUsageCount;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject("mappings");
Expand All @@ -326,6 +359,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
st.toXContent(builder, params);
}
builder.endArray();
builder.startObject("source_modes");
var entries = sourceModeUsageCount.entrySet().stream().sorted(Map.Entry.comparingByKey()).toList();
for (var entry : entries) {
builder.field(entry.getKey(), entry.getValue());
}
builder.endObject();
builder.endObject();
return builder;
}
Expand All @@ -344,11 +383,19 @@ public boolean equals(Object o) {
&& Objects.equals(totalDeduplicatedFieldCount, that.totalDeduplicatedFieldCount)
&& Objects.equals(totalMappingSizeBytes, that.totalMappingSizeBytes)
&& fieldTypeStats.equals(that.fieldTypeStats)
&& runtimeFieldStats.equals(that.runtimeFieldStats);
&& runtimeFieldStats.equals(that.runtimeFieldStats)
&& sourceModeUsageCount.equals(that.sourceModeUsageCount);
}

@Override
public int hashCode() {
return Objects.hash(totalFieldCount, totalDeduplicatedFieldCount, totalMappingSizeBytes, fieldTypeStats, runtimeFieldStats);
return Objects.hash(
totalFieldCount,
totalDeduplicatedFieldCount,
totalMappingSizeBytes,
fieldTypeStats,
runtimeFieldStats,
sourceModeUsageCount
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ org.elasticsearch.search.retriever.RetrieversFeatures
org.elasticsearch.script.ScriptFeatures
org.elasticsearch.reservedstate.service.FileSettingsFeatures
org.elasticsearch.cluster.routing.RoutingFeatures
org.elasticsearch.action.admin.cluster.stats.ClusterStatsFeatures
Loading

0 comments on commit 4b3ecd3

Please sign in to comment.