Skip to content
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

Added initial metrics for synthetic source #106732

Merged
merged 22 commits into from
May 14, 2024

Conversation

lkts
Copy link
Contributor

@lkts lkts commented Mar 25, 2024

This PR is a proposal of an approach to add metrics for mappers with minimal impact to existing code. First metric added here is time to reconstruct synthetic source.

Contributes to #106659

This PR adds basic infra for mapper metrics and adds first metrics for
synthetic source load latency.
@elasticsearchmachine
Copy link
Collaborator

Hi @lkts, I've created a changelog YAML for you.

@lkts lkts force-pushed the feature/synthetic_source_metrics branch from e338eed to 38b307f Compare March 29, 2024 01:07
@lkts
Copy link
Contributor Author

lkts commented Mar 29, 2024

@elasticmachine update branch

@lkts
Copy link
Contributor Author

lkts commented Apr 15, 2024

@elasticmachine update branch

@lkts lkts added :StorageEngine/Mapping The storage related side of mappings and removed :StorageEngine/TSDB You know, for Metrics labels Apr 15, 2024
@lkts lkts marked this pull request as ready for review April 15, 2024 22:08
@lkts lkts requested a review from a team as a code owner April 15, 2024 22:08
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-storage-engine (Team:StorageEngine)

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little bit uncomfortable with the approach taken here. If I understand correctly, the thread local is only really needed for testing purposes, while the code relies on a static field to be set. That a special SourceLoader can read.

We usually don't rely on these static fields in Elasticsearch to keep things around. One particular problem that comes to mind is any test case extending from ESIntegTestCase, here multiple nodes run within the same jvm.

Although I'm not a big fan of the alternative (proving MeterRegistry to where it is needed), I suspect for now this best. It would look something like this:

Subject: [PATCH] patch
---
Index: server/src/main/java/org/elasticsearch/node/NodeServiceProvider.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/node/NodeServiceProvider.java b/server/src/main/java/org/elasticsearch/node/NodeServiceProvider.java
--- a/server/src/main/java/org/elasticsearch/node/NodeServiceProvider.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/node/NodeServiceProvider.java	(date 1713446405948)
@@ -34,6 +34,7 @@
 import org.elasticsearch.search.SearchService;
 import org.elasticsearch.search.fetch.FetchPhase;
 import org.elasticsearch.tasks.TaskManager;
+import org.elasticsearch.telemetry.TelemetryProvider;
 import org.elasticsearch.telemetry.tracing.Tracer;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.transport.Transport;
@@ -120,7 +121,7 @@
         ResponseCollectorService responseCollectorService,
         CircuitBreakerService circuitBreakerService,
         ExecutorSelector executorSelector,
-        Tracer tracer
+        TelemetryProvider telemetryProvider
     ) {
         return new SearchService(
             clusterService,
@@ -132,7 +133,7 @@
             responseCollectorService,
             circuitBreakerService,
             executorSelector,
-            tracer
+            telemetryProvider
         );
     }
 
Index: x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsPhysicalOperationProviders.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsPhysicalOperationProviders.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsPhysicalOperationProviders.java
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsPhysicalOperationProviders.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsPhysicalOperationProviders.java	(date 1713446759792)
@@ -242,7 +242,7 @@
 
         @Override
         public SourceLoader newSourceLoader() {
-            return ctx.newSourceLoader(false);
+            return ctx.newSourceLoader(meterRegistry, false);
         }
 
         @Override
Index: server/src/test/java/org/elasticsearch/index/IndexModuleTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/test/java/org/elasticsearch/index/IndexModuleTests.java b/server/src/test/java/org/elasticsearch/index/IndexModuleTests.java
--- a/server/src/test/java/org/elasticsearch/index/IndexModuleTests.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/test/java/org/elasticsearch/index/IndexModuleTests.java	(date 1713447867174)
@@ -233,8 +233,8 @@
             () -> true,
             indexNameExpressionResolver,
             Collections.emptyMap(),
-            mock(SlowLogFieldProvider.class)
-        );
+            mock(SlowLogFieldProvider.class),
+                telemetryProvider);
         module.setReaderWrapper(s -> new Wrapper());
 
         IndexService indexService = newIndexService(module);
@@ -259,8 +259,8 @@
             () -> true,
             indexNameExpressionResolver,
             Collections.emptyMap(),
-            mock(SlowLogFieldProvider.class)
-        );
+            mock(SlowLogFieldProvider.class),
+                telemetryProvider);
 
         final IndexService indexService = newIndexService(module);
         assertThat(indexService.getDirectoryFactory(), instanceOf(FooFunction.class));
@@ -283,8 +283,8 @@
             () -> true,
             indexNameExpressionResolver,
             Collections.emptyMap(),
-            mock(SlowLogFieldProvider.class)
-        );
+            mock(SlowLogFieldProvider.class),
+                telemetryProvider);
 
         module.setDirectoryWrapper(new TestDirectoryWrapper());
 
@@ -635,8 +635,8 @@
             () -> true,
             indexNameExpressionResolver,
             recoveryStateFactories,
-            mock(SlowLogFieldProvider.class)
-        );
+            mock(SlowLogFieldProvider.class),
+                telemetryProvider);
 
         final IndexService indexService = newIndexService(module);
 
@@ -656,8 +656,8 @@
             () -> true,
             indexNameExpressionResolver,
             Collections.emptyMap(),
-            mock(SlowLogFieldProvider.class)
-        );
+            mock(SlowLogFieldProvider.class),
+                telemetryProvider);
 
         final AtomicLong lastAcquiredPrimaryTerm = new AtomicLong();
         final AtomicReference<Engine.IndexCommitRef> lastAcquiredCommit = new AtomicReference<>();
@@ -757,8 +757,8 @@
             () -> true,
             indexNameExpressionResolver,
             Collections.emptyMap(),
-            mock(SlowLogFieldProvider.class)
-        );
+            mock(SlowLogFieldProvider.class),
+                telemetryProvider);
     }
 
     class CustomQueryCache implements QueryCache {
Index: server/src/main/java/org/elasticsearch/index/IndexService.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/IndexService.java b/server/src/main/java/org/elasticsearch/index/IndexService.java
--- a/server/src/main/java/org/elasticsearch/index/IndexService.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/IndexService.java	(date 1713447867135)
@@ -84,6 +84,7 @@
 import org.elasticsearch.plugins.IndexStorePlugin;
 import org.elasticsearch.script.ScriptService;
 import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry;
+import org.elasticsearch.telemetry.TelemetryProvider;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.transport.RemoteClusterAware;
 import org.elasticsearch.xcontent.XContentParserConfiguration;
@@ -158,6 +159,7 @@
     private final IndexNameExpressionResolver expressionResolver;
     private final Supplier<Sort> indexSortSupplier;
     private final ValuesSourceRegistry valuesSourceRegistry;
+    private final TelemetryProvider telemetryProvider;
 
     @SuppressWarnings("this-escape")
     public IndexService(
@@ -191,8 +193,8 @@
         IndexStorePlugin.RecoveryStateFactory recoveryStateFactory,
         IndexStorePlugin.IndexFoldersDeletionListener indexFoldersDeletionListener,
         IndexStorePlugin.SnapshotCommitSupplier snapshotCommitSupplier,
-        Engine.IndexCommitListener indexCommitListener
-    ) {
+        Engine.IndexCommitListener indexCommitListener,
+        TelemetryProvider telemetryProvider) {
         super(indexSettings);
         assert indexCreationContext != IndexCreationContext.RELOAD_ANALYZERS
             : "IndexCreationContext.RELOAD_ANALYZERS should only be used when reloading analysers";
@@ -270,6 +272,7 @@
             this.globalCheckpointTask = new AsyncGlobalCheckpointTask(this);
             this.retentionLeaseSyncTask = new AsyncRetentionLeaseSyncTask(this);
         }
+        this.telemetryProvider = telemetryProvider;
         updateFsyncTaskIfNecessary();
     }
 
@@ -541,7 +544,8 @@
                 circuitBreakerService,
                 snapshotCommitSupplier,
                 System::nanoTime,
-                indexCommitListener
+                indexCommitListener,
+                telemetryProvider
             );
             eventListener.indexShardStateChanged(indexShard, null, indexShard.state(), "shard created");
             eventListener.afterIndexShardCreated(indexShard);
Index: server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java
--- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java	(date 1713446759803)
@@ -112,7 +112,7 @@
          * Build an empty source loader to validate that the mapping is compatible
          * with the source loading strategy declared on the source field mapper.
          */
-        sourceMapper().newSourceLoader(mapping());
+        sourceMapper().newSourceLoader(meterRegistry, mapping());
         if (settings.getIndexSortConfig().hasIndexSort() && mappers().nestedLookup() != NestedLookup.EMPTY) {
             throw new IllegalArgumentException("cannot have nested fields when index sort is activated");
         }
Index: server/src/main/java/org/elasticsearch/index/IndexModule.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/IndexModule.java b/server/src/main/java/org/elasticsearch/index/IndexModule.java
--- a/server/src/main/java/org/elasticsearch/index/IndexModule.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/IndexModule.java	(date 1713447867149)
@@ -59,6 +59,7 @@
 import org.elasticsearch.plugins.IndexStorePlugin;
 import org.elasticsearch.script.ScriptService;
 import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry;
+import org.elasticsearch.telemetry.TelemetryProvider;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.xcontent.XContentParserConfiguration;
 
@@ -177,6 +178,7 @@
     private final BooleanSupplier allowExpensiveQueries;
     private final Map<String, IndexStorePlugin.RecoveryStateFactory> recoveryStateFactories;
     private final SetOnce<Engine.IndexCommitListener> indexCommitListener = new SetOnce<>();
+    private final TelemetryProvider telemetryProvider;
 
     /**
      * Construct the index module for the index with the specified index settings. The index module contains extension points for plugins
@@ -186,6 +188,7 @@
      * @param analysisRegistry   the analysis registry
      * @param engineFactory      the engine factory
      * @param directoryFactories the available store types
+     * @param telemetryProvider
      */
     public IndexModule(
         final IndexSettings indexSettings,
@@ -195,8 +198,8 @@
         final BooleanSupplier allowExpensiveQueries,
         final IndexNameExpressionResolver expressionResolver,
         final Map<String, IndexStorePlugin.RecoveryStateFactory> recoveryStateFactories,
-        final SlowLogFieldProvider slowLogFieldProvider
-    ) {
+        final SlowLogFieldProvider slowLogFieldProvider,
+        TelemetryProvider telemetryProvider) {
         this.indexSettings = indexSettings;
         this.analysisRegistry = analysisRegistry;
         this.engineFactory = Objects.requireNonNull(engineFactory);
@@ -206,6 +209,7 @@
         this.allowExpensiveQueries = allowExpensiveQueries;
         this.expressionResolver = expressionResolver;
         this.recoveryStateFactories = recoveryStateFactories;
+        this.telemetryProvider = telemetryProvider;
     }
 
     /**
@@ -536,7 +540,8 @@
                 recoveryStateFactory,
                 indexFoldersDeletionListener,
                 snapshotCommitSupplier,
-                indexCommitListener.get()
+                indexCommitListener.get(),
+                telemetryProvider
             );
             success = true;
             return indexService;
Index: server/src/main/java/org/elasticsearch/index/query/FilteredSearchExecutionContext.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/query/FilteredSearchExecutionContext.java b/server/src/main/java/org/elasticsearch/index/query/FilteredSearchExecutionContext.java
--- a/server/src/main/java/org/elasticsearch/index/query/FilteredSearchExecutionContext.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/query/FilteredSearchExecutionContext.java	(date 1713446759796)
@@ -39,6 +39,7 @@
 import org.elasticsearch.search.lookup.LeafFieldLookupProvider;
 import org.elasticsearch.search.lookup.SearchLookup;
 import org.elasticsearch.search.lookup.SourceProvider;
+import org.elasticsearch.telemetry.metric.MeterRegistry;
 import org.elasticsearch.xcontent.XContentParserConfiguration;
 
 import java.util.List;
@@ -161,8 +162,8 @@
     }
 
     @Override
-    public SourceLoader newSourceLoader(boolean forceSyntheticSource) {
-        return in.newSourceLoader(forceSyntheticSource);
+    public SourceLoader newSourceLoader(MeterRegistry meterRegistry, boolean forceSyntheticSource) {
+        return in.newSourceLoader(meterRegistry, forceSyntheticSource);
     }
 
     @Override
Index: server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java
--- a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java	(date 1713446759768)
@@ -26,6 +26,7 @@
 import org.elasticsearch.index.query.SearchExecutionContext;
 import org.elasticsearch.search.lookup.Source;
 import org.elasticsearch.search.lookup.SourceFilter;
+import org.elasticsearch.telemetry.metric.MeterRegistry;
 import org.elasticsearch.xcontent.XContentType;
 
 import java.io.IOException;
@@ -353,9 +354,9 @@
     /**
      * Build something to load source {@code _source}.
      */
-    public SourceLoader newSourceLoader(Mapping mapping) {
+    public SourceLoader newSourceLoader(MeterRegistry meterRegistry, Mapping mapping) {
         if (mode == Mode.SYNTHETIC) {
-            return new SourceLoader.Synthetic(mapping);
+            return new SourceLoader.Synthetic(meterRegistry, mapping);
         }
         return SourceLoader.FROM_STORED_SOURCE;
     }
Index: test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java b/test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java
--- a/test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/test/framework/src/main/java/org/elasticsearch/index/shard/IndexShardTestCase.java	(date 1713447867146)
@@ -527,8 +527,8 @@
                 breakerService,
                 IndexModule.DEFAULT_SNAPSHOT_COMMIT_SUPPLIER,
                 relativeTimeSupplier,
-                null
-            );
+                null,
+                    telemetryProvider);
             indexShard.addShardFailureCallback(DEFAULT_SHARD_FAILURE_HANDLER);
             success = true;
         } finally {
Index: x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java	(date 1713447867154)
@@ -374,8 +374,8 @@
             () -> true,
             TestIndexNameExpressionResolver.newInstance(threadPool.getThreadContext()),
             Collections.emptyMap(),
-            mock(SlowLogFieldProvider.class)
-        );
+            mock(SlowLogFieldProvider.class),
+                telemetryProvider);
         security.onIndexModule(indexModule);
         // indexReaderWrapper is a SetOnce so if Security#onIndexModule had already set an ReaderWrapper we would get an exception here
         indexModule.setReaderWrapper(null);
Index: test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java b/test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java
--- a/test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java	(date 1713446759784)
@@ -1188,7 +1188,7 @@
             }
             try (DirectoryReader reader = DirectoryReader.open(directory)) {
                 int i = 0;
-                SourceLoader loader = mapper.sourceMapper().newSourceLoader(mapper.mapping());
+                SourceLoader loader = mapper.sourceMapper().newSourceLoader(meterRegistry, mapper.mapping());
                 StoredFieldLoader storedFieldLoader = loader.requiredStoredFields().isEmpty()
                     ? StoredFieldLoader.empty()
                     : StoredFieldLoader.create(false, loader.requiredStoredFields());
Index: test/framework/src/main/java/org/elasticsearch/search/MockSearchService.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/test/framework/src/main/java/org/elasticsearch/search/MockSearchService.java b/test/framework/src/main/java/org/elasticsearch/search/MockSearchService.java
--- a/test/framework/src/main/java/org/elasticsearch/search/MockSearchService.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/test/framework/src/main/java/org/elasticsearch/search/MockSearchService.java	(date 1713446759788)
@@ -23,7 +23,7 @@
 import org.elasticsearch.search.internal.ReaderContext;
 import org.elasticsearch.search.internal.SearchContext;
 import org.elasticsearch.search.internal.ShardSearchRequest;
-import org.elasticsearch.telemetry.tracing.Tracer;
+import org.elasticsearch.telemetry.TelemetryProvider;
 import org.elasticsearch.threadpool.ThreadPool;
 
 import java.io.IOException;
@@ -85,7 +85,7 @@
         ResponseCollectorService responseCollectorService,
         CircuitBreakerService circuitBreakerService,
         ExecutorSelector executorSelector,
-        Tracer tracer
+        TelemetryProvider telemetryProvider
     ) {
         super(
             clusterService,
@@ -97,7 +97,7 @@
             responseCollectorService,
             circuitBreakerService,
             executorSelector,
-            tracer
+            telemetryProvider
         );
     }
 
Index: server/src/test/java/org/elasticsearch/search/DefaultSearchContextTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/test/java/org/elasticsearch/search/DefaultSearchContextTests.java b/server/src/test/java/org/elasticsearch/search/DefaultSearchContextTests.java
--- a/server/src/test/java/org/elasticsearch/search/DefaultSearchContextTests.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/test/java/org/elasticsearch/search/DefaultSearchContextTests.java	(date 1713446759763)
@@ -175,8 +175,8 @@
                 null,
                 randomFrom(SearchService.ResultsType.values()),
                 randomBoolean(),
-                randomInt()
-            );
+                randomInt(),
+                    meterRegistry);
             contextWithoutScroll.from(300);
             contextWithoutScroll.close();
 
@@ -217,8 +217,8 @@
                     null,
                     randomFrom(SearchService.ResultsType.values()),
                     randomBoolean(),
-                    randomInt()
-                )
+                    randomInt(),
+                        meterRegistry)
             ) {
                 context1.from(300);
                 exception = expectThrows(IllegalArgumentException.class, context1::preProcess);
@@ -296,8 +296,8 @@
                     null,
                     randomFrom(SearchService.ResultsType.values()),
                     randomBoolean(),
-                    randomInt()
-                )
+                    randomInt(),
+                        meterRegistry)
             ) {
 
                 SliceBuilder sliceBuilder = mock(SliceBuilder.class);
@@ -338,8 +338,8 @@
                     null,
                     randomFrom(SearchService.ResultsType.values()),
                     randomBoolean(),
-                    randomInt()
-                )
+                    randomInt(),
+                        meterRegistry)
             ) {
                 context3.sliceBuilder(null).parsedQuery(parsedQuery).preProcess();
                 assertEquals(context3.query(), context3.buildFilteredQuery(parsedQuery.query()));
@@ -369,8 +369,8 @@
                     null,
                     randomFrom(SearchService.ResultsType.values()),
                     randomBoolean(),
-                    randomInt()
-                )
+                    randomInt(),
+                        meterRegistry)
             ) {
                 context4.sliceBuilder(new SliceBuilder(1, 2)).parsedQuery(parsedQuery).preProcess();
                 Query query1 = context4.query();
@@ -440,8 +440,8 @@
                 null,
                 randomFrom(SearchService.ResultsType.values()),
                 randomBoolean(),
-                randomInt()
-            );
+                randomInt(),
+                    meterRegistry);
 
             assertThat(context.searcher().hasCancellations(), is(false));
             context.searcher().addQueryCancellation(() -> {});
@@ -906,8 +906,8 @@
                 null,
                 randomFrom(SearchService.ResultsType.values()),
                 randomBoolean(),
-                randomInt()
-            );
+                randomInt(),
+                    meterRegistry);
         }
     }
 
Index: server/src/main/java/org/elasticsearch/index/shard/IndexShard.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java b/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java
--- a/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java	(date 1713447867163)
@@ -149,6 +149,7 @@
 import org.elasticsearch.rest.RestStatus;
 import org.elasticsearch.search.internal.FieldUsageTrackingDirectoryReader;
 import org.elasticsearch.search.suggest.completion.CompletionStats;
+import org.elasticsearch.telemetry.TelemetryProvider;
 import org.elasticsearch.threadpool.ThreadPool;
 
 import java.io.Closeable;
@@ -321,8 +322,8 @@
         final CircuitBreakerService circuitBreakerService,
         final IndexStorePlugin.SnapshotCommitSupplier snapshotCommitSupplier,
         final LongSupplier relativeTimeInNanosSupplier,
-        final Engine.IndexCommitListener indexCommitListener
-    ) throws IOException {
+        final Engine.IndexCommitListener indexCommitListener,
+        TelemetryProvider telemetryProvider) throws IOException {
         super(shardRouting.shardId(), indexSettings);
         assert shardRouting.initializing();
         this.shardRouting = shardRouting;
@@ -351,7 +352,7 @@
             CollectionUtils.appendToCopyNoNullElements(searchOperationListener, searchStats),
             logger
         );
-        this.getService = new ShardGetService(indexSettings, this, mapperService);
+        this.getService = new ShardGetService(telemetryProvider, indexSettings, this, mapperService);
         this.shardWarmerService = new ShardIndexWarmerService(shardId, indexSettings);
         this.requestCacheStats = new ShardRequestCache();
         this.shardFieldData = new ShardFieldData();
Index: test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java b/test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java
--- a/test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/test/framework/src/main/java/org/elasticsearch/test/TestSearchContext.java	(date 1713446759760)
@@ -530,7 +530,7 @@
 
     @Override
     public SourceLoader newSourceLoader() {
-        return searchExecutionContext.newSourceLoader(false);
+        return searchExecutionContext.newSourceLoader(meterRegistry, false);
     }
 
     @Override
Index: server/src/main/java/org/elasticsearch/index/mapper/MappingLookup.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MappingLookup.java b/server/src/main/java/org/elasticsearch/index/mapper/MappingLookup.java
--- a/server/src/main/java/org/elasticsearch/index/mapper/MappingLookup.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/mapper/MappingLookup.java	(date 1713446759787)
@@ -15,6 +15,7 @@
 import org.elasticsearch.index.analysis.IndexAnalyzers;
 import org.elasticsearch.index.analysis.NamedAnalyzer;
 import org.elasticsearch.inference.InferenceService;
+import org.elasticsearch.telemetry.metric.MeterRegistry;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -483,9 +484,9 @@
     /**
      * Build something to load source {@code _source}.
      */
-    public SourceLoader newSourceLoader() {
+    public SourceLoader newSourceLoader(MeterRegistry meterRegistry) {
         SourceFieldMapper sfm = mapping.getMetadataMapperByClass(SourceFieldMapper.class);
-        return sfm == null ? SourceLoader.FROM_STORED_SOURCE : sfm.newSourceLoader(mapping);
+        return sfm == null ? SourceLoader.FROM_STORED_SOURCE : sfm.newSourceLoader(meterRegistry, mapping);
     }
 
     /**
Index: test/framework/src/main/java/org/elasticsearch/node/MockNode.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/test/framework/src/main/java/org/elasticsearch/node/MockNode.java b/test/framework/src/main/java/org/elasticsearch/node/MockNode.java
--- a/test/framework/src/main/java/org/elasticsearch/node/MockNode.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/test/framework/src/main/java/org/elasticsearch/node/MockNode.java	(date 1713446405957)
@@ -41,6 +41,7 @@
 import org.elasticsearch.search.SearchService;
 import org.elasticsearch.search.fetch.FetchPhase;
 import org.elasticsearch.tasks.TaskManager;
+import org.elasticsearch.telemetry.TelemetryProvider;
 import org.elasticsearch.telemetry.tracing.Tracer;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.test.MockHttpTransport;
@@ -91,17 +92,17 @@
 
         @Override
         SearchService newSearchService(
-            PluginsService pluginsService,
-            ClusterService clusterService,
-            IndicesService indicesService,
-            ThreadPool threadPool,
-            ScriptService scriptService,
-            BigArrays bigArrays,
-            FetchPhase fetchPhase,
-            ResponseCollectorService responseCollectorService,
-            CircuitBreakerService circuitBreakerService,
-            ExecutorSelector executorSelector,
-            Tracer tracer
+                PluginsService pluginsService,
+                ClusterService clusterService,
+                IndicesService indicesService,
+                ThreadPool threadPool,
+                ScriptService scriptService,
+                BigArrays bigArrays,
+                FetchPhase fetchPhase,
+                ResponseCollectorService responseCollectorService,
+                CircuitBreakerService circuitBreakerService,
+                ExecutorSelector executorSelector,
+                TelemetryProvider telemetryProvider
         ) {
             if (pluginsService.filterPlugins(MockSearchService.TestPlugin.class).findAny().isEmpty()) {
                 return super.newSearchService(
@@ -115,7 +116,7 @@
                     responseCollectorService,
                     circuitBreakerService,
                     executorSelector,
-                    tracer
+                    telemetryProvider
                 );
             }
             return new MockSearchService(
@@ -128,7 +129,7 @@
                 responseCollectorService,
                 circuitBreakerService,
                 executorSelector,
-                tracer
+                telemetryProvider
             );
         }
 
Index: test/framework/src/main/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/test/framework/src/main/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java b/test/framework/src/main/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java
--- a/test/framework/src/main/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/test/framework/src/main/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java	(date 1713446759774)
@@ -469,7 +469,7 @@
         when(indexShard.shardId()).thenReturn(new ShardId("test", "test", 0));
         when(indexShard.indexSettings()).thenReturn(indexSettings);
         when(ctx.indexShard()).thenReturn(indexShard);
-        when(ctx.newSourceLoader()).thenAnswer(inv -> searchExecutionContext.newSourceLoader(false));
+        when(ctx.newSourceLoader()).thenAnswer(inv -> searchExecutionContext.newSourceLoader(meterRegistry, false));
         when(ctx.newIdLoader()).thenReturn(IdLoader.fromLeafStoredFieldLoader());
         var res = new SubSearchContext(ctx);
         releasables.add(res); // TODO: nasty workaround for not getting the standard resource handling behavior of a real search context
Index: server/src/main/java/org/elasticsearch/indices/IndicesServiceBuilder.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/indices/IndicesServiceBuilder.java b/server/src/main/java/org/elasticsearch/indices/IndicesServiceBuilder.java
--- a/server/src/main/java/org/elasticsearch/indices/IndicesServiceBuilder.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/indices/IndicesServiceBuilder.java	(date 1713447867141)
@@ -32,6 +32,7 @@
 import org.elasticsearch.script.ScriptService;
 import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry;
 import org.elasticsearch.search.internal.ShardSearchRequest;
+import org.elasticsearch.telemetry.TelemetryProvider;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.xcontent.NamedXContentRegistry;
 
@@ -71,6 +72,7 @@
     Map<String, IndexStorePlugin.SnapshotCommitSupplier> snapshotCommitSuppliers = Map.of();
     @Nullable
     CheckedBiConsumer<ShardSearchRequest, StreamOutput, IOException> requestCacheKeyDifferentiator;
+    TelemetryProvider telemetryProvider;
 
     public IndicesServiceBuilder settings(Settings settings) {
         this.settings = settings;
@@ -168,6 +170,11 @@
         this.requestCacheKeyDifferentiator = requestCacheKeyDifferentiator;
         return this;
     }
+
+    public IndicesServiceBuilder telemetryProvider(TelemetryProvider telemetryProvider) {
+        this.telemetryProvider = telemetryProvider;
+        return this;
+    }
 
     public IndicesService build() {
         Objects.requireNonNull(settings);
Index: server/src/main/java/org/elasticsearch/search/SearchService.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/search/SearchService.java b/server/src/main/java/org/elasticsearch/search/SearchService.java
--- a/server/src/main/java/org/elasticsearch/search/SearchService.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/search/SearchService.java	(date 1713446759805)
@@ -121,6 +121,8 @@
 import org.elasticsearch.search.suggest.Suggest;
 import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
 import org.elasticsearch.tasks.TaskCancelledException;
+import org.elasticsearch.telemetry.TelemetryProvider;
+import org.elasticsearch.telemetry.metric.MeterRegistry;
 import org.elasticsearch.telemetry.tracing.Tracer;
 import org.elasticsearch.threadpool.Scheduler;
 import org.elasticsearch.threadpool.Scheduler.Cancellable;
@@ -307,6 +309,7 @@
     private final String sessionId = UUIDs.randomBase64UUID();
 
     private final Tracer tracer;
+    private final MeterRegistry meterRegistry;
 
     public SearchService(
         ClusterService clusterService,
@@ -318,7 +321,7 @@
         ResponseCollectorService responseCollectorService,
         CircuitBreakerService circuitBreakerService,
         ExecutorSelector executorSelector,
-        Tracer tracer
+        TelemetryProvider tracer
     ) {
         Settings settings = clusterService.getSettings();
         this.threadPool = threadPool;
@@ -334,7 +337,8 @@
             circuitBreakerService.getBreaker(CircuitBreaker.REQUEST)
         );
         this.executorSelector = executorSelector;
-        this.tracer = tracer;
+        this.tracer = tracer.getTracer();
+        this.meterRegistry = tracer.getMeterRegistry();
 
         TimeValue keepAliveInterval = KEEPALIVE_INTERVAL_SETTING.get(settings);
         setKeepAlives(DEFAULT_KEEPALIVE_SETTING.get(settings), MAX_KEEPALIVE_SETTING.get(settings));
@@ -1103,7 +1107,8 @@
                 executor,
                 resultsType,
                 enableQueryPhaseParallelCollection,
-                minimumDocsPerSlice
+                minimumDocsPerSlice,
+                meterRegistry
             );
             // we clone the query shard context here just for rewriting otherwise we
             // might end up with incorrect state since we are using now() or script services
Index: test/framework/src/main/java/org/elasticsearch/search/fetch/HighlighterTestCase.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/test/framework/src/main/java/org/elasticsearch/search/fetch/HighlighterTestCase.java b/test/framework/src/main/java/org/elasticsearch/search/fetch/HighlighterTestCase.java
--- a/test/framework/src/main/java/org/elasticsearch/search/fetch/HighlighterTestCase.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/test/framework/src/main/java/org/elasticsearch/search/fetch/HighlighterTestCase.java	(date 1713446759780)
@@ -112,7 +112,7 @@
         when(fetchContext.highlight()).thenReturn(search.highlighter().build(context));
         when(fetchContext.parsedQuery()).thenReturn(new ParsedQuery(search.query().toQuery(context)));
         when(fetchContext.getSearchExecutionContext()).thenReturn(context);
-        when(fetchContext.sourceLoader()).thenReturn(context.newSourceLoader(false));
+        when(fetchContext.sourceLoader()).thenReturn(context.newSourceLoader(meterRegistry, false));
         return fetchContext;
     }
 
Index: server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java
--- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java	(date 1713446759756)
@@ -2254,7 +2254,7 @@
                     responseCollectorService,
                     new NoneCircuitBreakerService(),
                     EmptySystemIndices.INSTANCE.getExecutorSelector(),
-                    Tracer.NOOP
+                    TelemetryProvider.NOOP
                 );
 
                 final SnapshotFilesProvider snapshotFilesProvider = new SnapshotFilesProvider(repositoriesService);
Index: server/src/main/java/org/elasticsearch/indices/IndicesService.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/indices/IndicesService.java b/server/src/main/java/org/elasticsearch/indices/IndicesService.java
--- a/server/src/main/java/org/elasticsearch/indices/IndicesService.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/indices/IndicesService.java	(date 1713447867169)
@@ -140,6 +140,7 @@
 import org.elasticsearch.search.internal.ShardSearchRequest;
 import org.elasticsearch.search.query.QueryPhase;
 import org.elasticsearch.search.query.QuerySearchResult;
+import org.elasticsearch.telemetry.TelemetryProvider;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.xcontent.XContentParser;
 import org.elasticsearch.xcontent.XContentParserConfiguration;
@@ -258,6 +259,7 @@
     private final ValuesSourceRegistry valuesSourceRegistry;
     private final TimestampFieldMapperService timestampFieldMapperService;
     private final CheckedBiConsumer<ShardSearchRequest, StreamOutput, IOException> requestCacheKeyDifferentiator;
+    private final TelemetryProvider telemetryProvider;
 
     @Override
     protected void doStart() {
@@ -374,6 +376,7 @@
         clusterService.getClusterSettings().addSettingsUpdateConsumer(ALLOW_EXPENSIVE_QUERIES, this::setAllowExpensiveQueries);
 
         this.timestampFieldMapperService = new TimestampFieldMapperService(settings, threadPool, this);
+        this.telemetryProvider = builder.telemetryProvider;
     }
 
     private static final String DANGLING_INDICES_UPDATE_THREAD_NAME = "DanglingIndices#updateTask";
@@ -739,7 +742,8 @@
             () -> allowExpensiveQueries,
             indexNameExpressionResolver,
             recoveryStateFactories,
-            loadSlowLogFieldProvider()
+            loadSlowLogFieldProvider(),
+            telemetryProvider
         );
         for (IndexingOperationListener operationListener : indexingOperationListeners) {
             indexModule.addIndexOperationListener(operationListener);
@@ -816,8 +820,8 @@
             () -> allowExpensiveQueries,
             indexNameExpressionResolver,
             recoveryStateFactories,
-            loadSlowLogFieldProvider()
-        );
+            loadSlowLogFieldProvider(),
+            telemetryProvider);
         pluginsService.forEach(p -> p.onIndexModule(indexModule));
         return indexModule.newIndexMapperService(clusterService, parserConfig, mapperRegistry, scriptService);
     }
Index: server/src/main/java/org/elasticsearch/index/query/SearchExecutionContext.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/query/SearchExecutionContext.java b/server/src/main/java/org/elasticsearch/index/query/SearchExecutionContext.java
--- a/server/src/main/java/org/elasticsearch/index/query/SearchExecutionContext.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/query/SearchExecutionContext.java	(date 1713446759800)
@@ -56,6 +56,7 @@
 import org.elasticsearch.search.lookup.LeafFieldLookupProvider;
 import org.elasticsearch.search.lookup.SearchLookup;
 import org.elasticsearch.search.lookup.SourceProvider;
+import org.elasticsearch.telemetry.metric.MeterRegistry;
 import org.elasticsearch.transport.RemoteClusterAware;
 import org.elasticsearch.xcontent.XContentParserConfiguration;
 
@@ -425,11 +426,11 @@
     /**
      * Build something to load source {@code _source}.
      */
-    public SourceLoader newSourceLoader(boolean forceSyntheticSource) {
+    public SourceLoader newSourceLoader(MeterRegistry meterRegistry, boolean forceSyntheticSource) {
         if (forceSyntheticSource) {
-            return new SourceLoader.Synthetic(mappingLookup.getMapping());
+            return new SourceLoader.Synthetic(meterRegistry, mappingLookup.getMapping());
         }
-        return mappingLookup.newSourceLoader();
+        return mappingLookup.newSourceLoader(meterRegistry);
     }
 
     /**
Index: server/src/internalClusterTest/java/org/elasticsearch/index/shard/IndexShardIT.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/index/shard/IndexShardIT.java b/server/src/internalClusterTest/java/org/elasticsearch/index/shard/IndexShardIT.java
--- a/server/src/internalClusterTest/java/org/elasticsearch/index/shard/IndexShardIT.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/internalClusterTest/java/org/elasticsearch/index/shard/IndexShardIT.java	(date 1713447867158)
@@ -628,8 +628,8 @@
             cbs,
             IndexModule.DEFAULT_SNAPSHOT_COMMIT_SUPPLIER,
             System::nanoTime,
-            null
-        );
+            null,
+                telemetryProvider);
     }
 
     private static ShardRouting getInitializingShardRouting(ShardRouting existingShardRouting) {
Index: x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherPluginTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherPluginTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherPluginTests.java
--- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherPluginTests.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherPluginTests.java	(date 1713447867171)
@@ -68,8 +68,8 @@
             () -> true,
             TestIndexNameExpressionResolver.newInstance(),
             Collections.emptyMap(),
-            mock(SlowLogFieldProvider.class)
-        );
+            mock(SlowLogFieldProvider.class),
+                telemetryProvider);
         // this will trip an assertion if the watcher indexing operation listener is null (which it is) but we try to add it
         watcher.onIndexModule(indexModule);
 
Index: server/src/test/java/org/elasticsearch/index/mapper/DocCountFieldMapperTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/test/java/org/elasticsearch/index/mapper/DocCountFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/DocCountFieldMapperTests.java
--- a/server/src/test/java/org/elasticsearch/index/mapper/DocCountFieldMapperTests.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/test/java/org/elasticsearch/index/mapper/DocCountFieldMapperTests.java	(date 1713446759776)
@@ -96,7 +96,7 @@
                 iw.addDocument(mapper.documentMapper().parse(source(b -> b.field("doc", doc).field(CONTENT_TYPE, c))).rootDoc());
             }
         }, reader -> {
-            SourceLoader loader = mapper.mappingLookup().newSourceLoader();
+            SourceLoader loader = mapper.mappingLookup().newSourceLoader(meterRegistry);
             assertTrue(loader.requiredStoredFields().isEmpty());
             for (LeafReaderContext leaf : reader.leaves()) {
                 int[] docIds = IntStream.range(0, leaf.reader().maxDoc()).toArray();
@@ -128,7 +128,7 @@
                 })).rootDoc());
             }
         }, reader -> {
-            SourceLoader loader = mapper.mappingLookup().newSourceLoader();
+            SourceLoader loader = mapper.mappingLookup().newSourceLoader(meterRegistry);
             assertTrue(loader.requiredStoredFields().isEmpty());
             for (LeafReaderContext leaf : reader.leaves()) {
                 int[] docIds = IntStream.range(0, leaf.reader().maxDoc()).toArray();
Index: server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java b/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java
--- a/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java	(date 1713446759778)
@@ -70,6 +70,7 @@
 import org.elasticsearch.search.slice.SliceBuilder;
 import org.elasticsearch.search.sort.SortAndFormats;
 import org.elasticsearch.search.suggest.SuggestionSearchContext;
+import org.elasticsearch.telemetry.metric.MeterRegistry;
 
 import java.io.IOException;
 import java.io.UncheckedIOException;
@@ -148,6 +149,7 @@
     private final Map<String, SearchExtBuilder> searchExtBuilders = new HashMap<>();
     private final SearchExecutionContext searchExecutionContext;
     private final FetchPhase fetchPhase;
+    private final MeterRegistry meterRegistry;
 
     DefaultSearchContext(
         ReaderContext readerContext,
@@ -160,11 +162,12 @@
         Executor executor,
         SearchService.ResultsType resultsType,
         boolean enableQueryPhaseParallelCollection,
-        int minimumDocsPerSlice
-    ) throws IOException {
+        int minimumDocsPerSlice,
+        MeterRegistry meterRegistry) throws IOException {
         this.readerContext = readerContext;
         this.request = request;
         this.fetchPhase = fetchPhase;
+        this.meterRegistry = meterRegistry;
         boolean success = false;
         try {
             this.searchType = request.searchType();
@@ -887,7 +890,7 @@
 
     @Override
     public SourceLoader newSourceLoader() {
-        return searchExecutionContext.newSourceLoader(request.isForceSyntheticSource());
+        return searchExecutionContext.newSourceLoader(meterRegistry, request.isForceSyntheticSource());
     }
 
     @Override
Index: server/src/main/java/org/elasticsearch/node/NodeConstruction.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/node/NodeConstruction.java b/server/src/main/java/org/elasticsearch/node/NodeConstruction.java
--- a/server/src/main/java/org/elasticsearch/node/NodeConstruction.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/node/NodeConstruction.java	(date 1713447867185)
@@ -736,6 +736,7 @@
             .metaStateService(metaStateService)
             .valuesSourceRegistry(searchModule.getValuesSourceRegistry())
             .requestCacheKeyDifferentiator(searchModule.getRequestCacheKeyDifferentiator())
+            .telemetryProvider(telemetryProvider)
             .build();
 
         final var parameters = new IndexSettingProvider.Parameters(indicesService::createIndexMapperServiceForValidation);
@@ -1008,7 +1009,7 @@
             responseCollectorService,
             circuitBreakerService,
             systemIndices.getExecutorSelector(),
-            telemetryProvider.getTracer()
+            telemetryProvider
         );
 
         modules.add(
Index: server/src/main/java/org/elasticsearch/index/get/ShardGetService.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/get/ShardGetService.java b/server/src/main/java/org/elasticsearch/index/get/ShardGetService.java
--- a/server/src/main/java/org/elasticsearch/index/get/ShardGetService.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/get/ShardGetService.java	(date 1713447867165)
@@ -33,6 +33,7 @@
 import org.elasticsearch.index.shard.MultiEngineGet;
 import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
 import org.elasticsearch.search.lookup.Source;
+import org.elasticsearch.telemetry.TelemetryProvider;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -53,11 +54,13 @@
     private final MeanMetric missingMetric = new MeanMetric();
     private final CounterMetric currentMetric = new CounterMetric();
     private final IndexShard indexShard;
+    private final TelemetryProvider telemetryProvider;
 
-    public ShardGetService(IndexSettings indexSettings, IndexShard indexShard, MapperService mapperService) {
+    public ShardGetService(TelemetryProvider telemetryProvider, IndexSettings indexSettings, IndexShard indexShard, MapperService mapperService) {
         super(indexShard.shardId(), indexSettings);
         this.mapperService = mapperService;
         this.indexShard = indexShard;
+        this.telemetryProvider = telemetryProvider;
     }
 
     public GetStats stats() {
@@ -297,8 +300,8 @@
         Map<String, DocumentField> metadataFields = null;
         DocIdAndVersion docIdAndVersion = get.docIdAndVersion();
         SourceLoader loader = forceSyntheticSource
-            ? new SourceLoader.Synthetic(mappingLookup.getMapping())
-            : mappingLookup.newSourceLoader();
+            ? new SourceLoader.Synthetic(telemetryProvider.getMeterRegistry(), mappingLookup.getMapping())
+            : mappingLookup.newSourceLoader(telemetryProvider.getMeterRegistry());
         StoredFieldLoader storedFieldLoader = buildStoredFieldLoader(storedFields, fetchSourceContext, loader);
         LeafStoredFieldLoader leafStoredFieldLoader = storedFieldLoader.getLoader(docIdAndVersion.reader.getContext(), null);
         try {
Index: server/src/test/java/org/elasticsearch/index/mapper/SourceLoaderTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/test/java/org/elasticsearch/index/mapper/SourceLoaderTests.java b/server/src/test/java/org/elasticsearch/index/mapper/SourceLoaderTests.java
--- a/server/src/test/java/org/elasticsearch/index/mapper/SourceLoaderTests.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/test/java/org/elasticsearch/index/mapper/SourceLoaderTests.java	(date 1713446759749)
@@ -20,7 +20,7 @@
             b.startObject("o").field("type", "object").endObject();
             b.startObject("kwd").field("type", "keyword").endObject();
         }));
-        assertFalse(mapper.mappers().newSourceLoader().reordersFieldValues());
+        assertFalse(mapper.mappers().newSourceLoader(meterRegistry).reordersFieldValues());
     }
 
     public void testEmptyObject() throws IOException {
@@ -28,7 +28,7 @@
             b.startObject("o").field("type", "object").endObject();
             b.startObject("kwd").field("type", "keyword").endObject();
         }));
-        assertTrue(mapper.mappers().newSourceLoader().reordersFieldValues());
+        assertTrue(mapper.mappers().newSourceLoader(meterRegistry).reordersFieldValues());
         assertThat(syntheticSource(mapper, b -> b.field("kwd", "foo")), equalTo("""
             {"kwd":"foo"}"""));
     }
Index: server/src/main/java/org/elasticsearch/index/mapper/SourceLoader.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SourceLoader.java b/server/src/main/java/org/elasticsearch/index/mapper/SourceLoader.java
--- a/server/src/main/java/org/elasticsearch/index/mapper/SourceLoader.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/index/mapper/SourceLoader.java	(date 1713446759794)
@@ -12,6 +12,7 @@
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.index.fieldvisitor.LeafStoredFieldLoader;
 import org.elasticsearch.search.lookup.Source;
+import org.elasticsearch.telemetry.metric.MeterRegistry;
 import org.elasticsearch.xcontent.XContentBuilder;
 import org.elasticsearch.xcontent.json.JsonXContent;
 
@@ -82,13 +83,15 @@
     class Synthetic implements SourceLoader {
         private final Supplier<SyntheticFieldLoader> syntheticFieldLoaderLeafSupplier;
         private final Set<String> requiredStoredFields;
+        private final MeterRegistry meterRegistry;
 
-        public Synthetic(Mapping mapping) {
+        public Synthetic(MeterRegistry meterRegistry, Mapping mapping) {
             this.syntheticFieldLoaderLeafSupplier = mapping::syntheticFieldLoader;
             this.requiredStoredFields = syntheticFieldLoaderLeafSupplier.get()
                 .storedFieldLoaders()
                 .map(Map.Entry::getKey)
                 .collect(Collectors.toSet());
+            this.meterRegistry = meterRegistry;
         }
 
         @Override
@@ -103,6 +106,7 @@
 
         @Override
         public Leaf leaf(LeafReader reader, int[] docIdsInLeaf) throws IOException {
+            // use meterRegistry
             SyntheticFieldLoader loader = syntheticFieldLoaderLeafSupplier.get();
             return new SyntheticLeaf(loader, loader.docValuesLoader(reader, docIdsInLeaf));
         }
Index: server/src/main/java/org/elasticsearch/search/lookup/SyntheticSourceProvider.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/server/src/main/java/org/elasticsearch/search/lookup/SyntheticSourceProvider.java b/server/src/main/java/org/elasticsearch/search/lookup/SyntheticSourceProvider.java
--- a/server/src/main/java/org/elasticsearch/search/lookup/SyntheticSourceProvider.java	(revision f5c7938ab8043383aebeac0998a40967da55f924)
+++ b/server/src/main/java/org/elasticsearch/search/lookup/SyntheticSourceProvider.java	(date 1713446759770)
@@ -26,7 +26,7 @@
     private volatile SyntheticSourceLeafLoader[] leafLoaders;
 
     SyntheticSourceProvider(Mapping mapping) {
-        sourceLoader = new SourceLoader.Synthetic(mapping);
+        sourceLoader = new SourceLoader.Synthetic(meterRegistry, mapping);
     }
 
     @Override

@lkts
Copy link
Contributor Author

lkts commented Apr 25, 2024

@elasticmachine update branch

@lkts lkts force-pushed the feature/synthetic_source_metrics branch from 2a01fa3 to 925d45d Compare April 25, 2024 22:38
@lkts
Copy link
Contributor Author

lkts commented Apr 25, 2024

I have absolutely no idea how could my changes break painless tests.

@lkts lkts force-pushed the feature/synthetic_source_metrics branch from 925d45d to 843d670 Compare April 25, 2024 23:42
@lkts
Copy link
Contributor Author

lkts commented Apr 29, 2024

@elasticmachine update branch

@elasticmachine
Copy link
Collaborator

merge conflict between base and head

* Groups together all metrics used in mappers.
* Main purpose of this class is to avoid verbosity of passing individual metric instances around.
*/
public record MapperMetrics(SourceFieldMetrics sourceFieldMetrics) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should make this even more generic given that it is now in SearchExecutionContext.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine, but I'd use a container like SearchExecutionMetrics to the context and include MapperMetrics in it.

@lkts lkts requested review from martijnvg and kkrik-es April 30, 2024 22:28
@kkrik-es
Copy link
Contributor

kkrik-es commented May 1, 2024

Not a big fan of updating all those classes.. Will leave it to Martijn to decide.

* Main purpose of this class is to avoid verbosity of passing individual metric instances around.
*/
public record MapperMetrics(SourceFieldMetrics sourceFieldMetrics) {
public static MapperMetrics NOOP = new MapperMetrics(SourceFieldMetrics.NOOP);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are this NOOP instance and the other one in SourceFieldMetrics only used in non production code? Otherwise maybe we can move it to test framework?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost - it is used in benchmarks too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, maybe then let's keep it here.

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@lkts lkts merged commit 954efe0 into elastic:main May 14, 2024
15 checks passed
@lkts lkts deleted the feature/synthetic_source_metrics branch May 14, 2024 20:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants