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,15 @@ 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 .isPatchFrom (TransportVersions .SOURCE_MODE_TELEMETRY_FIX_8_17 )
288+ || version .onOrAfter (TransportVersions .SOURCE_MODE_TELEMETRY );
260289 }
261290
262291 private static OptionalLong ofNullable (Long l ) {
@@ -300,6 +329,10 @@ public List<RuntimeFieldStats> getRuntimeFieldStats() {
300329 return runtimeFieldStats ;
301330 }
302331
332+ public Map <String , Integer > getSourceModeUsageCount () {
333+ return sourceModeUsageCount ;
334+ }
335+
303336 @ Override
304337 public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
305338 builder .startObject ("mappings" );
@@ -326,6 +359,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
326359 st .toXContent (builder , params );
327360 }
328361 builder .endArray ();
362+ builder .startObject ("source_modes" );
363+ var entries = sourceModeUsageCount .entrySet ().stream ().sorted (Map .Entry .comparingByKey ()).toList ();
364+ for (var entry : entries ) {
365+ builder .field (entry .getKey (), entry .getValue ());
366+ }
367+ builder .endObject ();
329368 builder .endObject ();
330369 return builder ;
331370 }
@@ -344,11 +383,19 @@ public boolean equals(Object o) {
344383 && Objects .equals (totalDeduplicatedFieldCount , that .totalDeduplicatedFieldCount )
345384 && Objects .equals (totalMappingSizeBytes , that .totalMappingSizeBytes )
346385 && fieldTypeStats .equals (that .fieldTypeStats )
347- && runtimeFieldStats .equals (that .runtimeFieldStats );
386+ && runtimeFieldStats .equals (that .runtimeFieldStats )
387+ && sourceModeUsageCount .equals (that .sourceModeUsageCount );
348388 }
349389
350390 @ Override
351391 public int hashCode () {
352- return Objects .hash (totalFieldCount , totalDeduplicatedFieldCount , totalMappingSizeBytes , fieldTypeStats , runtimeFieldStats );
392+ return Objects .hash (
393+ totalFieldCount ,
394+ totalDeduplicatedFieldCount ,
395+ totalMappingSizeBytes ,
396+ fieldTypeStats ,
397+ runtimeFieldStats ,
398+ sourceModeUsageCount
399+ );
353400 }
354401}
0 commit comments