This is an automated email from the ASF dual-hosted git repository.

apolovtsev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 09bbc1be158 IGNITE-17718 MetricManager refactoring (#7682)
09bbc1be158 is described below

commit 09bbc1be1587f585576a28e0957358fe5b885f78
Author: Alexander Polovtcev <[email protected]>
AuthorDate: Fri Feb 27 10:27:04 2026 +0200

    IGNITE-17718 MetricManager refactoring (#7682)
---
 modules/client-handler/build.gradle                |   1 +
 .../apache/ignite/client/handler/TestServer.java   |   4 +-
 modules/client/build.gradle                        |   1 +
 .../internal/client/ClientMetricManager.java       |  47 ++++
 .../ignite/internal/client/TcpIgniteClient.java    |   5 +-
 .../java/org/apache/ignite/client/TestServer.java  |   4 +-
 .../exporters/otlp/OtlpPushMetricExporterTest.java |   6 +-
 .../metrics/exporters/ItJvmMetricSourceTest.java   |  12 +-
 .../exporters/ItMetricExportersLoadingTest.java    |   8 +-
 .../metrics/exporters/ItOsMetricSourceTest.java    |   9 +-
 .../internal/metrics/AbstractMetricManager.java    | 174 ++++++++++++
 .../ignite/internal/metrics/MetricManager.java     |  31 ---
 .../ignite/internal/metrics/MetricManagerImpl.java | 308 +++++----------------
 .../internal/metrics/exporters/MetricExporter.java |   8 +-
 .../internal/metrics/MetricConfigurationTest.java  |  14 +-
 .../ignite/internal/metrics/MetricManagerTest.java |   8 +-
 .../metrics/exporters/PushExporterTest.java        |  16 +-
 .../metrics/exporters/log/LogPushExporterTest.java |   6 +-
 .../ignite/internal/metrics/NoOpMetricManager.java |  16 --
 .../ignite/internal/metrics/TestMetricManager.java |  19 --
 .../runner/app/ItIgniteNodeRestartTest.java        |   5 +-
 .../org/apache/ignite/internal/app/IgniteImpl.java |  12 +-
 .../sql/engine/planner/PlannerTimeoutTest.java     |   5 +-
 .../sql/engine/prepare/PrepareServiceImplTest.java |   6 +-
 .../sql/metrics/PlanningCacheMetricsTest.java      |   3 +-
 25 files changed, 338 insertions(+), 390 deletions(-)

diff --git a/modules/client-handler/build.gradle 
b/modules/client-handler/build.gradle
index 12c531f5378..ede09e164b9 100644
--- a/modules/client-handler/build.gradle
+++ b/modules/client-handler/build.gradle
@@ -84,6 +84,7 @@ dependencies {
     integrationTestImplementation testFixtures(project(':ignite-table'))
     integrationTestImplementation 
testFixtures(project(':ignite-client-handler'))
     integrationTestImplementation 
testFixtures(project(':ignite-low-watermark'))
+    integrationTestImplementation testFixtures(project(':ignite-metrics'))
     integrationTestImplementation testFixtures(project(':ignite-schema'))
     integrationTestImplementation libs.msgpack.core
     integrationTestImplementation libs.netty.handler
diff --git 
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/TestServer.java
 
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/TestServer.java
index 708e1cf7435..066656b8b0d 100644
--- 
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/TestServer.java
+++ 
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/TestServer.java
@@ -34,7 +34,7 @@ import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.TestClockService;
 import org.apache.ignite.internal.lowwatermark.TestLowWatermark;
 import org.apache.ignite.internal.manager.ComponentContext;
-import org.apache.ignite.internal.metrics.MetricManagerImpl;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NettyBootstrapFactory;
 import org.apache.ignite.internal.network.configuration.NetworkConfiguration;
@@ -131,7 +131,7 @@ public class TestServer {
                 clusterService,
                 bootstrapFactory,
                 () -> new ClusterInfo(clusterTag, 
List.of(clusterTag.clusterId())),
-                mock(MetricManagerImpl.class),
+                new NoOpMetricManager(),
                 metrics,
                 authenticationManager,
                 new TestClockService(new HybridClockImpl()),
diff --git a/modules/client/build.gradle b/modules/client/build.gradle
index 129a7c8d333..1aefe0f95b2 100644
--- a/modules/client/build.gradle
+++ b/modules/client/build.gradle
@@ -66,6 +66,7 @@ dependencies {
     testImplementation testFixtures(project(':ignite-table'))
     testImplementation testFixtures(project(':ignite-client-handler'))
     testImplementation testFixtures(project(':ignite-low-watermark'))
+    testImplementation testFixtures(project(':ignite-metrics'))
     testImplementation testFixtures(project(':ignite-schema'))
     testImplementation libs.archunit.core
     testImplementation libs.archunit.junit5
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/ClientMetricManager.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/ClientMetricManager.java
new file mode 100644
index 00000000000..29d8d589ace
--- /dev/null
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/ClientMetricManager.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client;
+
+import static 
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
+import static org.apache.ignite.internal.util.IgniteUtils.inBusyLockAsync;
+
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.internal.manager.ComponentContext;
+import org.apache.ignite.internal.metrics.AbstractMetricManager;
+import org.apache.ignite.internal.metrics.exporters.MetricExporter;
+
+class ClientMetricManager extends AbstractMetricManager {
+    private final String clientName;
+
+    ClientMetricManager(String clientName, MetricExporter... exporters) {
+        this.clientName = clientName;
+
+        for (MetricExporter exporter : exporters) {
+            enabledMetricExporters.put(exporter.name(), exporter);
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> startAsync(ComponentContext 
componentContext) {
+        return inBusyLockAsync(busyLock, () -> {
+            enabledMetricExporters.values().forEach(e -> e.start(registry, 
null, null, clientName));
+
+            return nullCompletedFuture();
+        });
+    }
+}
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
index febb5513361..28028d5e48e 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
@@ -40,7 +40,6 @@ import 
org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.manager.ComponentContext;
 import org.apache.ignite.internal.marshaller.ReflectionMarshallersProvider;
 import org.apache.ignite.internal.metrics.MetricManager;
-import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.metrics.exporters.jmx.JmxExporter;
 import org.apache.ignite.internal.tostring.S;
 import org.apache.ignite.lang.ErrorGroups;
@@ -148,11 +147,11 @@ public class TcpIgniteClient implements IgniteClient {
             return null;
         }
 
-        var metricManager = new MetricManagerImpl(ClientUtils.logger(cfg, 
MetricManagerImpl.class), clientName);
+        var metricManager = new ClientMetricManager(clientName, new 
JmxExporter(ClientUtils.logger(cfg, JmxExporter.class)));
 
+        metricManager.startAsync(new ComponentContext()).join();
         metricManager.registerSource(metrics);
         metricManager.enable(metrics);
-        metricManager.start(List.of(new JmxExporter(ClientUtils.logger(cfg, 
JmxExporter.class))));
 
         return metricManager;
     }
diff --git 
a/modules/client/src/test/java/org/apache/ignite/client/TestServer.java 
b/modules/client/src/test/java/org/apache/ignite/client/TestServer.java
index 33de44b9d7c..2c326849e42 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/TestServer.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/TestServer.java
@@ -65,7 +65,7 @@ import org.apache.ignite.internal.hlc.TestClockService;
 import org.apache.ignite.internal.lowwatermark.TestLowWatermark;
 import org.apache.ignite.internal.manager.ComponentContext;
 import org.apache.ignite.internal.manager.IgniteComponent;
-import org.apache.ignite.internal.metrics.MetricManagerImpl;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterNodeImpl;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.InternalClusterNode;
@@ -281,7 +281,7 @@ public class TestServer implements AutoCloseable {
                         clusterService,
                         bootstrapFactory,
                         () -> clusterInfo,
-                        mock(MetricManagerImpl.class),
+                        new NoOpMetricManager(),
                         metrics,
                         authenticationManager,
                         new TestClockService(ignite.clock()),
diff --git 
a/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
 
b/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
index 4d9b1caacff..db807fdc7e7 100644
--- 
a/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
+++ 
b/modules/metrics-exporter-otlp/src/test/java/org/apache/ignite/internal/metrics/exporters/otlp/OtlpPushMetricExporterTest.java
@@ -57,7 +57,6 @@ import org.apache.ignite.internal.metrics.LongAdderMetric;
 import org.apache.ignite.internal.metrics.LongGauge;
 import org.apache.ignite.internal.metrics.LongMetric;
 import org.apache.ignite.internal.metrics.Metric;
-import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.metrics.MetricSet;
 import org.apache.ignite.internal.metrics.configuration.MetricChange;
@@ -109,7 +108,7 @@ class OtlpPushMetricExporterTest extends 
BaseIgniteAbstractTest {
                     )
             );
 
-    private MetricManager metricManager;
+    private MetricManagerImpl metricManager;
 
     private MetricExporter metricsExporter;
 
@@ -120,9 +119,8 @@ class OtlpPushMetricExporterTest extends 
BaseIgniteAbstractTest {
 
     @BeforeEach
     void setUp() {
-        metricManager = new MetricManagerImpl();
+        metricManager = new MetricManagerImpl("nodeName", () -> CLUSTER_ID, 
metricConfiguration);
 
-        metricManager.configure(metricConfiguration, () -> CLUSTER_ID, 
"nodeName");
         metricManager.registerSource(new TestMetricSource(SRC_NAME, 
metricSet));
 
         exporter = new OtlpPushMetricExporter();
diff --git 
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
index acf7f3c4d0f..929b405176c 100644
--- 
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
+++ 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
@@ -22,13 +22,11 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import org.apache.ignite.internal.manager.ComponentContext;
-import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.sources.JvmMetricSource;
@@ -53,19 +51,13 @@ public class ItJvmMetricSourceTest extends 
BaseIgniteAbstractTest {
 
     @Test
     public void testMemoryUsageMetric() {
-        MetricManager metricManager = new MetricManagerImpl();
-
-        metricManager.configure(simpleConfiguration, UUID::randomUUID, 
"test-node");
-
-        Map<String, MetricExporter> exporters = new HashMap<>();
+        var metricManager = new MetricManagerImpl("test-node", 
UUID::randomUUID, simpleConfiguration);
 
         TestSimpleExporter simpleExporter = new TestSimpleExporter();
 
-        exporters.put(simpleExporter.name(), simpleExporter);
-
         metricManager.registerSource(new JvmMetricSource());
 
-        metricManager.start(exporters);
+        metricManager.start(Map.of(simpleExporter.name(), simpleExporter));
 
         metricManager.enable("jvm");
 
diff --git 
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItMetricExportersLoadingTest.java
 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItMetricExportersLoadingTest.java
index d1ee095e330..b76ffa86490 100644
--- 
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItMetricExportersLoadingTest.java
+++ 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItMetricExportersLoadingTest.java
@@ -55,9 +55,7 @@ public class ItMetricExportersLoadingTest extends 
BaseIgniteAbstractTest {
 
     @Test
     public void test() throws Exception {
-        MetricManager metricManager = new MetricManagerImpl();
-
-        metricManager.configure(metricConfiguration, UUID::randomUUID, 
"test-node");
+        MetricManager metricManager = new MetricManagerImpl("test-node", 
UUID::randomUUID, metricConfiguration);
 
         TestMetricsSource src = new TestMetricsSource("TestMetricsSource");
 
@@ -93,9 +91,7 @@ public class ItMetricExportersLoadingTest extends 
BaseIgniteAbstractTest {
 
     @Test
     public void shouldChangePeriod() throws Exception {
-        MetricManager metricManager = new MetricManagerImpl();
-
-        metricManager.configure(metricConfiguration, UUID::randomUUID, 
"test-node");
+        MetricManager metricManager = new MetricManagerImpl("test-node", 
UUID::randomUUID, metricConfiguration);
 
         TestMetricsSource src = new TestMetricsSource("TestMetricsSource");
 
diff --git 
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItOsMetricSourceTest.java
 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItOsMetricSourceTest.java
index f2b6918e47c..2dd769e0d01 100644
--- 
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItOsMetricSourceTest.java
+++ 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItOsMetricSourceTest.java
@@ -21,13 +21,11 @@ import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutur
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.greaterThan;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import org.apache.ignite.internal.manager.ComponentContext;
-import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.sources.OsMetricSource;
@@ -49,16 +47,13 @@ class ItOsMetricSourceTest extends BaseIgniteAbstractTest {
 
     @Test
     void testOsMetrics() {
-        MetricManager metricManager = new MetricManagerImpl();
-        metricManager.configure(simpleConfiguration, UUID::randomUUID, 
"test-node");
+        var metricManager = new MetricManagerImpl("test-node", 
UUID::randomUUID, simpleConfiguration);
 
-        Map<String, MetricExporter> exporters = new HashMap<>();
         TestSimpleExporter simpleExporter = new TestSimpleExporter();
-        exporters.put(simpleExporter.name(), simpleExporter);
 
         metricManager.registerSource(new OsMetricSource());
 
-        metricManager.start(exporters);
+        metricManager.start(Map.of(simpleExporter.name(), simpleExporter));
 
         metricManager.enable("os");
 
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/AbstractMetricManager.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/AbstractMetricManager.java
new file mode 100644
index 00000000000..072d35836ff
--- /dev/null
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/AbstractMetricManager.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metrics;
+
+import static 
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
+import static org.apache.ignite.internal.util.IgniteUtils.closeAllManually;
+import static org.apache.ignite.internal.util.IgniteUtils.inBusyLock;
+import static org.apache.ignite.internal.util.IgniteUtils.inBusyLockSafe;
+import static org.apache.ignite.lang.ErrorGroups.Common.RESOURCE_CLOSING_ERR;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Stream;
+import org.apache.ignite.internal.close.ManuallyCloseable;
+import org.apache.ignite.internal.lang.IgniteInternalException;
+import org.apache.ignite.internal.manager.ComponentContext;
+import org.apache.ignite.internal.metrics.exporters.MetricExporter;
+import org.apache.ignite.internal.util.IgniteSpinBusyLock;
+
+/** Base implementation of {@link MetricManager}. */
+public abstract class AbstractMetricManager implements MetricManager {
+    protected final MetricRegistry registry = new MetricRegistry();
+
+    protected final Map<String, MetricExporter> enabledMetricExporters = new 
ConcurrentHashMap<>();
+
+    protected final IgniteSpinBusyLock busyLock = new IgniteSpinBusyLock();
+
+    private final AtomicBoolean stopGuard = new AtomicBoolean();
+
+    @Override
+    public void beforeNodeStop() {
+        if (!stopGuard.compareAndSet(false, true)) {
+            return;
+        }
+
+        busyLock.block();
+
+        try {
+            closeAllManually(Stream.concat(
+                    
enabledMetricExporters.values().stream().map(metricExporter -> 
(ManuallyCloseable) metricExporter::stop),
+                    Stream.of(registry)
+            ));
+        } catch (Exception e) {
+            throw new IgniteInternalException(RESOURCE_CLOSING_ERR, e);
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> stopAsync(ComponentContext 
componentContext) {
+        enabledMetricExporters.clear();
+
+        return nullCompletedFuture();
+    }
+
+    @Override
+    public void registerSource(MetricSource src) {
+        inBusyLock(busyLock, () -> registry.registerSource(src));
+    }
+
+    @Override
+    public void unregisterSource(MetricSource src) {
+        inBusyLockSafe(busyLock, () -> {
+            if (metricSources().contains(src)) {
+                MetricSet metricSet = getMetricSet(src.name());
+
+                registry.unregisterSource(src);
+
+                removeMetricSet(metricSet);
+            }
+        });
+    }
+
+    @Override
+    public void unregisterSource(String srcName) {
+        inBusyLockSafe(busyLock, () -> {
+            if (metricSources().stream().anyMatch(metricSource -> 
metricSource.name().equals(srcName))) {
+                MetricSet metricSet = getMetricSet(srcName);
+
+                registry.unregisterSource(srcName);
+
+                removeMetricSet(metricSet);
+            }
+        });
+    }
+
+    @Override
+    public MetricSet enable(MetricSource src) {
+        return inBusyLock(busyLock, () -> {
+            MetricSet enabled = registry.enable(src);
+
+            if (enabled != null) {
+                enabledMetricExporters.values().forEach(e -> 
e.addMetricSet(enabled));
+            }
+
+            return enabled;
+        });
+    }
+
+    @Override
+    public MetricSet enable(String srcName) {
+        return inBusyLock(busyLock, () -> {
+            MetricSet enabled = registry.enable(srcName);
+
+            if (enabled != null) {
+                enabledMetricExporters.values().forEach(e -> 
e.addMetricSet(enabled));
+            }
+
+            return enabled;
+        });
+    }
+
+    @Override
+    public void disable(MetricSource src) {
+        inBusyLockSafe(busyLock, () -> {
+            MetricSet metricSet = getMetricSet(src.name());
+
+            registry.disable(src);
+
+            removeMetricSet(metricSet);
+        });
+    }
+
+    @Override
+    public void disable(String srcName) {
+        inBusyLockSafe(busyLock, () -> {
+            MetricSet metricSet = getMetricSet(srcName);
+
+            registry.disable(srcName);
+
+            removeMetricSet(metricSet);
+        });
+    }
+
+    private MetricSet getMetricSet(String srcName) {
+        return registry.snapshot().metrics().get(srcName);
+    }
+
+    private void removeMetricSet(MetricSet metricSet) {
+        enabledMetricExporters.values().forEach(e -> 
e.removeMetricSet(metricSet));
+    }
+
+    @Override
+    public MetricSnapshot metricSnapshot() {
+        return inBusyLock(busyLock, registry::snapshot);
+    }
+
+    @Override
+    public Collection<MetricSource> metricSources() {
+        return inBusyLock(busyLock, registry::metricSources);
+    }
+
+    @Override
+    public Collection<MetricExporter> enabledExporters() {
+        return inBusyLock(busyLock, enabledMetricExporters::values);
+    }
+}
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
index b9201d06107..c3a0b28867a 100644
--- 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
@@ -18,45 +18,14 @@
 package org.apache.ignite.internal.metrics;
 
 import java.util.Collection;
-import java.util.Map;
-import java.util.UUID;
-import java.util.function.Supplier;
 import org.apache.ignite.internal.manager.IgniteComponent;
-import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.exporters.MetricExporter;
 import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.VisibleForTesting;
 
 /**
  * The component services of the metrics. It has functions to switch on / off 
and register them.
  */
 public interface MetricManager extends IgniteComponent {
-    /**
-     * Method to configure {@link MetricManager} with distributed 
configuration.
-     *
-     * @param metricConfiguration Distributed metric configuration.
-     * @param clusterIdSupplier Cluster ID supplier.
-     * @param nodeName Node name.
-     */
-    // TODO: IGNITE-17718 when we design the system to configure metrics itself
-    // TODO: this method should be revisited, but now it is supposed to use 
only to set distributed configuration for exporters.
-    void configure(MetricConfiguration metricConfiguration, Supplier<UUID> 
clusterIdSupplier, String nodeName);
-
-    /**
-     * Start component.
-     *
-     * @param availableExporters Map of (name, exporter) with available 
exporters.
-     */
-    @VisibleForTesting
-    void start(Map<String, MetricExporter> availableExporters);
-
-    /**
-     * Starts component with default configuration.
-     *
-     * @param exporters Exporters.
-     */
-    void start(Iterable<MetricExporter> exporters);
-
     /**
      * Register metric source. See {@link 
MetricRegistry#registerSource(MetricSource)}.
      *
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
index ebb67a26119..1ec0cd2520b 100644
--- 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
@@ -17,99 +17,65 @@
 
 package org.apache.ignite.internal.metrics;
 
-import static java.util.Collections.emptyList;
-import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toUnmodifiableMap;
 import static 
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
-import static org.apache.ignite.internal.util.IgniteUtils.closeAllManually;
-import static org.apache.ignite.internal.util.IgniteUtils.inBusyLock;
 import static org.apache.ignite.internal.util.IgniteUtils.inBusyLockAsync;
 import static org.apache.ignite.internal.util.IgniteUtils.inBusyLockSafe;
-import static org.apache.ignite.lang.ErrorGroups.Common.RESOURCE_CLOSING_ERR;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.ServiceLoader;
 import java.util.ServiceLoader.Provider;
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Function;
 import java.util.function.Supplier;
-import java.util.stream.Stream;
 import 
org.apache.ignite.configuration.notifications.ConfigurationNamedListListener;
 import 
org.apache.ignite.configuration.notifications.ConfigurationNotificationEvent;
-import org.apache.ignite.internal.close.ManuallyCloseable;
-import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.manager.ComponentContext;
 import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
-import org.apache.ignite.internal.metrics.configuration.MetricView;
 import org.apache.ignite.internal.metrics.exporters.MetricExporter;
 import org.apache.ignite.internal.metrics.exporters.configuration.ExporterView;
 import 
org.apache.ignite.internal.metrics.exporters.configuration.LogPushExporterConfigurationSchema;
 import 
org.apache.ignite.internal.metrics.exporters.configuration.LogPushExporterView;
 import org.apache.ignite.internal.metrics.exporters.log.LogPushExporter;
-import org.apache.ignite.internal.util.IgniteSpinBusyLock;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
 import org.jetbrains.annotations.VisibleForTesting;
 
 /**
  * Metric manager.
  */
-public class MetricManagerImpl implements MetricManager {
-    /** Logger. */
-    private final IgniteLogger log;
+public class MetricManagerImpl extends AbstractMetricManager {
+    // This field cannot be static, because its used by the Thin Client.
+    // However, it is expected that MetricManagerImpl will be used only on the 
server side.
+    private final IgniteLogger log = Loggers.forClass(MetricManagerImpl.class);
 
-    /** Metric registry. */
-    private final MetricRegistry registry;
+    private final String nodeName;
 
-    private final Map<String, MetricExporter> enabledMetricExporters = new 
ConcurrentHashMap<>();
-
-    private final IgniteSpinBusyLock busyLock = new IgniteSpinBusyLock();
-
-    private final AtomicBoolean stopGuard = new AtomicBoolean();
-
-    /** Metrics' exporters. */
-    private volatile Map<String, MetricExporter> availableExporters;
+    private final Supplier<UUID> clusterIdSupplier;
 
     private volatile MetricConfiguration metricConfiguration;
 
-    private volatile Supplier<UUID> clusterIdSupplier;
-
-    private volatile @Nullable String nodeName;
-
-    /**
-     * Constructor.
-     */
-    public MetricManagerImpl() {
-        this(Loggers.forClass(MetricManagerImpl.class), null);
+    /** Constructor. */
+    public MetricManagerImpl(String nodeName, Supplier<UUID> 
clusterIdSupplier) {
+        this.nodeName = nodeName;
+        this.clusterIdSupplier = clusterIdSupplier;
     }
 
-    /**
-     * Constructor.
-     *
-     * @param log Logger.
-     */
-    public MetricManagerImpl(IgniteLogger log, @Nullable String nodeName) {
-        registry = new MetricRegistry();
-        this.log = log;
+    /** Constructor for smoother testing. */
+    @TestOnly
+    public MetricManagerImpl(String nodeName, Supplier<UUID> 
clusterIdSupplier, MetricConfiguration metricConfiguration) {
         this.nodeName = nodeName;
+        this.clusterIdSupplier = clusterIdSupplier;
+        this.metricConfiguration = metricConfiguration;
     }
 
-    @Override
-    public void configure(MetricConfiguration metricConfiguration, 
Supplier<UUID> clusterIdSupplier, String nodeName) {
-        assert this.metricConfiguration == null : "Metric manager must be 
configured only once, on the start of the node";
-        assert this.clusterIdSupplier == null : "Metric manager must be 
configured only once, on the start of the node";
-        assert this.nodeName == null : "Metric manager must be configured only 
once, on the start of the node";
+    /** Sets the configuration. Needed to resolve cyclic dependencies. */
+    public void configure(MetricConfiguration metricConfiguration) {
+        assert this.metricConfiguration == null : "Metric configuration is 
already set.";
 
         this.metricConfiguration = metricConfiguration;
-        this.clusterIdSupplier = clusterIdSupplier;
-        this.nodeName = nodeName;
     }
 
     @Override
@@ -121,207 +87,44 @@ public class MetricManagerImpl implements MetricManager {
         });
     }
 
-    @Override
+    /** Starts the manager using the given exporters. */
     @VisibleForTesting
     public void start(Map<String, MetricExporter> availableExporters) {
-        this.availableExporters = Map.copyOf(availableExporters);
+        MetricConfiguration metricConfiguration = this.metricConfiguration;
 
-        MetricView conf = metricConfiguration.value();
+        assert metricConfiguration != null : "Metric configuration is not 
set.";
 
-        List<ExporterView> exporters = 
conf.exporters().stream().collect(toList());
-        exporters.addAll(defaultExporters(exporters));
+        for (ExporterView exporterConfiguration : 
metricConfiguration.value().exporters()) {
+            startAndEnableExporter(exporterConfiguration, availableExporters);
+        }
 
-        for (ExporterView exporter : exporters) {
-            checkAndStartExporter(exporter.exporterName(), exporter);
+        if 
(!enabledMetricExporters.containsKey(LogPushExporter.EXPORTER_NAME)) {
+            startAndEnableExporter(new DefaultLogPushExporterView(), 
availableExporters);
         }
 
-        metricConfiguration.exporters().listenElements(new 
ExporterConfigurationListener());
+        metricConfiguration.exporters().listenElements(new 
ExporterConfigurationListener(availableExporters));
     }
 
-    @Override
-    public void start(Iterable<MetricExporter> exporters) {
-        inBusyLock(busyLock, () -> {
-            var availableExporters = new HashMap<String, MetricExporter>();
+    private void startAndEnableExporter(ExporterView exporterConfiguration, 
Map<String, MetricExporter> availableExporters) {
+        String exporterName = exporterConfiguration.exporterName();
 
-            for (MetricExporter exporter : exporters) {
-                exporter.start(registry, null, clusterIdSupplier, nodeName);
-
-                availableExporters.put(exporter.name(), exporter);
-                enabledMetricExporters.put(exporter.name(), exporter);
-            }
+        MetricExporter exporter = availableExporters.get(exporterName);
 
-            this.availableExporters = Map.copyOf(availableExporters);
-        });
-    }
+        if (exporter == null) {
+            log.warn("Unknown metric exporter in configuration [name = {}].", 
exporterName);
 
-    @Override
-    public void beforeNodeStop() {
-        if (!stopGuard.compareAndSet(false, true)) {
             return;
         }
 
-        busyLock.block();
-
         try {
-            closeAllManually(Stream.concat(
-                    
enabledMetricExporters.values().stream().map(metricExporter -> 
(ManuallyCloseable) metricExporter::stop),
-                    Stream.of(registry)
-            ));
+            exporter.start(registry, exporterConfiguration, clusterIdSupplier, 
nodeName);
         } catch (Exception e) {
-            throw new IgniteInternalException(RESOURCE_CLOSING_ERR, e);
-        }
-    }
-
-    @Override
-    public CompletableFuture<Void> stopAsync(ComponentContext 
componentContext) {
-        enabledMetricExporters.clear();
+            log.warn("Unable to start metric exporter [name = {}].", e, 
exporterName);
 
-        return nullCompletedFuture();
-    }
-
-    @Override
-    public void registerSource(MetricSource src) {
-        inBusyLock(busyLock, () -> registry.registerSource(src));
-    }
-
-    @Override
-    public void unregisterSource(MetricSource src) {
-        inBusyLockSafe(busyLock, () -> {
-            if (metricSources().contains(src)) {
-                disable(src);
-                registry.unregisterSource(src);
-            }
-        });
-    }
-
-    @Override
-    public void unregisterSource(String srcName) {
-        inBusyLockSafe(busyLock, () -> {
-            if (metricSources().stream().anyMatch(metricSource -> 
metricSource.name().equals(srcName))) {
-                disable(srcName);
-                registry.unregisterSource(srcName);
-            }
-        });
-    }
-
-    @Override
-    public MetricSet enable(MetricSource src) {
-        return inBusyLock(busyLock, () -> {
-            MetricSet enabled = registry.enable(src);
-
-            if (enabled != null) {
-                enabledMetricExporters.values().forEach(e -> 
e.addMetricSet(enabled));
-            }
-
-            return enabled;
-        });
-    }
-
-    @Override
-    public MetricSet enable(String srcName) {
-        return inBusyLock(busyLock, () -> {
-            MetricSet enabled = registry.enable(srcName);
-
-            if (enabled != null) {
-                enabledMetricExporters.values().forEach(e -> 
e.addMetricSet(enabled));
-            }
-
-            return enabled;
-        });
-    }
-
-    @Override
-    public void disable(MetricSource src) {
-        inBusyLockSafe(busyLock, () -> {
-            MetricSet metricSet = 
registry.snapshot().metrics().get(src.name());
-
-            registry.disable(src);
-
-            enabledMetricExporters.values().forEach(e -> 
e.removeMetricSet(metricSet));
-        });
-    }
-
-    @Override
-    public void disable(String srcName) {
-        inBusyLockSafe(busyLock, () -> {
-            MetricSet metricSet = registry.snapshot().metrics().get(srcName);
-
-            registry.disable(srcName);
-
-            enabledMetricExporters.values().forEach(e -> 
e.removeMetricSet(metricSet));
-        });
-    }
-
-    @Override
-    public MetricSnapshot metricSnapshot() {
-        return inBusyLock(busyLock, registry::snapshot);
-    }
-
-    @Override
-    public Collection<MetricSource> metricSources() {
-        return inBusyLock(busyLock, registry::metricSources);
-    }
-
-    @Override
-    public Collection<MetricExporter> enabledExporters() {
-        return inBusyLock(busyLock, enabledMetricExporters::values);
-    }
-
-    private static List<ExporterView> defaultExporters(List<? extends 
ExporterView> configuredExporters) {
-        if 
(configuredExporters.stream().map(ExporterView::exporterName).anyMatch(n -> 
n.equals(LogPushExporter.EXPORTER_NAME))) {
-            return emptyList();
-        } else {
-            ExporterView logExporterView = new LogPushExporterView() {
-                private final LogPushExporterConfigurationSchema schema = new 
LogPushExporterConfigurationSchema();
-
-                @Override
-                public long periodMillis() {
-                    return schema.periodMillis;
-                }
-
-                @Override
-                public boolean oneLinePerMetricSource() {
-                    return schema.oneLinePerMetricSource;
-                }
-
-                @Override
-                public String[] enabledMetrics() {
-                    return schema.enabledMetrics;
-                }
-
-                @Override
-                public String exporterName() {
-                    return LogPushExporter.EXPORTER_NAME;
-                }
-
-                @Override
-                public String name() {
-                    return "log";
-                }
-            };
-
-            return List.of(logExporterView);
+            return;
         }
-    }
-
-    private void checkAndStartExporter(String exporterName, ExporterView 
exporterConfiguration) {
-        MetricExporter exporter = availableExporters.get(exporterName);
-
-        if (exporter != null) {
-            enabledMetricExporters.computeIfAbsent(exporter.name(), name -> {
-                try {
-                    exporter.start(registry, exporterConfiguration, 
clusterIdSupplier, nodeName);
 
-                    return exporter;
-                } catch (Exception e) {
-                    log.warn("Unable to start metrics exporter name=[" + 
exporterName + "].", e);
-
-                    return null;
-                }
-            });
-        } else {
-            log.warn("Received configuration for unknown metric exporter with 
the name '" + exporterName + "'");
-        }
+        enabledMetricExporters.put(exporterName, exporter);
     }
 
     /**
@@ -337,7 +140,42 @@ public class MetricManagerImpl implements MetricManager {
                 .collect(toUnmodifiableMap(MetricExporter::name, 
Function.identity()));
     }
 
+    private static class DefaultLogPushExporterView implements 
LogPushExporterView {
+        private final LogPushExporterConfigurationSchema schema = new 
LogPushExporterConfigurationSchema();
+
+        @Override
+        public long periodMillis() {
+            return schema.periodMillis;
+        }
+
+        @Override
+        public boolean oneLinePerMetricSource() {
+            return schema.oneLinePerMetricSource;
+        }
+
+        @Override
+        public String[] enabledMetrics() {
+            return schema.enabledMetrics;
+        }
+
+        @Override
+        public String exporterName() {
+            return LogPushExporter.EXPORTER_NAME;
+        }
+
+        @Override
+        public String name() {
+            return "log";
+        }
+    }
+
     private class ExporterConfigurationListener implements 
ConfigurationNamedListListener<ExporterView> {
+        private final Map<String, MetricExporter> availableExporters;
+
+        ExporterConfigurationListener(Map<String, MetricExporter> 
availableExporters) {
+            this.availableExporters = availableExporters;
+        }
+
         @Override
         public CompletableFuture<?> 
onCreate(ConfigurationNotificationEvent<ExporterView> ctx) {
             inBusyLockSafe(busyLock, () -> {
@@ -345,7 +183,7 @@ public class MetricManagerImpl implements MetricManager {
 
                 assert newValue != null;
 
-                checkAndStartExporter(newValue.exporterName(), newValue);
+                startAndEnableExporter(newValue, availableExporters);
             });
 
             return nullCompletedFuture();
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/MetricExporter.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/MetricExporter.java
index 915e71ceb1b..15e029a6934 100644
--- 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/MetricExporter.java
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/MetricExporter.java
@@ -19,7 +19,7 @@ package org.apache.ignite.internal.metrics.exporters;
 
 import java.util.UUID;
 import java.util.function.Supplier;
-import org.apache.ignite.internal.metrics.MetricManagerImpl;
+import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.metrics.MetricProvider;
 import org.apache.ignite.internal.metrics.MetricSet;
 import 
org.apache.ignite.internal.metrics.exporters.configuration.ExporterConfiguration;
@@ -70,8 +70,7 @@ public interface MetricExporter {
     void reconfigure(ExporterView newValue);
 
     /**
-     * {@link MetricManagerImpl} invokes this method,
-     * when new metric source was enabled.
+     * {@link MetricManager} invokes this method, when new metric source was 
enabled.
      *
      * @param metricSet Named metric set.
      */
@@ -80,8 +79,7 @@ public interface MetricExporter {
     }
 
     /**
-     * {@link MetricManagerImpl} invokes this method,
-     * when the metric source was disabled.
+     * {@link MetricManager} invokes this method, when the metric source was 
disabled.
      *
      * @param metricSet Named metric set to remove.
      */
diff --git 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricConfigurationTest.java
 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricConfigurationTest.java
index a7faf83c41a..a8695ac1149 100644
--- 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricConfigurationTest.java
+++ 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricConfigurationTest.java
@@ -21,13 +21,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
-import org.apache.ignite.internal.metrics.exporters.MetricExporter;
 import org.apache.ignite.internal.metrics.exporters.TestExporter;
 import 
org.apache.ignite.internal.metrics.exporters.configuration.TestExporterChange;
 import 
org.apache.ignite.internal.metrics.exporters.configuration.TestExporterConfigurationSchema;
@@ -48,23 +46,17 @@ public class MetricConfigurationTest extends 
BaseIgniteAbstractTest {
     )
     private MetricConfiguration metricConfiguration;
 
-    private MetricManager metricManager;
+    private MetricManagerImpl metricManager;
 
     private TestExporter exporter;
 
     @BeforeEach
     public void setUp() {
-        metricManager = new MetricManagerImpl();
-
-        Map<String, MetricExporter> availableExporters = new HashMap<>();
+        metricManager = new MetricManagerImpl("test-node", UUID::randomUUID, 
metricConfiguration);
 
         exporter  = new TestExporter();
 
-        availableExporters.put("test", exporter);
-
-        metricManager.configure(metricConfiguration, UUID::randomUUID, 
"test-node");
-
-        metricManager.start(availableExporters);
+        metricManager.start(Map.of("test", exporter));
     }
 
     @Test
diff --git 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricManagerTest.java
 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricManagerTest.java
index 49281fb3691..97b4fa8e49d 100644
--- 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricManagerTest.java
+++ 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MetricManagerTest.java
@@ -29,8 +29,6 @@ import java.util.UUID;
 import javax.management.ObjectName;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
-import org.apache.ignite.internal.logger.IgniteLogger;
-import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.manager.ComponentContext;
 import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.sources.OsMetricSource;
@@ -43,8 +41,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
  */
 @ExtendWith(ConfigurationExtension.class)
 public class MetricManagerTest extends BaseIgniteAbstractTest {
-    private static final IgniteLogger LOG = 
Loggers.forClass(MetricManagerTest.class);
-
     private static final String NODE_NAME = "test-node-name";
 
     private static final UUID NODE_ID = UUID.randomUUID();
@@ -97,9 +93,7 @@ public class MetricManagerTest extends BaseIgniteAbstractTest 
{
     }
 
     private static MetricManager createAndStartManager(MetricConfiguration 
configuration) {
-        MetricManager metricManager = new MetricManagerImpl(LOG, null);
-
-        metricManager.configure(configuration, () -> NODE_ID, NODE_NAME);
+        MetricManager metricManager = new MetricManagerImpl(NODE_NAME, () -> 
NODE_ID, configuration);
 
         assertThat(metricManager.startAsync(new ComponentContext()), 
willSucceedFast());
 
diff --git 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/PushExporterTest.java
 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/PushExporterTest.java
index fcad050610c..b5e4e3d4b82 100644
--- 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/PushExporterTest.java
+++ 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/PushExporterTest.java
@@ -23,14 +23,12 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
-import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.exporters.configuration.ExporterView;
@@ -52,23 +50,17 @@ public class PushExporterTest extends 
BaseIgniteAbstractTest {
     @InjectConfiguration(polymorphicExtensions = 
TestPushExporterConfigurationSchema.class)
     private MetricConfiguration metricConfiguration;
 
-    private MetricManager metricManager;
+    private MetricManagerImpl metricManager;
 
     private TestPushExporter exporter;
 
     @BeforeEach
     public void setUp() {
-        metricManager = new MetricManagerImpl();
+        metricManager = new MetricManagerImpl("test-node", UUID::randomUUID, 
metricConfiguration);
 
-        Map<String, MetricExporter> availableExporters = new HashMap<>();
+        exporter = new TestPushExporter();
 
-        exporter  = new TestPushExporter();
-
-        availableExporters.put(TEST_EXPORTER_NAME, exporter);
-
-        metricManager.configure(metricConfiguration, UUID::randomUUID, 
"test-node");
-
-        metricManager.start(availableExporters);
+        metricManager.start(Map.of(TEST_EXPORTER_NAME, exporter));
     }
 
     @AfterEach
diff --git 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporterTest.java
 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporterTest.java
index 2f91f3be3e6..d1abfcf37d5 100644
--- 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporterTest.java
+++ 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporterTest.java
@@ -44,7 +44,6 @@ import org.apache.ignite.internal.metrics.HitRateMetric;
 import org.apache.ignite.internal.metrics.IntGauge;
 import org.apache.ignite.internal.metrics.LongAdderMetric;
 import org.apache.ignite.internal.metrics.LongGauge;
-import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.metrics.MetricSet;
 import org.apache.ignite.internal.metrics.StringGauge;
@@ -165,14 +164,13 @@ public class LogPushExporterTest extends 
BaseIgniteAbstractTest {
                     Map.of("IgnoredMetric", new IntGauge("IgnoredMetric", "", 
() -> 1))
             );
 
-    private MetricManager metricManager;
+    private MetricManagerImpl metricManager;
 
     private LogPushExporter exporter;
 
     @BeforeEach
     void setUp() {
-        metricManager = new MetricManagerImpl();
-        metricManager.configure(metricConfiguration, () -> CLUSTER_ID, 
"nodeName");
+        metricManager = new MetricManagerImpl("nodeName", () -> CLUSTER_ID, 
metricConfiguration);
 
         // Register JVM and OS metric sources for system metrics (heap, CPU).
         metricManager.registerSource(new JvmMetricSource());
diff --git 
a/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
 
b/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
index a7869ae2b21..7c333612cb9 100644
--- 
a/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
+++ 
b/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
@@ -22,12 +22,8 @@ import static 
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFu
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
-import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
-import java.util.function.Supplier;
 import org.apache.ignite.internal.manager.ComponentContext;
-import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.exporters.MetricExporter;
 
 /**
@@ -35,23 +31,11 @@ import 
org.apache.ignite.internal.metrics.exporters.MetricExporter;
  * fulfilled.
  */
 public class NoOpMetricManager implements MetricManager {
-    @Override
-    public void configure(MetricConfiguration metricConfiguration, 
Supplier<UUID> clusterIdSupplier, String nodeName) {
-    }
-
     @Override
     public CompletableFuture<Void> startAsync(ComponentContext 
componentContext) {
         return nullCompletedFuture();
     }
 
-    @Override
-    public void start(Map<String, MetricExporter> availableExporters) {
-    }
-
-    @Override
-    public void start(Iterable<MetricExporter> exporters) {
-    }
-
     @Override
     public CompletableFuture<Void> stopAsync(ComponentContext 
componentContext) {
         return nullCompletedFuture();
diff --git 
a/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/TestMetricManager.java
 
b/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/TestMetricManager.java
index 02c5cca7c79..0f88d8b2a41 100644
--- 
a/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/TestMetricManager.java
+++ 
b/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/TestMetricManager.java
@@ -21,12 +21,8 @@ import static 
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFu
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
-import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
-import java.util.function.Supplier;
 import org.apache.ignite.internal.manager.ComponentContext;
-import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.exporters.MetricExporter;
 import org.jetbrains.annotations.Nullable;
 
@@ -44,21 +40,6 @@ public class TestMetricManager implements MetricManager {
         return nullCompletedFuture();
     }
 
-    @Override
-    public void configure(MetricConfiguration metricConfiguration, 
Supplier<UUID> clusterIdSupplier, String nodeName) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void start(Map<String, MetricExporter> availableExporters) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void start(Iterable<MetricExporter> exporters) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public void registerSource(MetricSource src) {
         registry.registerSource(src);
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java
index 13fb6a904e3..2c75521e15a 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java
@@ -155,6 +155,7 @@ import 
org.apache.ignite.internal.metastorage.server.persistence.RocksDbKeyValue
 import org.apache.ignite.internal.metastorage.server.raft.MetastorageGroupId;
 import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.metrics.NoOpMetricManager;
+import 
org.apache.ignite.internal.metrics.configuration.MetricExtensionConfiguration;
 import org.apache.ignite.internal.network.MessagingService;
 import org.apache.ignite.internal.network.NettyBootstrapFactory;
 import org.apache.ignite.internal.network.NettyWorkersRegistrar;
@@ -382,7 +383,7 @@ public class ItIgniteNodeRestartTest extends 
BaseIgniteRestartTest {
         NetworkConfiguration networkConfiguration = nodeConfigRegistry
                 .getConfiguration(NetworkExtensionConfiguration.KEY).network();
 
-        var metricManager = new MetricManagerImpl();
+        var metricManager = new MetricManagerImpl(name, 
clusterIdService::clusterId);
 
         var threadPoolsManager = new ThreadPoolsManager(name, metricManager);
 
@@ -555,6 +556,8 @@ public class ItIgniteNodeRestartTest extends 
BaseIgniteRestartTest {
                 
ConfigurationValidatorImpl.withDefaultValidators(distributedConfigurationGenerator,
 modules.distributed().validators())
         );
 
+        
metricManager.configure(clusterConfigRegistry.getConfiguration(MetricExtensionConfiguration.KEY).metrics());
+
         var resourcesRegistry = new RemotelyTriggeredResourceRegistry();
 
         GcConfiguration gcConfig = 
clusterConfigRegistry.getConfiguration(GcExtensionConfiguration.KEY).gc();
diff --git 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
index c8583b0b0a7..11634c5a272 100644
--- 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
+++ 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
@@ -437,7 +437,7 @@ public class IgniteImpl implements Ignite {
     private final SchemaManager schemaManager;
 
     /** Metric manager. */
-    private final MetricManager metricManager;
+    private final MetricManagerImpl metricManager;
 
     /** Metric messaging. */
     private final MetricMessaging metricMessaging;
@@ -555,7 +555,7 @@ public class IgniteImpl implements Ignite {
 
         lifecycleManager = new LifecycleManager(name);
 
-        metricManager = new MetricManagerImpl();
+        metricManager = new MetricManagerImpl(name, () -> 
clusterState().clusterTag().clusterId());
 
         threadPoolsManager = new ThreadPoolsManager(name, metricManager);
 
@@ -815,6 +815,8 @@ public class IgniteImpl implements Ignite {
                 
KeyIgnorer.fromDeletedPrefixes(modules.local().deletedPrefixes())
         );
 
+        
metricManager.configure(clusterConfigRegistry.getConfiguration(MetricExtensionConfiguration.KEY).metrics());
+
         eventLog = new EventLogImpl(
                 
clusterConfigRegistry.getConfiguration(EventLogExtensionConfiguration.KEY).eventlog(),
                 () -> clusterState().clusterTag().clusterId(),
@@ -964,12 +966,6 @@ public class IgniteImpl implements Ignite {
                 threadPoolsManager.commonScheduler()
         );
 
-        metricManager.configure(
-                
clusterConfigRegistry.getConfiguration(MetricExtensionConfiguration.KEY).metrics(),
-                () -> clusterState().clusterTag().clusterId(),
-                name
-        );
-
         DataStorageModules dataStorageModules = new DataStorageModules(
                 ServiceLoader.load(DataStorageModule.class, 
serviceProviderClassLoader)
         );
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PlannerTimeoutTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PlannerTimeoutTest.java
index 14d657de343..676b1febd16 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PlannerTimeoutTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PlannerTimeoutTest.java
@@ -41,7 +41,7 @@ import org.apache.calcite.rel.RelVisitor;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import org.apache.ignite.internal.event.AbstractEventProducer;
-import org.apache.ignite.internal.metrics.MetricManagerImpl;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import 
org.apache.ignite.internal.sql.configuration.distributed.StatisticsConfiguration;
 import org.apache.ignite.internal.sql.engine.SqlOperationContext;
 import org.apache.ignite.internal.sql.engine.framework.PredefinedSchemaManager;
@@ -90,7 +90,7 @@ public class PlannerTimeoutTest extends AbstractPlannerTest {
                 plannerTimeout,
                 1,
                 Integer.MAX_VALUE,
-                new MetricManagerImpl(),
+                new NoOpMetricManager(),
                 new PredefinedSchemaManager(schema),
                 mock(LongSupplier.class),
                 mock(ScheduledExecutorService.class),
@@ -194,4 +194,3 @@ public class PlannerTimeoutTest extends AbstractPlannerTest 
{
         return spyTable;
     }
 }
-
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/PrepareServiceImplTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/PrepareServiceImplTest.java
index 56c7e6184bb..84178f81493 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/PrepareServiceImplTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/PrepareServiceImplTest.java
@@ -71,7 +71,7 @@ import org.apache.ignite.internal.hlc.ClockService;
 import org.apache.ignite.internal.hlc.ClockServiceImpl;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.HybridTimestamp;
-import org.apache.ignite.internal.metrics.MetricManagerImpl;
+import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.sql.SqlCommon;
 import 
org.apache.ignite.internal.sql.configuration.distributed.StatisticsConfiguration;
 import org.apache.ignite.internal.sql.engine.QueryCancel;
@@ -902,7 +902,7 @@ public class PrepareServiceImplTest extends 
BaseIgniteAbstractTest {
         AbstractEventProducer<StatisticChangedEvent, StatisticEventParameters> 
producer = new AbstractEventProducer<>() {};
 
         PrepareServiceImpl service = new PrepareServiceImpl("test", cacheSize, 
cacheFactory,
-                mock(DdlSqlToCommandConverter.class), timeoutMillis, 2, 
planExpireSeconds, mock(MetricManagerImpl.class),
+                mock(DdlSqlToCommandConverter.class), timeoutMillis, 2, 
planExpireSeconds, mock(MetricManager.class),
                 new PredefinedSchemaManager(schemas), 
clockService::currentLong, commonExecutor, producer,
                 
statisticsConfiguration.autoRefresh().staleRowsCheckIntervalSeconds()
         );
@@ -941,7 +941,7 @@ public class PrepareServiceImplTest extends 
BaseIgniteAbstractTest {
         AbstractEventProducer<StatisticChangedEvent, StatisticEventParameters> 
producer = new AbstractEventProducer<>() {};
 
         PrepareServiceImpl service = new PrepareServiceImpl("test", cacheSize, 
cacheFactory,
-                mock(DdlSqlToCommandConverter.class), timeoutMillis, 2, 
planExpireSeconds, mock(MetricManagerImpl.class),
+                mock(DdlSqlToCommandConverter.class), timeoutMillis, 2, 
planExpireSeconds, mock(MetricManager.class),
                 new VersionedSchemaManager(schemas, ver), 
clockService::currentLong, executor, producer,
                 
statisticsConfiguration.autoRefresh().staleRowsCheckIntervalSeconds()
         );
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/metrics/PlanningCacheMetricsTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/metrics/PlanningCacheMetricsTest.java
index 7e5291892e1..629bc6f645e 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/metrics/PlanningCacheMetricsTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/metrics/PlanningCacheMetricsTest.java
@@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.UUID;
 import java.util.concurrent.ScheduledExecutorService;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
@@ -63,7 +64,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
 @ExtendWith(ConfigurationExtension.class)
 public class PlanningCacheMetricsTest extends AbstractPlannerTest {
 
-    private final MetricManager metricManager = new MetricManagerImpl();
+    private final MetricManager metricManager = new MetricManagerImpl("test", 
UUID::randomUUID);
 
     @Mock(strictness = Strictness.LENIENT)
     private ScheduledExecutorService commonExecutor;

Reply via email to