99
1010package org .elasticsearch .action .admin .cluster .stats ;
1111
12+ import org .elasticsearch .TransportVersion ;
1213import org .elasticsearch .TransportVersions ;
1314import org .elasticsearch .cluster .metadata .IndexMetadata ;
1415import org .elasticsearch .cluster .metadata .MappingMetadata ;
1920import org .elasticsearch .common .io .stream .Writeable ;
2021import org .elasticsearch .common .unit .ByteSizeValue ;
2122import org .elasticsearch .core .Nullable ;
23+ import org .elasticsearch .features .NodeFeature ;
24+ import org .elasticsearch .index .mapper .SourceFieldMapper ;
2225import org .elasticsearch .xcontent .ToXContentFragment ;
2326import org .elasticsearch .xcontent .XContentBuilder ;
2427
3134import java .util .HashSet ;
3235import java .util .IdentityHashMap ;
3336import java .util .List ;
37+ import java .util .Locale ;
3438import java .util .Map ;
3539import java .util .Objects ;
3640import java .util .OptionalLong ;
4448 */
4549public final class MappingStats implements ToXContentFragment , Writeable {
4650
51+ static final NodeFeature SOURCE_MODES_FEATURE = new NodeFeature ("cluster.stats.source_modes" );
52+
4753 private static final Pattern DOC_PATTERN = Pattern .compile ("doc[\\ [.]" );
4854 private static final Pattern SOURCE_PATTERN = Pattern .compile ("params\\ ._source" );
4955
@@ -53,6 +59,8 @@ public final class MappingStats implements ToXContentFragment, Writeable {
5359 public static MappingStats of (Metadata metadata , Runnable ensureNotCancelled ) {
5460 Map <String , FieldStats > fieldTypes = new HashMap <>();
5561 Set <String > concreteFieldNames = new HashSet <>();
62+ // Account different source modes based on index.mapping.source.mode setting:
63+ Map <String , Integer > sourceModeUsageCount = new HashMap <>();
5664 Map <String , RuntimeFieldStats > runtimeFieldTypes = new HashMap <>();
5765 final Map <MappingMetadata , Integer > mappingCounts = new IdentityHashMap <>(metadata .getMappingsByHash ().size ());
5866 for (IndexMetadata indexMetadata : metadata ) {
@@ -62,6 +70,9 @@ public static MappingStats of(Metadata metadata, Runnable ensureNotCancelled) {
6270 continue ;
6371 }
6472 AnalysisStats .countMapping (mappingCounts , indexMetadata );
73+
74+ var sourceMode = SourceFieldMapper .INDEX_MAPPER_SOURCE_MODE_SETTING .get (indexMetadata .getSettings ());
75+ sourceModeUsageCount .merge (sourceMode .toString ().toLowerCase (Locale .ENGLISH ), 1 , Integer ::sum );
6576 }
6677 final AtomicLong totalFieldCount = new AtomicLong ();
6778 final AtomicLong totalDeduplicatedFieldCount = new AtomicLong ();
@@ -175,12 +186,14 @@ public static MappingStats of(Metadata metadata, Runnable ensureNotCancelled) {
175186 for (MappingMetadata mappingMetadata : metadata .getMappingsByHash ().values ()) {
176187 totalMappingSizeBytes += mappingMetadata .source ().compressed ().length ;
177188 }
189+
178190 return new MappingStats (
179191 totalFieldCount .get (),
180192 totalDeduplicatedFieldCount .get (),
181193 totalMappingSizeBytes ,
182194 fieldTypes .values (),
183- runtimeFieldTypes .values ()
195+ runtimeFieldTypes .values (),
196+ sourceModeUsageCount
184197 );
185198 }
186199
@@ -215,17 +228,20 @@ private static int countOccurrences(String script, Pattern pattern) {
215228
216229 private final List <FieldStats > fieldTypeStats ;
217230 private final List <RuntimeFieldStats > runtimeFieldStats ;
231+ private final Map <String , Integer > sourceModeUsageCount ;
218232
219233 MappingStats (
220234 long totalFieldCount ,
221235 long totalDeduplicatedFieldCount ,
222236 long totalMappingSizeBytes ,
223237 Collection <FieldStats > fieldTypeStats ,
224- Collection <RuntimeFieldStats > runtimeFieldStats
238+ Collection <RuntimeFieldStats > runtimeFieldStats ,
239+ Map <String , Integer > sourceModeUsageCount
225240 ) {
226241 this .totalFieldCount = totalFieldCount ;
227242 this .totalDeduplicatedFieldCount = totalDeduplicatedFieldCount ;
228243 this .totalMappingSizeBytes = totalMappingSizeBytes ;
244+ this .sourceModeUsageCount = sourceModeUsageCount ;
229245 List <FieldStats > stats = new ArrayList <>(fieldTypeStats );
230246 stats .sort (Comparator .comparing (IndexFeatureStats ::getName ));
231247 this .fieldTypeStats = Collections .unmodifiableList (stats );
@@ -246,6 +262,10 @@ private static int countOccurrences(String script, Pattern pattern) {
246262 }
247263 fieldTypeStats = in .readCollectionAsImmutableList (FieldStats ::new );
248264 runtimeFieldStats = in .readCollectionAsImmutableList (RuntimeFieldStats ::new );
265+ var transportVersion = in .getTransportVersion ();
266+ sourceModeUsageCount = canReadOrWriteSourceModeTelemetry (transportVersion )
267+ ? in .readImmutableMap (StreamInput ::readString , StreamInput ::readVInt )
268+ : Map .of ();
249269 }
250270
251271 @ Override
@@ -257,6 +277,14 @@ public void writeTo(StreamOutput out) throws IOException {
257277 }
258278 out .writeCollection (fieldTypeStats );
259279 out .writeCollection (runtimeFieldStats );
280+ var transportVersion = out .getTransportVersion ();
281+ if (canReadOrWriteSourceModeTelemetry (transportVersion )) {
282+ out .writeMap (sourceModeUsageCount , StreamOutput ::writeVInt );
283+ }
284+ }
285+
286+ private static boolean canReadOrWriteSourceModeTelemetry (TransportVersion version ) {
287+ return version .onOrAfter (TransportVersions .SOURCE_MODE_TELEMETRY_FIX_8_17 );
260288 }
261289
262290 private static OptionalLong ofNullable (Long l ) {
@@ -300,6 +328,10 @@ public List<RuntimeFieldStats> getRuntimeFieldStats() {
300328 return runtimeFieldStats ;
301329 }
302330
331+ public Map <String , Integer > getSourceModeUsageCount () {
332+ return sourceModeUsageCount ;
333+ }
334+
303335 @ Override
304336 public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
305337 builder .startObject ("mappings" );
@@ -326,6 +358,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
326358 st .toXContent (builder , params );
327359 }
328360 builder .endArray ();
361+ builder .startObject ("source_modes" );
362+ var entries = sourceModeUsageCount .entrySet ().stream ().sorted (Map .Entry .comparingByKey ()).toList ();
363+ for (var entry : entries ) {
364+ builder .field (entry .getKey (), entry .getValue ());
365+ }
366+ builder .endObject ();
329367 builder .endObject ();
330368 return builder ;
331369 }
@@ -344,11 +382,19 @@ public boolean equals(Object o) {
344382 && Objects .equals (totalDeduplicatedFieldCount , that .totalDeduplicatedFieldCount )
345383 && Objects .equals (totalMappingSizeBytes , that .totalMappingSizeBytes )
346384 && fieldTypeStats .equals (that .fieldTypeStats )
347- && runtimeFieldStats .equals (that .runtimeFieldStats );
385+ && runtimeFieldStats .equals (that .runtimeFieldStats )
386+ && sourceModeUsageCount .equals (that .sourceModeUsageCount );
348387 }
349388
350389 @ Override
351390 public int hashCode () {
352- return Objects .hash (totalFieldCount , totalDeduplicatedFieldCount , totalMappingSizeBytes , fieldTypeStats , runtimeFieldStats );
391+ return Objects .hash (
392+ totalFieldCount ,
393+ totalDeduplicatedFieldCount ,
394+ totalMappingSizeBytes ,
395+ fieldTypeStats ,
396+ runtimeFieldStats ,
397+ sourceModeUsageCount
398+ );
353399 }
354400}
0 commit comments