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

vpyatkov 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 b02882dd7a IGNITE-21908 Add metrics of distribution among stripes in 
disruptor (#3645)
b02882dd7a is described below

commit b02882dd7a11c0b73bcd02980716c382f497f14d
Author: Vladislav Pyatkov <[email protected]>
AuthorDate: Tue Apr 30 17:58:35 2024 +0300

    IGNITE-21908 Add metrics of distribution among stripes in disruptor (#3645)
---
 .../apache/ignite/client/handler/TestServer.java   |   4 +-
 .../ignite/internal/client/TcpIgniteClient.java    |   3 +-
 .../java/org/apache/ignite/client/TestServer.java  |   4 +-
 modules/cluster-management/build.gradle            |   2 +
 .../management/raft/ItCmgRaftServiceTest.java      |   3 +-
 .../internal/cluster/management/MockNode.java      |   3 +-
 modules/metastorage/build.gradle                   |   2 +
 .../impl/ItMetaStorageManagerImplTest.java         |   4 +-
 .../ItMetaStorageMultipleNodesAbstractTest.java    |   2 +
 .../metastorage/impl/ItMetaStorageServiceTest.java |   2 +
 .../metastorage/impl/ItMetaStorageWatchTest.java   |   2 +
 modules/metrics/build.gradle                       |   3 +
 .../metrics/exporters/ItJvmMetricSourceTest.java   |   3 +-
 .../exporters/ItMetricExportersLoadingTest.java    |   3 +-
 .../apache/ignite/internal/metrics/LongGauge.java  |   2 +-
 .../ignite/internal/metrics/MetricManager.java     | 213 ++-------------------
 .../{MetricManager.java => MetricManagerImpl.java} | 121 ++++--------
 .../internal/metrics/SimpleMovingAverage.java      |  80 ++++++++
 .../configuration/MetricConfigurationModule.java   |   3 +-
 .../internal/metrics/exporters/MetricExporter.java |   5 +-
 .../LogPushExporterConfigurationSchema.java}       |  34 +---
 .../metrics/exporters/jmx/MetricSetMbean.java      |   4 +-
 .../metrics/exporters/log/LogPushExporter.java     |  90 +++++++++
 .../internal/metrics/sources/JvmMetricSource.java  |  27 ++-
 .../internal/metrics/MetricConfigurationTest.java  |   2 +-
 .../ignite/internal/metrics/MovingAverageTest.java |  90 +++++++++
 .../ignite/internal/metrics/NoOpMetricManager.java |  96 ++++++++++
 modules/placement-driver/build.gradle              |   2 +
 .../MultiActorPlacementDriverTest.java             |   2 +
 .../PlacementDriverManagerTest.java                |   2 +
 modules/raft/build.gradle                          |   3 +
 .../ignite/internal/raft/ItLearnersTest.java       |   3 +-
 .../apache/ignite/internal/raft/ItLozaTest.java    |   3 +-
 .../internal/raft/ItRaftGroupServiceTest.java      |   9 +-
 .../raft/ItTruncateSuffixAndRestartTest.java       |   3 +-
 .../internal/metrics/sources/RaftMetricSource.java | 178 +++++++++++++++++
 .../java/org/apache/ignite/internal/raft/Loza.java |  15 ++
 .../internal/raft/server/impl/JraftServerImpl.java |  17 +-
 .../apache/ignite/raft/jraft/core/NodeImpl.java    |  23 ++-
 .../raft/jraft/disruptor/StripedDisruptor.java     |  31 ++-
 .../ignite/raft/jraft/option/NodeOptions.java      |  16 ++
 .../ignite/disruptor/StripedDisruptorTest.java     |   6 +-
 .../org/apache/ignite/internal/raft/LozaTest.java  |   3 +-
 .../ignite/raft/jraft/core/FSMCallerTest.java      |  11 +-
 .../raft/jraft/core/ReadOnlyServiceTest.java       |  11 +-
 .../raft/jraft/storage/impl/LogManagerTest.java    |  11 +-
 modules/replicator/build.gradle                    |   2 +
 .../ItPlacementDriverReplicaSideTest.java          |   2 +
 modules/runner/build.gradle                        |   1 +
 .../ItDistributedConfigurationPropertiesTest.java  |   9 +-
 .../ItDistributedConfigurationStorageTest.java     |  10 +-
 .../runner/app/ItIgniteNodeRestartTest.java        |   7 +-
 .../ItRaftCommandLeftInLogUntilRestartTest.java    |   3 +-
 .../org/apache/ignite/internal/app/IgniteImpl.java |   9 +-
 .../sql/engine/exec/ExecutionServiceImplTest.java  |  13 +-
 .../sql/engine/framework/TestBuilders.java         |   4 +-
 .../sql/engine/planner/PlannerTimeoutTest.java     |   4 +-
 .../sql/engine/prepare/PrepareServiceImplTest.java |   4 +-
 .../sql/metrics/PlanningCacheMetricsTest.java      |   3 +-
 modules/table/build.gradle                         |   3 +
 .../ReplicasSafeTimePropagationTest.java           |   2 +
 .../rebalance/ItRebalanceDistributedTest.java      |  10 +-
 .../apache/ignite/distributed/ItTxTestCluster.java |   2 +
 63 files changed, 857 insertions(+), 387 deletions(-)

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 a43be8b487..50551ccfbf 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
@@ -31,7 +31,7 @@ import 
org.apache.ignite.internal.compute.IgniteComputeInternal;
 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.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NettyBootstrapFactory;
 import org.apache.ignite.internal.network.configuration.NetworkConfiguration;
@@ -124,7 +124,7 @@ public class TestServer {
                 clusterService,
                 bootstrapFactory,
                 () -> 
CompletableFuture.completedFuture(ClusterTag.clusterTag(msgFactory, "Test 
Server")),
-                mock(MetricManager.class),
+                mock(MetricManagerImpl.class),
                 metrics,
                 authenticationManager,
                 new TestClockService(new HybridClockImpl()),
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 4046840a25..591c83fcbc 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
@@ -37,6 +37,7 @@ import 
org.apache.ignite.internal.client.tx.ClientTransactions;
 import org.apache.ignite.internal.jdbc.proto.ClientMessage;
 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.lang.ErrorGroups;
 import org.apache.ignite.network.ClusterNode;
@@ -119,7 +120,7 @@ public class TcpIgniteClient implements IgniteClient {
             return null;
         }
 
-        var metricManager = new MetricManager(ClientUtils.logger(cfg, 
MetricManager.class));
+        var metricManager = new MetricManagerImpl(ClientUtils.logger(cfg, 
MetricManagerImpl.class));
         metricManager.start(List.of(new JmxExporter(ClientUtils.logger(cfg, 
JmxExporter.class))));
 
         metricManager.registerSource(metrics);
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 095ecfd3a1..8a8f049285 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
@@ -59,7 +59,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.IgniteComponent;
-import org.apache.ignite.internal.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NettyBootstrapFactory;
 import org.apache.ignite.internal.network.configuration.NetworkConfiguration;
@@ -243,7 +243,7 @@ public class TestServer implements AutoCloseable {
                         clusterService,
                         bootstrapFactory,
                         () -> CompletableFuture.completedFuture(tag),
-                        mock(MetricManager.class),
+                        mock(MetricManagerImpl.class),
                         metrics,
                         authenticationManager,
                         new TestClockService(clock),
diff --git a/modules/cluster-management/build.gradle 
b/modules/cluster-management/build.gradle
index 809b2f21e0..8987125ea3 100644
--- a/modules/cluster-management/build.gradle
+++ b/modules/cluster-management/build.gradle
@@ -61,6 +61,7 @@ dependencies {
     testFixturesImplementation testFixtures(project(':ignite-core'))
     testFixturesImplementation testFixtures(project(':ignite-configuration'))
     testFixturesImplementation testFixtures(project(':ignite-network'))
+    testFixturesImplementation testFixtures(project(':ignite-metrics'))
     testFixturesImplementation libs.jetbrains.annotations
 
     integrationTestAnnotationProcessor 
libs.micronaut.inject.annotation.processor
@@ -73,6 +74,7 @@ dependencies {
     integrationTestImplementation 
testFixtures(project(':ignite-configuration'))
     integrationTestImplementation testFixtures(project(':ignite-network'))
     integrationTestImplementation testFixtures(project(':ignite-runner'))
+    integrationTestImplementation testFixtures(project(':ignite-metrics:'))
     integrationTestImplementation libs.awaitility
     integrationTestImplementation libs.jetbrains.annotations
 }
diff --git 
a/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/raft/ItCmgRaftServiceTest.java
 
b/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/raft/ItCmgRaftServiceTest.java
index 0ebb827d2c..74d4a7a81f 100644
--- 
a/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/raft/ItCmgRaftServiceTest.java
+++ 
b/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/raft/ItCmgRaftServiceTest.java
@@ -56,6 +56,7 @@ import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguratio
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.lang.NodeStoppingException;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NodeFinder;
 import org.apache.ignite.internal.network.StaticNodeFinder;
@@ -104,7 +105,7 @@ public class ItCmgRaftServiceTest extends 
BaseIgniteAbstractTest {
 
         Node(TestInfo testInfo, NetworkAddress addr, NodeFinder nodeFinder, 
Path workDir) {
             this.clusterService = clusterService(testInfo, addr.port(), 
nodeFinder);
-            this.raftManager = new Loza(clusterService, raftConfiguration, 
workDir, new HybridClockImpl());
+            this.raftManager = new Loza(clusterService, new 
NoOpMetricManager(), raftConfiguration, workDir, new HybridClockImpl());
             this.logicalTopology = new LogicalTopologyImpl(raftStorage);
         }
 
diff --git 
a/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/MockNode.java
 
b/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/MockNode.java
index cf88e75384..300cb122db 100644
--- 
a/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/MockNode.java
+++ 
b/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/MockNode.java
@@ -39,6 +39,7 @@ import 
org.apache.ignite.internal.cluster.management.topology.api.LogicalTopolog
 import 
org.apache.ignite.internal.configuration.validation.TestConfigurationValidator;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.manager.IgniteComponent;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NodeFinder;
 import org.apache.ignite.internal.network.utils.ClusterServiceTestUtils;
@@ -112,7 +113,7 @@ public class MockNode {
 
         this.clusterService = ClusterServiceTestUtils.clusterService(testInfo, 
port, nodeFinder);
 
-        Loza raftManager = new Loza(clusterService, raftConfiguration, 
workDir, new HybridClockImpl());
+        Loza raftManager = new Loza(clusterService, new NoOpMetricManager(), 
raftConfiguration, workDir, new HybridClockImpl());
 
         var clusterStateStorage = new 
RocksDbClusterStateStorage(workDir.resolve("cmg"), clusterService.nodeName());
 
diff --git a/modules/metastorage/build.gradle b/modules/metastorage/build.gradle
index c23d1ba6b1..6f3408384c 100644
--- a/modules/metastorage/build.gradle
+++ b/modules/metastorage/build.gradle
@@ -58,6 +58,7 @@ dependencies {
     integrationTestImplementation project(':ignite-storage-rocksdb')
     integrationTestImplementation project(":ignite-vault")
     integrationTestImplementation project(":ignite-security")
+    integrationTestImplementation project(':ignite-metrics')
     integrationTestImplementation testFixtures(project(':ignite-core'))
     integrationTestImplementation testFixtures(project(':ignite-network'))
     integrationTestImplementation testFixtures(project(':ignite-raft'))
@@ -66,6 +67,7 @@ dependencies {
     integrationTestImplementation testFixtures(project(':ignite-metastorage'))
     integrationTestImplementation 
testFixtures(project(':ignite-cluster-management'))
     integrationTestImplementation 
testFixtures(project(':ignite-failure-handler'))
+    integrationTestImplementation testFixtures(project(':ignite-metrics:'))
 
     testFixturesImplementation project(':ignite-cluster-management')
     testFixturesImplementation project(':ignite-core')
diff --git 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageManagerImplTest.java
 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageManagerImplTest.java
index 74b47c130b..80838e5942 100644
--- 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageManagerImplTest.java
+++ 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageManagerImplTest.java
@@ -68,6 +68,7 @@ import org.apache.ignite.internal.metastorage.dsl.Operations;
 import org.apache.ignite.internal.metastorage.server.KeyValueStorage;
 import 
org.apache.ignite.internal.metastorage.server.persistence.RocksDbKeyValueStorage;
 import org.apache.ignite.internal.metastorage.server.time.ClusterTime;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
 import org.apache.ignite.internal.raft.Loza;
@@ -110,7 +111,8 @@ public class ItMetaStorageManagerImplTest extends 
IgniteAbstractTest {
 
         var raftGroupEventsClientListener = new 
RaftGroupEventsClientListener();
 
-        raftManager = new Loza(clusterService, raftConfiguration, 
workDir.resolve("loza"), clock, raftGroupEventsClientListener);
+        raftManager = new Loza(clusterService, new NoOpMetricManager(), 
raftConfiguration, workDir.resolve("loza"), clock,
+                raftGroupEventsClientListener);
 
         var logicalTopologyService = mock(LogicalTopologyService.class);
 
diff --git 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesAbstractTest.java
 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesAbstractTest.java
index e93e9d2c07..cf84819fe8 100644
--- 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesAbstractTest.java
+++ 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesAbstractTest.java
@@ -72,6 +72,7 @@ import 
org.apache.ignite.internal.metastorage.configuration.MetaStorageConfigura
 import org.apache.ignite.internal.metastorage.server.KeyValueStorage;
 import org.apache.ignite.internal.metastorage.server.time.ClusterTime;
 import org.apache.ignite.internal.metastorage.server.time.ClusterTimeImpl;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
 import org.apache.ignite.internal.network.utils.ClusterServiceTestUtils;
@@ -150,6 +151,7 @@ public abstract class 
ItMetaStorageMultipleNodesAbstractTest extends IgniteAbstr
 
             this.raftManager = new Loza(
                     clusterService,
+                    new NoOpMetricManager(),
                     raftConfiguration,
                     basePath.resolve("raft"),
                     clock,
diff --git 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageServiceTest.java
 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageServiceTest.java
index ecdaf478c9..1caa134172 100644
--- 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageServiceTest.java
+++ 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageServiceTest.java
@@ -95,6 +95,7 @@ import 
org.apache.ignite.internal.metastorage.server.ValueCondition.Type;
 import org.apache.ignite.internal.metastorage.server.raft.MetaStorageListener;
 import org.apache.ignite.internal.metastorage.server.raft.MetastorageGroupId;
 import org.apache.ignite.internal.metastorage.server.time.ClusterTimeImpl;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
 import org.apache.ignite.internal.network.utils.ClusterServiceTestUtils;
@@ -192,6 +193,7 @@ public class ItMetaStorageServiceTest extends 
BaseIgniteAbstractTest {
 
             this.raftManager = new Loza(
                     clusterService,
+                    new NoOpMetricManager(),
                     raftConfiguration,
                     dataPath.resolve(name()),
                     clock
diff --git 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageWatchTest.java
 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageWatchTest.java
index d7c7306e1d..dca14a1fd7 100644
--- 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageWatchTest.java
+++ 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageWatchTest.java
@@ -74,6 +74,7 @@ import 
org.apache.ignite.internal.metastorage.configuration.MetaStorageConfigura
 import org.apache.ignite.internal.metastorage.dsl.Conditions;
 import org.apache.ignite.internal.metastorage.dsl.Operations;
 import 
org.apache.ignite.internal.metastorage.server.persistence.RocksDbKeyValueStorage;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
 import org.apache.ignite.internal.network.utils.ClusterServiceTestUtils;
@@ -134,6 +135,7 @@ public class ItMetaStorageWatchTest extends 
IgniteAbstractTest {
 
             var raftManager = new Loza(
                     clusterService,
+                    new NoOpMetricManager(),
                     raftConfiguration,
                     basePath.resolve("raft"),
                     clock,
diff --git a/modules/metrics/build.gradle b/modules/metrics/build.gradle
index a609f8a095..d7eae38715 100644
--- a/modules/metrics/build.gradle
+++ b/modules/metrics/build.gradle
@@ -19,6 +19,7 @@ apply from: "$rootDir/buildscripts/java-core.gradle"
 apply from: "$rootDir/buildscripts/publishing.gradle"
 apply from: "$rootDir/buildscripts/java-junit5.gradle"
 apply from: "$rootDir/buildscripts/java-integration-test.gradle"
+apply from: "$rootDir/buildscripts/java-test-fixtures.gradle"
 
 dependencies {
     annotationProcessor project(":ignite-configuration-annotation-processor")
@@ -45,6 +46,8 @@ dependencies {
     integrationTestImplementation testFixtures(project(':ignite-core'))
     integrationTestImplementation 
testFixtures(project(':ignite-configuration'))
     integrationTestImplementation libs.auto.service.annotations
+
+    testFixturesImplementation project(':ignite-core')
 }
 
 description = 'ignite-metrics'
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 74609b9f2c..d0ce7704bb 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
@@ -27,6 +27,7 @@ import java.util.Map;
 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.sources.JvmMetricSource;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
@@ -50,7 +51,7 @@ public class ItJvmMetricSourceTest extends 
BaseIgniteAbstractTest {
 
     @Test
     public void testMemoryUsageMetric() {
-        MetricManager metricManager = new MetricManager();
+        MetricManager metricManager = new MetricManagerImpl();
 
         metricManager.configure(simpleConfiguration);
 
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 798460d6a1..ca2410b242 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
@@ -28,6 +28,7 @@ import java.util.concurrent.locks.LockSupport;
 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.testframework.BaseIgniteAbstractTest;
 import org.junit.jupiter.api.Test;
@@ -52,7 +53,7 @@ public class ItMetricExportersLoadingTest extends 
BaseIgniteAbstractTest {
 
     @Test
     public void test() throws Exception {
-        MetricManager metricManager = new MetricManager();
+        MetricManager metricManager = new MetricManagerImpl();
 
         metricManager.configure(metricConfiguration);
 
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/LongGauge.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/LongGauge.java
index 5f8db421f6..e3b2430e35 100644
--- 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/LongGauge.java
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/LongGauge.java
@@ -28,7 +28,7 @@ public class LongGauge extends AbstractMetric implements 
LongMetric {
     private final LongSupplier val;
 
     /**
-     * Constructor.
+     * The constructor.
      *
      * @param name Name.
      * @param desc Description.
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 ba5082da17..af8905b57b 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
@@ -17,67 +17,19 @@
 
 package org.apache.ignite.internal.metrics;
 
-import static 
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
-
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.ServiceLoader.Provider;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import 
org.apache.ignite.configuration.notifications.ConfigurationNamedListListener;
-import 
org.apache.ignite.configuration.notifications.ConfigurationNotificationEvent;
 import org.apache.ignite.internal.lang.IgniteBiTuple;
-import org.apache.ignite.internal.logger.IgniteLogger;
-import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.manager.IgniteComponent;
 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.jetbrains.annotations.VisibleForTesting;
 
-
 /**
- * Metric manager.
+ * The component services of the metrics. It has functions to switch on / off 
and register them.
  */
-public class MetricManager implements IgniteComponent {
-    /** Logger. */
-    private final IgniteLogger log;
-
-    /** Metric registry. */
-    private final MetricRegistry registry;
-
-    private final MetricProvider metricsProvider;
-
-    private final Map<String, MetricExporter> enabledMetricExporters = new 
ConcurrentHashMap<>();
-
-    /** Metrics' exporters. */
-    private Map<String, MetricExporter> availableExporters;
-
-    private MetricConfiguration metricConfiguration;
-
-    /**
-     * Constructor.
-     */
-    public MetricManager() {
-        this(Loggers.forClass(MetricManager.class));
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param log Logger.
-     */
-    public MetricManager(IgniteLogger log) {
-        registry = new MetricRegistry();
-        metricsProvider = new MetricProvider(registry);
-        this.log = log;
-    }
-
+public interface MetricManager extends IgniteComponent {
     /**
      * Method to configure {@link MetricManager} with distributed 
configuration.
      *
@@ -85,18 +37,10 @@ public class MetricManager implements IgniteComponent {
      */
     // 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.
-    public void configure(MetricConfiguration metricConfiguration) {
-        assert this.metricConfiguration == null : "Metric manager must be 
configured only once, on the start of the node";
+    void configure(MetricConfiguration metricConfiguration);
 
-        this.metricConfiguration = metricConfiguration;
-    }
-
-    /** {@inheritDoc} */
-    @Override public CompletableFuture<Void> startAsync() {
-        start(loadExporters());
-
-        return nullCompletedFuture();
-    }
+    @Override
+    CompletableFuture<Void> startAsync();
 
     /**
      * Start component.
@@ -104,71 +48,38 @@ public class MetricManager implements IgniteComponent {
      * @param availableExporters Map of (name, exporter) with available 
exporters.
      */
     @VisibleForTesting
-    public void start(Map<String, MetricExporter> availableExporters) {
-        this.availableExporters = availableExporters;
-
-        MetricView conf = metricConfiguration.value();
-
-        for (ExporterView exporter : conf.exporters()) {
-            checkAndStartExporter(exporter.exporterName(), exporter);
-        }
-
-        metricConfiguration.exporters().listenElements(new 
ExporterConfigurationListener());
-    }
+    void start(Map<String, MetricExporter> availableExporters);
 
     /**
      * Starts component with default configuration.
      *
      * @param exporters Exporters.
      */
-    public void start(Iterable<MetricExporter<?>> exporters) {
-        this.availableExporters = new HashMap<>();
-
-        for (MetricExporter<?> exporter : exporters) {
-            exporter.start(metricsProvider, null);
-
-            availableExporters.put(exporter.name(), exporter);
-            enabledMetricExporters.put(exporter.name(), exporter);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public CompletableFuture<Void> stopAsync() {
-        for (MetricExporter metricExporter : enabledMetricExporters.values()) {
-            metricExporter.stop();
-        }
+    void start(Iterable<MetricExporter<?>> exporters);
 
-        enabledMetricExporters.clear();
-
-        return nullCompletedFuture();
-    }
+    @Override
+    CompletableFuture<Void> stopAsync();
 
     /**
      * Register metric source. See {@link 
MetricRegistry#registerSource(MetricSource)}.
      *
      * @param src Metric source.
      */
-    public void registerSource(MetricSource src) {
-        registry.registerSource(src);
-    }
+    void registerSource(MetricSource src);
 
     /**
      * Unregister metric source. See {@link 
MetricRegistry#unregisterSource(MetricSource)}.
      *
      * @param src Metric source.
      */
-    public void unregisterSource(MetricSource src) {
-        registry.unregisterSource(src);
-    }
+    void unregisterSource(MetricSource src);
 
     /**
      * Unregister metric source by name. See {@link 
MetricRegistry#unregisterSource(String)}.
      *
      * @param srcName Metric source name.
      */
-    public void unregisterSource(String srcName) {
-        registry.unregisterSource(srcName);
-    }
+    void unregisterSource(String srcName);
 
     /**
      * Enable metric source. See {@link MetricRegistry#enable(MetricSource)}.
@@ -176,15 +87,7 @@ public class MetricManager implements IgniteComponent {
      * @param src Metric source.
      * @return Metric set, or {@code null} if already enabled.
      */
-    public MetricSet enable(MetricSource src) {
-        MetricSet enabled = registry.enable(src);
-
-        if (enabled != null) {
-            enabledMetricExporters.values().forEach(e -> 
e.addMetricSet(enabled));
-        }
-
-        return enabled;
-    }
+    MetricSet enable(MetricSource src);
 
     /**
      * Enable metric source by name. See {@link MetricRegistry#enable(String)}.
@@ -192,52 +95,21 @@ public class MetricManager implements IgniteComponent {
      * @param srcName Source name.
      * @return Metric set, or {@code null} if already enabled.
      */
-    public MetricSet enable(final String srcName) {
-        MetricSet enabled = registry.enable(srcName);
-
-        if (enabled != null) {
-            enabledMetricExporters.values().forEach(e -> 
e.addMetricSet(enabled));
-        }
-
-        return enabled;
-    }
-
-    /**
-     * Load exporters by {@link ServiceLoader} mechanism.
-     *
-     * @return list of loaded exporters.
-     */
-    public static Map<String, MetricExporter> loadExporters() {
-        var clsLdr = Thread.currentThread().getContextClassLoader();
-
-        return ServiceLoader
-                .load(MetricExporter.class, clsLdr)
-                .stream()
-                .map(Provider::get)
-                .collect(Collectors.toMap(e -> e.name(), Function.identity()));
-    }
+    MetricSet enable(String srcName);
 
     /**
      * Disable metric source. See {@link MetricRegistry#disable(MetricSource)}.
      *
      * @param src Metric source.
      */
-    public void disable(MetricSource src) {
-        registry.disable(src);
-
-        enabledMetricExporters.values().forEach(e -> 
e.removeMetricSet(src.name()));
-    }
+    void disable(MetricSource src);
 
     /**
      * Disable metric source by name. See {@link 
MetricRegistry#disable(String)}.
      *
      * @param srcName Metric source name.
      */
-    public void disable(final String srcName) {
-        registry.disable(srcName);
-
-        enabledMetricExporters.values().forEach(e -> 
e.removeMetricSet(srcName));
-    }
+    void disable(String srcName);
 
     /**
      * Metrics snapshot. This is a snapshot of metric sets with corresponding 
version, the values of the metrics in the
@@ -245,61 +117,12 @@ public class MetricManager implements IgniteComponent {
      *
      * @return Metrics snapshot.
      */
-    public IgniteBiTuple<Map<String, MetricSet>, Long> metricSnapshot() {
-        return registry.metricSnapshot();
-    }
+    IgniteBiTuple<Map<String, MetricSet>, Long> metricSnapshot();
 
     /**
      * Gets a collection of metric sources.
      *
      * @return collection of metric sources
      */
-    public Collection<MetricSource> metricSources() {
-        return registry.metricSources();
-    }
-
-    private <T extends ExporterView> void checkAndStartExporter(
-            String exporterName,
-            T exporterConfiguration) {
-        MetricExporter<T> exporter = availableExporters.get(exporterName);
-
-        if (exporter != null) {
-            exporter.start(metricsProvider, exporterConfiguration);
-
-            enabledMetricExporters.put(exporter.name(), exporter);
-        } else {
-            log.warn("Received configuration for unknown metric exporter with 
the name '" + exporterName + "'");
-        }
-    }
-
-    private class ExporterConfigurationListener implements 
ConfigurationNamedListListener<ExporterView> {
-        @Override
-        public CompletableFuture<?> 
onCreate(ConfigurationNotificationEvent<ExporterView> ctx) {
-            checkAndStartExporter(ctx.newValue().exporterName(), 
ctx.newValue());
-
-            return nullCompletedFuture();
-        }
-
-        @Override
-        public CompletableFuture<?> 
onDelete(ConfigurationNotificationEvent<ExporterView> ctx) {
-            var removed = 
enabledMetricExporters.remove(ctx.oldValue().exporterName());
-
-            if (removed != null) {
-                removed.stop();
-            }
-
-            return nullCompletedFuture();
-        }
-
-        @Override
-        public CompletableFuture<?> 
onUpdate(ConfigurationNotificationEvent<ExporterView> ctx) {
-            MetricExporter exporter = 
enabledMetricExporters.get(ctx.newValue().exporterName());
-
-            if (exporter != null) {
-                exporter.reconfigure(ctx.newValue());
-            }
-
-            return nullCompletedFuture();
-        }
-    }
+    Collection<MetricSource> metricSources();
 }
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/MetricManagerImpl.java
similarity index 75%
copy from 
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManager.java
copy to 
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/MetricManagerImpl.java
index ba5082da17..4123070596 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/MetricManagerImpl.java
@@ -33,7 +33,6 @@ import 
org.apache.ignite.configuration.notifications.ConfigurationNotificationEv
 import org.apache.ignite.internal.lang.IgniteBiTuple;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
-import org.apache.ignite.internal.manager.IgniteComponent;
 import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.configuration.MetricView;
 import org.apache.ignite.internal.metrics.exporters.MetricExporter;
@@ -44,7 +43,7 @@ import org.jetbrains.annotations.VisibleForTesting;
 /**
  * Metric manager.
  */
-public class MetricManager implements IgniteComponent {
+public class MetricManagerImpl implements MetricManager {
     /** Logger. */
     private final IgniteLogger log;
 
@@ -63,8 +62,8 @@ public class MetricManager implements IgniteComponent {
     /**
      * Constructor.
      */
-    public MetricManager() {
-        this(Loggers.forClass(MetricManager.class));
+    public MetricManagerImpl() {
+        this(Loggers.forClass(MetricManagerImpl.class));
     }
 
     /**
@@ -72,37 +71,27 @@ public class MetricManager implements IgniteComponent {
      *
      * @param log Logger.
      */
-    public MetricManager(IgniteLogger log) {
+    public MetricManagerImpl(IgniteLogger log) {
         registry = new MetricRegistry();
         metricsProvider = new MetricProvider(registry);
         this.log = log;
     }
 
-    /**
-     * Method to configure {@link MetricManager} with distributed 
configuration.
-     *
-     * @param metricConfiguration Distributed metric configuration.
-     */
-    // 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.
+    @Override
     public void configure(MetricConfiguration metricConfiguration) {
         assert this.metricConfiguration == null : "Metric manager must be 
configured only once, on the start of the node";
 
         this.metricConfiguration = metricConfiguration;
     }
 
-    /** {@inheritDoc} */
-    @Override public CompletableFuture<Void> startAsync() {
+    @Override
+    public CompletableFuture<Void> startAsync() {
         start(loadExporters());
 
         return nullCompletedFuture();
     }
 
-    /**
-     * Start component.
-     *
-     * @param availableExporters Map of (name, exporter) with available 
exporters.
-     */
+    @Override
     @VisibleForTesting
     public void start(Map<String, MetricExporter> availableExporters) {
         this.availableExporters = availableExporters;
@@ -116,11 +105,7 @@ public class MetricManager implements IgniteComponent {
         metricConfiguration.exporters().listenElements(new 
ExporterConfigurationListener());
     }
 
-    /**
-     * Starts component with default configuration.
-     *
-     * @param exporters Exporters.
-     */
+    @Override
     public void start(Iterable<MetricExporter<?>> exporters) {
         this.availableExporters = new HashMap<>();
 
@@ -132,7 +117,6 @@ public class MetricManager implements IgniteComponent {
         }
     }
 
-    /** {@inheritDoc} */
     @Override public CompletableFuture<Void> stopAsync() {
         for (MetricExporter metricExporter : enabledMetricExporters.values()) {
             metricExporter.stop();
@@ -143,39 +127,22 @@ public class MetricManager implements IgniteComponent {
         return nullCompletedFuture();
     }
 
-    /**
-     * Register metric source. See {@link 
MetricRegistry#registerSource(MetricSource)}.
-     *
-     * @param src Metric source.
-     */
+    @Override
     public void registerSource(MetricSource src) {
         registry.registerSource(src);
     }
 
-    /**
-     * Unregister metric source. See {@link 
MetricRegistry#unregisterSource(MetricSource)}.
-     *
-     * @param src Metric source.
-     */
+    @Override
     public void unregisterSource(MetricSource src) {
         registry.unregisterSource(src);
     }
 
-    /**
-     * Unregister metric source by name. See {@link 
MetricRegistry#unregisterSource(String)}.
-     *
-     * @param srcName Metric source name.
-     */
+    @Override
     public void unregisterSource(String srcName) {
         registry.unregisterSource(srcName);
     }
 
-    /**
-     * Enable metric source. See {@link MetricRegistry#enable(MetricSource)}.
-     *
-     * @param src Metric source.
-     * @return Metric set, or {@code null} if already enabled.
-     */
+    @Override
     public MetricSet enable(MetricSource src) {
         MetricSet enabled = registry.enable(src);
 
@@ -186,12 +153,7 @@ public class MetricManager implements IgniteComponent {
         return enabled;
     }
 
-    /**
-     * Enable metric source by name. See {@link MetricRegistry#enable(String)}.
-     *
-     * @param srcName Source name.
-     * @return Metric set, or {@code null} if already enabled.
-     */
+    @Override
     public MetricSet enable(final String srcName) {
         MetricSet enabled = registry.enable(srcName);
 
@@ -202,58 +164,26 @@ public class MetricManager implements IgniteComponent {
         return enabled;
     }
 
-    /**
-     * Load exporters by {@link ServiceLoader} mechanism.
-     *
-     * @return list of loaded exporters.
-     */
-    public static Map<String, MetricExporter> loadExporters() {
-        var clsLdr = Thread.currentThread().getContextClassLoader();
-
-        return ServiceLoader
-                .load(MetricExporter.class, clsLdr)
-                .stream()
-                .map(Provider::get)
-                .collect(Collectors.toMap(e -> e.name(), Function.identity()));
-    }
-
-    /**
-     * Disable metric source. See {@link MetricRegistry#disable(MetricSource)}.
-     *
-     * @param src Metric source.
-     */
+    @Override
     public void disable(MetricSource src) {
         registry.disable(src);
 
         enabledMetricExporters.values().forEach(e -> 
e.removeMetricSet(src.name()));
     }
 
-    /**
-     * Disable metric source by name. See {@link 
MetricRegistry#disable(String)}.
-     *
-     * @param srcName Metric source name.
-     */
+    @Override
     public void disable(final String srcName) {
         registry.disable(srcName);
 
         enabledMetricExporters.values().forEach(e -> 
e.removeMetricSet(srcName));
     }
 
-    /**
-     * Metrics snapshot. This is a snapshot of metric sets with corresponding 
version, the values of the metrics in the
-     * metric sets that are included into the snapshot, are changed 
dynamically.
-     *
-     * @return Metrics snapshot.
-     */
+    @Override
     public IgniteBiTuple<Map<String, MetricSet>, Long> metricSnapshot() {
         return registry.metricSnapshot();
     }
 
-    /**
-     * Gets a collection of metric sources.
-     *
-     * @return collection of metric sources
-     */
+    @Override
     public Collection<MetricSource> metricSources() {
         return registry.metricSources();
     }
@@ -272,6 +202,21 @@ public class MetricManager implements IgniteComponent {
         }
     }
 
+    /**
+     * Load exporters by {@link ServiceLoader} mechanism.
+     *
+     * @return list of loaded exporters.
+     */
+    public static Map<String, MetricExporter> loadExporters() {
+        var clsLdr = Thread.currentThread().getContextClassLoader();
+
+        return ServiceLoader
+                .load(MetricExporter.class, clsLdr)
+                .stream()
+                .map(Provider::get)
+                .collect(Collectors.toMap(e -> e.name(), Function.identity()));
+    }
+
     private class ExporterConfigurationListener implements 
ConfigurationNamedListListener<ExporterView> {
         @Override
         public CompletableFuture<?> 
onCreate(ConfigurationNotificationEvent<ExporterView> ctx) {
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/SimpleMovingAverage.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/SimpleMovingAverage.java
new file mode 100644
index 0000000000..d7b020cc48
--- /dev/null
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/SimpleMovingAverage.java
@@ -0,0 +1,80 @@
+/*
+ * 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 java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.function.DoubleFunction;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * The metric calculates the average value for the last several operations.
+ */
+public class SimpleMovingAverage extends AbstractMetric implements 
DoubleMetric {
+    /** Default window size. */
+    public static final int DFLT_ITEMS = 100;
+
+    /** Size. */
+    private final int items;
+
+    /** Elements. */
+    ConcurrentLinkedDeque<Double> queue = new ConcurrentLinkedDeque<>();
+
+    /**
+     * The constructor.
+     *
+     * @param name Name.
+     * @param desc Description.
+     * @param stringFormatter String formatter to get a readable value.
+     */
+    public SimpleMovingAverage(String name, @Nullable String desc, @Nullable 
DoubleFunction<String> stringFormatter) {
+        this(name, desc, stringFormatter, DFLT_ITEMS);
+    }
+
+    /**
+     * The constructor.
+     *
+     * @param name Name.
+     * @param desc Description.
+     * @param stringFormatter String formatter to get a readable value.
+     * @param items Quantity items to calculate average value.
+     */
+    public SimpleMovingAverage(String name, @Nullable String desc, 
DoubleFunction<String> stringFormatter, int items) {
+        super(name, desc);
+
+        this.items = items;
+    }
+
+    /**
+     * Adds some value.
+     *
+     * @param val Value.
+     */
+    public void add(double val) {
+        queue.add(val);
+
+        while (queue.size() > items) {
+            queue.pop();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double value() {
+        return queue.stream().mapToDouble(a -> a).average().orElse(0.);
+    }
+}
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/configuration/MetricConfigurationModule.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/configuration/MetricConfigurationModule.java
index 7b58867f1e..9b22ef19f9 100644
--- 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/configuration/MetricConfigurationModule.java
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/configuration/MetricConfigurationModule.java
@@ -24,6 +24,7 @@ import org.apache.ignite.configuration.ConfigurationModule;
 import org.apache.ignite.configuration.RootKey;
 import org.apache.ignite.configuration.annotation.ConfigurationType;
 import 
org.apache.ignite.internal.metrics.exporters.configuration.JmxExporterConfigurationSchema;
+import 
org.apache.ignite.internal.metrics.exporters.configuration.LogPushExporterConfigurationSchema;
 
 /**
  * Configuration module for metrics' configs.
@@ -45,6 +46,6 @@ public class MetricConfigurationModule implements 
ConfigurationModule {
     /** {@inheritDoc} */
     @Override
     public Collection<Class<?>> polymorphicSchemaExtensions() {
-        return List.of(JmxExporterConfigurationSchema.class);
+        return List.of(JmxExporterConfigurationSchema.class, 
LogPushExporterConfigurationSchema.class);
     }
 }
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 2bae2dfcbf..d93db1fd85 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
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.metrics.exporters;
 
+import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.metrics.MetricProvider;
 import org.apache.ignite.internal.metrics.MetricSet;
 import 
org.apache.ignite.internal.metrics.exporters.configuration.ExporterConfiguration;
@@ -64,7 +65,7 @@ public interface MetricExporter<CfgT extends ExporterView> {
     void reconfigure(CfgT newValue);
 
     /**
-     * {@link org.apache.ignite.internal.metrics.MetricManager} invokes this 
method,
+     * {@link MetricManagerImpl} invokes this method,
      * when new metric source was enabled.
      *
      * @param metricSet Named metric set.
@@ -72,7 +73,7 @@ public interface MetricExporter<CfgT extends ExporterView> {
     void addMetricSet(MetricSet metricSet);
 
     /**
-     * {@link org.apache.ignite.internal.metrics.MetricManager} invokes this 
method,
+     * {@link MetricManagerImpl} invokes this method,
      * when the metric source was disabled.
      *
      * @param metricSetName Name of metric set to remove.
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/LongGauge.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
similarity index 54%
copy from 
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/LongGauge.java
copy to 
modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
index 5f8db421f6..6e0b63046a 100644
--- 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/LongGauge.java
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/configuration/LogPushExporterConfigurationSchema.java
@@ -15,33 +15,17 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.metrics;
+package org.apache.ignite.internal.metrics.exporters.configuration;
 
-import java.util.function.LongSupplier;
-import org.jetbrains.annotations.Nullable;
+import org.apache.ignite.configuration.annotation.PolymorphicConfigInstance;
+import org.apache.ignite.configuration.annotation.Value;
+import org.apache.ignite.internal.metrics.exporters.log.LogPushExporter;
 
 /**
- * Implementation based on primitive supplier.
+ * Configuration for log push exporter.
  */
-public class LongGauge extends AbstractMetric implements LongMetric {
-    /** Value supplier. */
-    private final LongSupplier val;
-
-    /**
-     * Constructor.
-     *
-     * @param name Name.
-     * @param desc Description.
-     * @param val Supplier.
-     */
-    public LongGauge(String name, @Nullable String desc, LongSupplier val) {
-        super(name, desc);
-
-        this.val = val;
-    }
-
-    /** {@inheritDoc} */
-    @Override public long value() {
-        return val.getAsLong();
-    }
+@PolymorphicConfigInstance(LogPushExporter.EXPORTER_NAME)
+public class LogPushExporterConfigurationSchema extends 
ExporterConfigurationSchema {
+    @Value(hasDefault = true)
+    public int period = 30_000;
 }
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/jmx/MetricSetMbean.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/jmx/MetricSetMbean.java
index 95486794e1..4d4c0defd1 100644
--- 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/jmx/MetricSetMbean.java
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/jmx/MetricSetMbean.java
@@ -33,7 +33,7 @@ import org.apache.ignite.internal.metrics.DoubleMetric;
 import org.apache.ignite.internal.metrics.IntMetric;
 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;
 
 /**
@@ -135,7 +135,7 @@ public class MetricSetMbean implements DynamicMBean {
         });
 
         return new MBeanInfo(
-                MetricManager.class.getName(),
+                MetricManagerImpl.class.getName(),
                 metricSet.name(),
                 attrs.toArray(new MBeanAttributeInfo[0]),
                 null,
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporter.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporter.java
new file mode 100644
index 0000000000..cd00a45d7f
--- /dev/null
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/exporters/log/LogPushExporter.java
@@ -0,0 +1,90 @@
+/*
+ * 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.exporters.log;
+
+import com.google.auto.service.AutoService;
+import java.util.Comparator;
+import java.util.stream.StreamSupport;
+import org.apache.ignite.internal.logger.IgniteLogger;
+import org.apache.ignite.internal.logger.Loggers;
+import org.apache.ignite.internal.metrics.Metric;
+import org.apache.ignite.internal.metrics.MetricProvider;
+import org.apache.ignite.internal.metrics.MetricSet;
+import org.apache.ignite.internal.metrics.exporters.MetricExporter;
+import org.apache.ignite.internal.metrics.exporters.PushMetricExporter;
+import 
org.apache.ignite.internal.metrics.exporters.configuration.LogPushExporterView;
+import org.apache.ignite.internal.util.CollectionUtils;
+
+/**
+ * Log push metrics exporter.
+ */
+@AutoService(MetricExporter.class)
+public class LogPushExporter extends PushMetricExporter<LogPushExporterView> {
+    public static final String EXPORTER_NAME = "logPush";
+
+    private IgniteLogger log;
+
+    private long period;
+
+    @Override
+    public void start(MetricProvider metricsProvider, LogPushExporterView 
configuration) {
+        period = configuration.period();
+        log = Loggers.forClass(LogPushExporter.class);
+
+        super.start(metricsProvider, configuration);
+    }
+
+    @Override
+    protected long period() {
+        return period;
+    }
+
+    @Override
+    public void report() {
+        if (CollectionUtils.nullOrEmpty(metrics().get1().values())) {
+            return;
+        }
+
+        var report = new StringBuilder("Metric report: \n");
+
+        for (MetricSet metricSet : metrics().get1().values()) {
+            report.append(metricSet.name()).append(":\n");
+
+            StreamSupport.stream(metricSet.spliterator(), 
false).sorted(Comparator.comparing(Metric::name)).forEach(metric ->
+                    report.append(metric.name())
+                            .append(':')
+                            .append(metric.getValueAsString())
+                            .append('\n'));
+        }
+
+        log.info(report.toString());
+    }
+
+    @Override
+    public String name() {
+        return EXPORTER_NAME;
+    }
+
+    @Override
+    public void addMetricSet(MetricSet metricSet) {
+    }
+
+    @Override
+    public void removeMetricSet(String metricSetName) {
+    }
+}
diff --git 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/sources/JvmMetricSource.java
 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/sources/JvmMetricSource.java
index adb60243a5..0ffb02aa47 100644
--- 
a/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/sources/JvmMetricSource.java
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/sources/JvmMetricSource.java
@@ -74,37 +74,48 @@ public class JvmMetricSource implements MetricSource {
 
         CachedMemoryUsage heapMemoryUsage = new 
CachedMemoryUsage(memoryMxBean::getHeapMemoryUsage, MEMORY_USAGE_CACHE_TIMEOUT);
         metrics.put("memory.heap.Init",
-                new LongGauge("memory.heap.Init", "Initial amount of heap 
memory", () -> heapMemoryUsage.get().getInit()));
+                new LongGauge(
+                        "memory.heap.Init",
+                        "Initial amount of heap memory",
+                        () -> heapMemoryUsage.get().getInit()
+                ));
         metrics.put("memory.heap.Used",
                 new LongGauge("memory.heap.Used",
                         "Current used amount of heap memory",
-                        () -> heapMemoryUsage.get().getUsed()));
+                        () -> heapMemoryUsage.get().getUsed()
+                ));
         metrics.put("memory.heap.Committed",
                 new LongGauge("memory.heap.Committed",
                         "Committed amount of heap memory",
-                        () -> heapMemoryUsage.get().getCommitted()));
+                        () -> heapMemoryUsage.get().getCommitted()
+                ));
         metrics.put("memory.heap.Max",
                 new LongGauge("memory.heap.Max",
                         "Maximum amount of heap memory",
-                        () -> heapMemoryUsage.get().getMax()));
+                        () -> heapMemoryUsage.get().getMax()
+                ));
 
         CachedMemoryUsage nonHeapMemoryUsage = new 
CachedMemoryUsage(memoryMxBean::getNonHeapMemoryUsage, 
MEMORY_USAGE_CACHE_TIMEOUT);
         metrics.put("memory.non-heap.Init",
                 new LongGauge("memory.non-heap.Init",
                         "Initial amount of non-heap memory",
-                        () -> nonHeapMemoryUsage.get().getInit()));
+                        () -> nonHeapMemoryUsage.get().getInit()
+                ));
         metrics.put("memory.non-heap.Used",
                 new LongGauge("memory.non-heap.Used",
                         "Used amount of non-heap memory",
-                        () -> nonHeapMemoryUsage.get().getUsed()));
+                        () -> nonHeapMemoryUsage.get().getUsed()
+                ));
         metrics.put("memory.non-heap.Committed",
                 new LongGauge("memory.non-heap.Committed",
                         "Committed amount of non-heap memory",
-                        () -> nonHeapMemoryUsage.get().getCommitted()));
+                        () -> nonHeapMemoryUsage.get().getCommitted()
+                ));
         metrics.put("memory.non-heap.Max",
                 new LongGauge("memory.non-heap.Max",
                         "Maximum amount of non-heap memory",
-                        () -> nonHeapMemoryUsage.get().getMax()));
+                        () -> nonHeapMemoryUsage.get().getMax()
+                ));
 
         enabled = true;
 
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 b20aad62d9..f14034627b 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
@@ -53,7 +53,7 @@ public class MetricConfigurationTest extends 
BaseIgniteAbstractTest {
 
     @BeforeEach
     public void setUp() {
-        metricManager = new MetricManager();
+        metricManager = new MetricManagerImpl();
 
         Map<String, MetricExporter> availableExporters = new HashMap<>();
 
diff --git 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MovingAverageTest.java
 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MovingAverageTest.java
new file mode 100644
index 0000000000..6f8f3e1afc
--- /dev/null
+++ 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/MovingAverageTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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 java.util.Arrays;
+
+/**
+ * Metric to calculate moving average value.
+ */
+public class MovingAverageTest extends AbstractDoubleMetricTest {
+    public double[] items = new double[10];
+
+    int pos = 0;
+
+    @Override
+    protected void increment0(DoubleMetric metric) {
+        double avg = getAvg();
+
+        addValue(avg);
+
+        ((SimpleMovingAverage) metric).add(avg);
+    }
+
+    @Override
+    protected void decrement0(DoubleMetric metric) {
+        addValue(0);
+
+        ((SimpleMovingAverage) metric).add(0);
+    }
+
+    @Override
+    protected void add0(DoubleMetric metric, double value) {
+        addValue(value);
+
+        ((SimpleMovingAverage) metric).add(value);
+    }
+
+    @Override
+    protected void setValue0(DoubleMetric metric, double value) {
+        for (int i = 0; i < items.length; i++) {
+            addValue(value);
+
+            ((SimpleMovingAverage) metric).add(value);
+        }
+    }
+
+    @Override
+    protected DoubleMetric createMetric(String name, String description) {
+        return new SimpleMovingAverage(name, description, Double::toString, 
items.length);
+    }
+
+    @Override
+    protected Double expected() {
+        return getAvg();
+    }
+
+    /**
+     * Adds a value for the proper calculation of the expected one.
+     *
+     * @param value Some value.
+     */
+    private void addValue(double value) {
+        items[pos % items.length] = value;
+        pos++;
+    }
+
+    /**
+     * Calculated average value.
+     *
+     * @return Average value.
+     */
+    private double getAvg() {
+        return pos == 0 ? 0 : Arrays.stream(items, 0, Math.min(pos, 
items.length)).sum() / (Math.min(pos, items.length));
+    }
+}
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
new file mode 100644
index 0000000000..1ad4383483
--- /dev/null
+++ 
b/modules/metrics/src/testFixtures/java/org/apache/ignite/internal/metrics/NoOpMetricManager.java
@@ -0,0 +1,96 @@
+/*
+ * 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 java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.internal.lang.IgniteBiTuple;
+import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
+import org.apache.ignite.internal.metrics.exporters.MetricExporter;
+
+/**
+ * The metric manager does nothing in all operations. It is designed to be 
used in tests where not all component workflow steps might be
+ * fulfilled.
+ */
+public class NoOpMetricManager implements MetricManager {
+    @Override
+    public void configure(MetricConfiguration metricConfiguration) {
+    }
+
+    @Override
+    public CompletableFuture<Void> startAsync() {
+        return nullCompletedFuture();
+    }
+
+    @Override
+    public void start(Map<String, MetricExporter> availableExporters) {
+    }
+
+    @Override
+    public void start(Iterable<MetricExporter<?>> exporters) {
+    }
+
+    @Override
+    public CompletableFuture<Void> stopAsync() {
+        return nullCompletedFuture();
+    }
+
+    @Override
+    public void registerSource(MetricSource src) {
+    }
+
+    @Override
+    public void unregisterSource(MetricSource src) {
+    }
+
+    @Override
+    public void unregisterSource(String srcName) {
+    }
+
+    @Override
+    public MetricSet enable(MetricSource src) {
+        return null;
+    }
+
+    @Override
+    public MetricSet enable(String srcName) {
+        return null;
+    }
+
+    @Override
+    public void disable(MetricSource src) {
+    }
+
+    @Override
+    public void disable(String srcName) {
+    }
+
+    @Override
+    public IgniteBiTuple<Map<String, MetricSet>, Long> metricSnapshot() {
+        return new IgniteBiTuple<>(Collections.emptyMap(), 1L);
+    }
+
+    @Override
+    public Collection<MetricSource> metricSources() {
+        return Collections.emptyList();
+    }
+}
diff --git a/modules/placement-driver/build.gradle 
b/modules/placement-driver/build.gradle
index 9efc3a557f..ed2552c935 100644
--- a/modules/placement-driver/build.gradle
+++ b/modules/placement-driver/build.gradle
@@ -56,6 +56,7 @@ dependencies {
     integrationTestImplementation project(':ignite-replicator')
     integrationTestImplementation project(':ignite-transactions')
     integrationTestImplementation project(':ignite-catalog')
+    integrationTestImplementation project(':ignite-metrics')
 
     integrationTestImplementation(testFixtures(project(':ignite-core')))
     integrationTestImplementation(testFixtures(project(':ignite-network')))
@@ -66,6 +67,7 @@ dependencies {
     
integrationTestImplementation(testFixtures(project(':ignite-distribution-zones')))
     integrationTestImplementation(testFixtures(project(':ignite-runner')))
     integrationTestImplementation(testFixtures(project(':ignite-replicator')))
+    integrationTestImplementation(testFixtures(project(':ignite-metrics:')))
 
     testImplementation(testFixtures(project(':ignite-core')))
     testImplementation(testFixtures(project(':ignite-metastorage')))
diff --git 
a/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/MultiActorPlacementDriverTest.java
 
b/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/MultiActorPlacementDriverTest.java
index abcef594d8..fe784efb88 100644
--- 
a/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/MultiActorPlacementDriverTest.java
+++ 
b/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/MultiActorPlacementDriverTest.java
@@ -53,6 +53,7 @@ import 
org.apache.ignite.internal.metastorage.impl.MetaStorageManagerImpl;
 import org.apache.ignite.internal.metastorage.impl.MetaStorageServiceImpl;
 import 
org.apache.ignite.internal.metastorage.server.SimpleInMemoryKeyValueStorage;
 import org.apache.ignite.internal.metastorage.server.raft.MetastorageGroupId;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NetworkMessageHandler;
 import org.apache.ignite.internal.network.StaticNodeFinder;
@@ -243,6 +244,7 @@ public class MultiActorPlacementDriverTest extends 
BasePlacementDriverTest {
 
             var raftManager = new Loza(
                     clusterService,
+                    new NoOpMetricManager(),
                     raftConfiguration,
                     workDir.resolve(nodeName + "_loza"),
                     nodeClock,
diff --git 
a/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/PlacementDriverManagerTest.java
 
b/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/PlacementDriverManagerTest.java
index bec4dbabc9..4171b9f9ac 100644
--- 
a/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/PlacementDriverManagerTest.java
+++ 
b/modules/placement-driver/src/integrationTest/java/org/apache/ignite/internal/placementdriver/PlacementDriverManagerTest.java
@@ -72,6 +72,7 @@ import 
org.apache.ignite.internal.metastorage.configuration.MetaStorageConfigura
 import org.apache.ignite.internal.metastorage.impl.MetaStorageManagerImpl;
 import 
org.apache.ignite.internal.metastorage.server.SimpleInMemoryKeyValueStorage;
 import org.apache.ignite.internal.metastorage.server.raft.MetastorageGroupId;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NetworkMessageHandler;
 import org.apache.ignite.internal.network.StaticNodeFinder;
@@ -180,6 +181,7 @@ public class PlacementDriverManagerTest extends 
BasePlacementDriverTest {
 
         raftManager = new Loza(
                 clusterService,
+                new NoOpMetricManager(),
                 raftConfiguration,
                 workDir.resolve("loza"),
                 nodeClock,
diff --git a/modules/raft/build.gradle b/modules/raft/build.gradle
index 89aad16e66..98b0a1789c 100644
--- a/modules/raft/build.gradle
+++ b/modules/raft/build.gradle
@@ -42,6 +42,7 @@ dependencies {
     implementation project(':ignite-raft-api')
     implementation project(':ignite-network')
     implementation project(':ignite-rocksdb-common')
+    implementation project(':ignite-metrics')
     implementation libs.jetbrains.annotations
     implementation libs.fastutil.core
     implementation libs.disruptor
@@ -59,6 +60,7 @@ dependencies {
     testImplementation(testFixtures(project(':ignite-core')))
     testImplementation(testFixtures(project(':ignite-network')))
     testImplementation(testFixtures(project(':ignite-configuration')))
+    testImplementation(testFixtures(project(':ignite-metrics:')))
     testImplementation project(':ignite-configuration')
     testImplementation project(':ignite-core')
     testImplementation project(':ignite-network')
@@ -88,6 +90,7 @@ dependencies {
     
integrationTestImplementation(testFixtures(project(':ignite-configuration')))
     integrationTestImplementation(testFixtures(project(':ignite-network')))
     integrationTestImplementation testFixtures(project(':ignite-workers'))
+    integrationTestImplementation testFixtures(project(':ignite-metrics:'))
     integrationTestImplementation project(':ignite-raft-api')
     integrationTestImplementation project(':ignite-failure-handler')
     integrationTestImplementation libs.jetbrains.annotations
diff --git 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItLearnersTest.java
 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItLearnersTest.java
index d6cf4d5ba3..d7f2279248 100644
--- 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItLearnersTest.java
+++ 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItLearnersTest.java
@@ -52,6 +52,7 @@ import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExten
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.lang.NodeStoppingException;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
 import org.apache.ignite.internal.raft.configuration.RaftConfiguration;
@@ -109,7 +110,7 @@ public class ItLearnersTest extends IgniteAbstractTest {
 
             Path raftDir = workDir.resolve(clusterService.nodeName());
 
-            loza = new Loza(clusterService, raftConfiguration, raftDir, new 
HybridClockImpl());
+            loza = new Loza(clusterService, new NoOpMetricManager(), 
raftConfiguration, raftDir, new HybridClockImpl());
         }
 
         String consistentId() {
diff --git 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItLozaTest.java
 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItLozaTest.java
index 0c08f1d36f..940a03ae66 100644
--- 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItLozaTest.java
+++ 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItLozaTest.java
@@ -38,6 +38,7 @@ import java.util.concurrent.TimeUnit;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.MessagingService;
 import org.apache.ignite.internal.network.NetworkMessage;
@@ -125,7 +126,7 @@ public class ItLozaTest extends BaseIgniteAbstractTest {
 
             CompletableFuture<NetworkMessage> exception = 
CompletableFuture.failedFuture(new IOException());
 
-            loza = new Loza(service, raftConfiguration, dataPath, new 
HybridClockImpl());
+            loza = new Loza(service, new NoOpMetricManager(), 
raftConfiguration, dataPath, new HybridClockImpl());
 
             assertThat(loza.startAsync(), willCompleteSuccessfully());
 
diff --git 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItRaftGroupServiceTest.java
 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItRaftGroupServiceTest.java
index 43e1589905..c1401c06f8 100644
--- 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItRaftGroupServiceTest.java
+++ 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItRaftGroupServiceTest.java
@@ -45,6 +45,7 @@ import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExten
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.lang.NodeStoppingException;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NodeFinder;
 import org.apache.ignite.internal.network.StaticNodeFinder;
@@ -215,7 +216,13 @@ public class ItRaftGroupServiceTest extends 
IgniteAbstractTest {
 
         TestNode(TestInfo testInfo) {
             this.clusterService = 
ClusterServiceTestUtils.clusterService(testInfo, NODE_PORT_BASE + nodes.size(), 
NODE_FINDER);
-            this.loza = new Loza(clusterService, raftConfiguration, 
workDir.resolve("node" + nodes.size()), new HybridClockImpl());
+            this.loza = new Loza(
+                    clusterService,
+                    new NoOpMetricManager(),
+                    raftConfiguration,
+                    workDir.resolve("node" + nodes.size()),
+                    new HybridClockImpl()
+            );
         }
 
         String name() {
diff --git 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItTruncateSuffixAndRestartTest.java
 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItTruncateSuffixAndRestartTest.java
index a641db24fe..bbb2adc645 100644
--- 
a/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItTruncateSuffixAndRestartTest.java
+++ 
b/modules/raft/src/integrationTest/java/org/apache/ignite/internal/raft/ItTruncateSuffixAndRestartTest.java
@@ -49,6 +49,7 @@ import org.apache.ignite.internal.failure.FailureProcessor;
 import org.apache.ignite.internal.hlc.HybridClock;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.lang.NodeStoppingException;
+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;
@@ -184,7 +185,7 @@ public class ItTruncateSuffixAndRestartTest extends 
BaseIgniteAbstractTest {
             assertThat(clusterSvc.startAsync(), willCompleteSuccessfully());
             cleanup.add(() -> assertThat(clusterSvc.stopAsync(), 
willCompleteSuccessfully()));
 
-            raftMgr = new Loza(clusterSvc, raftConfiguration, nodeDir, 
hybridClock);
+            raftMgr = new Loza(clusterSvc, new NoOpMetricManager(), 
raftConfiguration, nodeDir, hybridClock);
 
             assertThat(raftMgr.startAsync(), willCompleteSuccessfully());
             cleanup.add(() -> assertThat(raftMgr.stopAsync(), 
willCompleteSuccessfully()));
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/internal/metrics/sources/RaftMetricSource.java
 
b/modules/raft/src/main/java/org/apache/ignite/internal/metrics/sources/RaftMetricSource.java
new file mode 100644
index 0000000000..ae0deab8c7
--- /dev/null
+++ 
b/modules/raft/src/main/java/org/apache/ignite/internal/metrics/sources/RaftMetricSource.java
@@ -0,0 +1,178 @@
+/*
+ * 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.sources;
+
+import java.util.HashMap;
+import java.util.stream.LongStream;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.metrics.Metric;
+import org.apache.ignite.internal.metrics.MetricSet;
+import org.apache.ignite.internal.metrics.MetricSource;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Metrics of striped disruptor.
+ */
+public class RaftMetricSource implements MetricSource {
+    public static final String SOURCE_NAME = "raft";
+
+    /** True, if source is enabled, false otherwise. */
+    private boolean enabled;
+
+    /** Disruptor stripe count. */
+    private final int stripeCount;
+
+    /** Log disruptor stripe count. */
+    private final int logStripeCount;
+
+    /** Metric set. */
+    HashMap<String, Metric> metrics = new HashMap<>();
+
+    /**
+     * Constructor.
+     *
+     * @param stripeCount Count of stripes.
+     * @param logStripeCount Log manager disruptor stripe count.
+     */
+    public RaftMetricSource(int stripeCount, int logStripeCount) {
+        this.stripeCount = stripeCount;
+        this.logStripeCount = logStripeCount;
+
+        initMetrics();
+    }
+
+    @Override
+    public String name() {
+        return SOURCE_NAME;
+    }
+
+    @Override
+    public @Nullable MetricSet enable() {
+        enabled = true;
+
+        return new MetricSet(SOURCE_NAME, metrics);
+    }
+
+    private void initMetrics() {
+        long[] bounds = new long[]{10L, 20L, 30L, 40L, 50L};
+
+        // jraft-fsmcaller-disruptor
+        metrics.put("raft.fsmcaller.disruptor.Batch",
+                new DistributionMetric(
+                        "raft.fsmcaller.disruptor.Batch",
+                        "The histogram of the batch size to handle in the 
state machine for partitions",
+                        bounds
+                ));
+        metrics.put("raft.fsmcaller.disruptor.Stripes",
+                new DistributionMetric(
+                        "raft.fsmcaller.disruptor.Stripes",
+                        "The histogram of distribution data by stripes in the 
state machine for partitions",
+                        LongStream.range(0, stripeCount).toArray()
+                ));
+
+        // jraft-nodeimpl-disruptor
+        metrics.put("raft.nodeimpl.disruptor.Batch",
+                new DistributionMetric(
+                        "raft.nodeimpl.disruptor.Batch",
+                        "The histogram of the batch size to handle node 
operations for partitions",
+                        bounds
+                ));
+        metrics.put("raft.nodeimpl.disruptor.Stripes",
+                new DistributionMetric(
+                        "raft.nodeimpl.disruptor.Stripes",
+                        "The histogram of distribution data by stripes for 
node operations for partitions",
+                        LongStream.range(0, stripeCount).toArray()
+                ));
+
+        // jraft-readonlyservice-disruptor
+        metrics.put("raft.readonlyservice.disruptor.Batch",
+                new DistributionMetric(
+                        "raft.readonlyservice.disruptor.Batch",
+                        "The histogram of the batch size to handle readonly 
operations for partitions",
+                        bounds
+                ));
+        metrics.put("raft.readonlyservice.disruptor.Stripes",
+                new DistributionMetric(
+                        "raft.readonlyservice.disruptor.Stripes",
+                        "The histogram of distribution data by stripes 
readonly operations for partitions",
+                        LongStream.range(0, stripeCount).toArray()
+                ));
+
+        // jraft-logmanager-disruptor
+        metrics.put("raft.logmanager.disruptor.Batch",
+                new DistributionMetric(
+                        "raft.logmanager.disruptor.Batch",
+                        "The histogram of the batch size to handle in the log 
for partitions",
+                        bounds
+                ));
+        metrics.put("raft.logmanager.disruptor.Stripes",
+                new DistributionMetric(
+                        "raft.logmanager.disruptor.Stripes",
+                        "The histogram of distribution data by stripes in the 
log for partitions",
+                        LongStream.range(0, logStripeCount).toArray()
+                ));
+    }
+
+    /**
+     * Disruptor metrics source.
+     *
+     * @param name Disruptor name.
+     * @return Object to track metrics.
+     */
+    public DisruptorMetrics disruptorMetrics(String name) {
+        return new DisruptorMetrics(
+                (DistributionMetric) metrics.get(name + ".Batch"),
+                (DistributionMetric) metrics.get(name + ".Stripes")
+        );
+    }
+
+    @Override
+    public void disable() {
+        enabled = false;
+    }
+
+    @Override
+    public boolean enabled() {
+        return enabled;
+    }
+
+    /**
+     * Striped disruptor metrics.
+     */
+    public class DisruptorMetrics {
+        private DistributionMetric batchSizeHistogramMetric;
+        private DistributionMetric stripeHistogramMetric;
+
+        public DisruptorMetrics(DistributionMetric averageBatchSizeMetric, 
DistributionMetric stripeHistogramMetric) {
+            this.batchSizeHistogramMetric = averageBatchSizeMetric;
+            this.stripeHistogramMetric = stripeHistogramMetric;
+        }
+
+        public boolean enabled() {
+            return enabled;
+        }
+
+        public void addBatchSize(long size) {
+            batchSizeHistogramMetric.add(size);
+        }
+
+        public void hitToStripe(int stripe) {
+            stripeHistogramMetric.add(stripe);
+        }
+    }
+}
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
index a755cc06a5..f4c6732ba2 100644
--- a/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
+++ b/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
@@ -35,6 +35,8 @@ import org.apache.ignite.internal.lang.IgniteStringFormatter;
 import org.apache.ignite.internal.lang.NodeStoppingException;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
+import org.apache.ignite.internal.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.sources.RaftMetricSource;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.MessagingService;
 import org.apache.ignite.internal.raft.configuration.RaftConfiguration;
@@ -98,16 +100,20 @@ public class Loza implements RaftManager {
 
     private final NodeOptions opts;
 
+    private final MetricManager metricManager;
+
     /**
      * The constructor.
      *
      * @param clusterNetSvc Cluster network service.
+     * @param metricManager Metric manager.
      * @param raftConfiguration Raft configuration.
      * @param dataPath Data path.
      * @param clock A hybrid logical clock.
      */
     public Loza(
             ClusterService clusterNetSvc,
+            MetricManager metricManager,
             RaftConfiguration raftConfiguration,
             Path dataPath,
             HybridClock clock,
@@ -115,6 +121,7 @@ public class Loza implements RaftManager {
     ) {
         this.clusterNetSvc = clusterNetSvc;
         this.raftConfiguration = raftConfiguration;
+        this.metricManager = metricManager;
 
         NodeOptions options = new NodeOptions();
 
@@ -135,6 +142,7 @@ public class Loza implements RaftManager {
      * The constructor.
      *
      * @param clusterNetSvc Cluster network service.
+     * @param metricManager Metric manager.
      * @param raftConfiguration Raft configuration.
      * @param dataPath Data path.
      * @param clock A hybrid logical clock.
@@ -142,12 +150,14 @@ public class Loza implements RaftManager {
     @TestOnly
     public Loza(
             ClusterService clusterNetSvc,
+            MetricManager metricManager,
             RaftConfiguration raftConfiguration,
             Path dataPath,
             HybridClock clock
     ) {
         this(
                 clusterNetSvc,
+                metricManager,
                 raftConfiguration,
                 dataPath,
                 clock,
@@ -180,6 +190,11 @@ public class Loza implements RaftManager {
     public CompletableFuture<Void> startAsync() {
         RaftView raftConfig = raftConfiguration.value();
 
+        var stripeSource = new 
RaftMetricSource(raftConfiguration.value().stripes(), 
raftConfiguration.value().logStripesCount());
+
+        metricManager.registerSource(stripeSource);
+
+        opts.setRaftMetrics(stripeSource);
         
opts.setRpcInstallSnapshotTimeout(raftConfig.rpcInstallSnapshotTimeout());
         opts.setStripes(raftConfig.stripes());
         opts.setLogStripesCount(raftConfig.logStripesCount());
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/server/impl/JraftServerImpl.java
 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/server/impl/JraftServerImpl.java
index 7497c9ce76..5cb2f14840 100644
--- 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/server/impl/JraftServerImpl.java
+++ 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/server/impl/JraftServerImpl.java
@@ -48,6 +48,7 @@ import org.apache.ignite.internal.lang.IgniteStringFormatter;
 import org.apache.ignite.internal.lang.IgniteSystemProperties;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
+import org.apache.ignite.internal.metrics.sources.RaftMetricSource;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.raft.Marshaller;
 import org.apache.ignite.internal.raft.Peer;
@@ -319,6 +320,10 @@ public class JraftServerImpl implements RaftServer {
                 actionRequestInterceptor
         );
 
+        if (opts.getRaftMetrics() == null) {
+            opts.setRaftMetrics(new RaftMetricSource(opts.getStripes(), 
opts.getLogStripesCount()));
+        }
+
         if (opts.getfSMCallerExecutorDisruptor() == null) {
             opts.setfSMCallerExecutorDisruptor(new StripedDisruptor<>(
                     opts.getServerName(),
@@ -328,7 +333,8 @@ public class JraftServerImpl implements RaftServer {
                     ApplyTask::new,
                     opts.getStripes(),
                     false,
-                    false
+                    false,
+                    
opts.getRaftMetrics().disruptorMetrics("raft.fsmcaller.disruptor")
             ));
         }
 
@@ -340,7 +346,8 @@ public class JraftServerImpl implements RaftServer {
                     LogEntryAndClosure::new,
                     opts.getStripes(),
                     false,
-                    false
+                    false,
+                    
opts.getRaftMetrics().disruptorMetrics("raft.nodeimpl.disruptor")
             ));
         }
 
@@ -352,7 +359,8 @@ public class JraftServerImpl implements RaftServer {
                     ReadIndexEvent::new,
                     opts.getStripes(),
                     false,
-                    false
+                    false,
+                    
opts.getRaftMetrics().disruptorMetrics("raft.readonlyservice.disruptor")
             ));
         }
 
@@ -364,7 +372,8 @@ public class JraftServerImpl implements RaftServer {
                     StableClosureEvent::new,
                     opts.getLogStripesCount(),
                     true,
-                    opts.isLogYieldStrategy()
+                    opts.isLogYieldStrategy(),
+                    
opts.getRaftMetrics().disruptorMetrics("raft.logmanager.disruptor")
             ));
 
             opts.setLogStripes(IntStream.range(0, 
opts.getLogStripesCount()).mapToObj(i -> new Stripe()).collect(toList()));
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java
index 972a0bc217..963d25b6eb 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java
@@ -43,7 +43,7 @@ import org.apache.ignite.internal.hlc.HybridClock;
 import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
-import org.apache.ignite.internal.raft.JraftGroupEventsListener;
+import org.apache.ignite.internal.metrics.sources.RaftMetricSource;import 
org.apache.ignite.internal.raft.JraftGroupEventsListener;
 import org.apache.ignite.internal.raft.RaftNodeDisruptorConfiguration;
 import org.apache.ignite.internal.raft.storage.impl.RocksDbSharedLogStorage;
 import org.apache.ignite.internal.raft.storage.impl.StripeAwareLogManager;
@@ -1238,6 +1238,10 @@ public class NodeImpl implements Node, RaftServerService 
{
         if (opts.getClientExecutor() == null && validateOption(opts, 
"clientExecutor"))
             opts.setClientExecutor(JRaftUtils.createClientExecutor(opts, 
opts.getServerName()));
 
+        if (opts.getRaftMetrics() == null) {
+            opts.setRaftMetrics(new RaftMetricSource(opts.getStripes(), 
opts.getLogStripesCount()));
+        }
+
         if (opts.getfSMCallerExecutorDisruptor() == null) {
             opts.setfSMCallerExecutorDisruptor(new 
StripedDisruptor<FSMCallerImpl.ApplyTask>(
                 opts.getServerName(),
@@ -1247,17 +1251,19 @@ public class NodeImpl implements Node, 
RaftServerService {
                 () -> new FSMCallerImpl.ApplyTask(),
                 opts.getStripes(),
                 false,
-                false
+                false,
+                
opts.getRaftMetrics().disruptorMetrics("raft.fsmcaller.disruptor")
             ));
         } else if (ownFsmCallerExecutorDisruptorConfig != null) {
             opts.setfSMCallerExecutorDisruptor(new 
StripedDisruptor<FSMCallerImpl.ApplyTask>(
                 opts.getServerName(),
-                "JRaft-FSMCaller-Disruptor-" + 
ownFsmCallerExecutorDisruptorConfig.getThreadPostfix(),
+                "JRaft-FSMCaller-Disruptor" + 
ownFsmCallerExecutorDisruptorConfig.getThreadPostfix(),
                 opts.getRaftOptions().getDisruptorBufferSize(),
                 () -> new FSMCallerImpl.ApplyTask(),
                 ownFsmCallerExecutorDisruptorConfig.getStripes(),
                 false,
-                false
+                false,
+                null
             ));
         }
 
@@ -1269,7 +1275,8 @@ public class NodeImpl implements Node, RaftServerService {
                 () -> new NodeImpl.LogEntryAndClosure(),
                 opts.getStripes(),
                 false,
-                false
+                false,
+                
opts.getRaftMetrics().disruptorMetrics("raft.nodeimpl.disruptor")
             ));
         }
 
@@ -1281,7 +1288,8 @@ public class NodeImpl implements Node, RaftServerService {
                 () -> new ReadOnlyServiceImpl.ReadIndexEvent(),
                 opts.getStripes(),
                 false,
-                false
+                false,
+                
opts.getRaftMetrics().disruptorMetrics("raft.readonlyservice.disruptor")
             ));
         }
 
@@ -1293,7 +1301,8 @@ public class NodeImpl implements Node, RaftServerService {
                 () -> new LogManagerImpl.StableClosureEvent(),
                 opts.getLogStripesCount(),
                 logStorage instanceof RocksDbSharedLogStorage,
-                opts.isLogYieldStrategy()
+                opts.isLogYieldStrategy(),
+                
opts.getRaftMetrics().disruptorMetrics("raft.logmanager.disruptor")
             ));
 
             opts.setLogStripes(IntStream.range(0, 
opts.getLogStripesCount()).mapToObj(i -> new Stripe()).collect(toList()));
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
index 875c309b70..bb27f01514 100644
--- 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
+++ 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
@@ -33,8 +33,10 @@ import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
+import 
org.apache.ignite.internal.metrics.sources.RaftMetricSource.DisruptorMetrics;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.raft.jraft.entity.NodeId;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Stripe Disruptor is a set of queues which process several independent 
groups in one queue (in the stripe).
@@ -64,6 +66,8 @@ public class StripedDisruptor<T extends NodeIdAware> {
     /** The Striped disruptor name. */
     private final String name;
 
+    private final DisruptorMetrics metrics;
+
     /**
      * If {@code false}, this stripe will always pass {@code true} into {@link 
EventHandler#onEvent(Object, long, boolean)}.
      * Otherwise, the data will be provided with batches.
@@ -80,6 +84,7 @@ public class StripedDisruptor<T extends NodeIdAware> {
      * @param supportsBatches If {@code false}, this stripe will always pass 
{@code true} into
      *      {@link EventHandler#onEvent(Object, long, boolean)}. Otherwise, 
the data will be provided with batches.
      * @param useYieldStrategy If {@code true}, the yield strategy is to be 
used, otherwise the blocking strategy.
+     * @param metrics Metrics.
      */
     public StripedDisruptor(
             String nodeName,
@@ -88,7 +93,8 @@ public class StripedDisruptor<T extends NodeIdAware> {
             EventFactory<T> eventFactory,
             int stripes,
             boolean supportsBatches,
-            boolean useYieldStrategy
+            boolean useYieldStrategy,
+            @Nullable DisruptorMetrics metrics
     ) {
         this(
                 nodeName,
@@ -98,7 +104,8 @@ public class StripedDisruptor<T extends NodeIdAware> {
                 eventFactory,
                 stripes,
                 supportsBatches,
-                useYieldStrategy
+                useYieldStrategy,
+                metrics
         );
     }
 
@@ -112,6 +119,7 @@ public class StripedDisruptor<T extends NodeIdAware> {
      * @param supportsBatches If {@code false}, this stripe will always pass 
{@code true} into
      *      {@link EventHandler#onEvent(Object, long, boolean)}. Otherwise, 
the data will be provided with batches.
      * @param useYieldStrategy If {@code true}, the yield strategy is to be 
used, otherwise the blocking strategy.
+     * @param raftMetrics Metrics.
      */
     public StripedDisruptor(
             String nodeName,
@@ -121,7 +129,8 @@ public class StripedDisruptor<T extends NodeIdAware> {
             EventFactory<T> eventFactory,
             int stripes,
             boolean supportsBatches,
-            boolean useYieldStrategy
+            boolean useYieldStrategy,
+            @Nullable DisruptorMetrics raftMetrics
     ) {
         disruptors = new Disruptor[stripes];
         queues = new RingBuffer[stripes];
@@ -130,6 +139,7 @@ public class StripedDisruptor<T extends NodeIdAware> {
         this.stripes = stripes;
         this.name = NamedThreadFactory.threadPrefix(nodeName, poolName);
         this.supportsBatches = supportsBatches;
+        this.metrics = raftMetrics;
 
         for (int i = 0; i < stripes; i++) {
             String stripeName = format("{}_stripe_{}", poolName, i);
@@ -237,6 +247,9 @@ public class StripedDisruptor<T extends NodeIdAware> {
     private class StripeEntryHandler implements EventHandler<T> {
         private final ConcurrentHashMap<NodeId, EventHandler<T>> subscribers;
 
+        /** Size of the batch that is currently being handled. */
+        private int currentBatchSize = 0;
+
         /**
          * The constructor.
          */
@@ -269,6 +282,18 @@ public class StripedDisruptor<T extends NodeIdAware> {
 
             // TODO: IGNITE-20536 Need to add assert that handler is not null 
and to implement a no-op handler.
             if (handler != null) {
+                if (metrics != null && metrics.enabled()) {
+                    metrics.hitToStripe(getStripe(event.nodeId()));
+
+                    if (endOfBatch) {
+                        metrics.addBatchSize(currentBatchSize + 1);
+
+                        currentBatchSize = 0;
+                    } else {
+                        currentBatchSize ++;
+                    }
+                }
+
                 handler.onEvent(event, sequence, endOfBatch || 
subscribers.size() > 1 && !supportsBatches);
             } else {
                 LOG.warn(format("Group of the event is unsupported [nodeId={}, 
event={}]", event.nodeId(), event));
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/option/NodeOptions.java
 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/option/NodeOptions.java
index 0d140987dc..e444800edb 100644
--- 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/option/NodeOptions.java
+++ 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/option/NodeOptions.java
@@ -20,6 +20,7 @@ import java.util.List;
 import java.util.concurrent.ExecutorService;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.HybridClock;
+import org.apache.ignite.internal.metrics.sources.RaftMetricSource;
 import org.apache.ignite.internal.raft.JraftGroupEventsListener;
 import org.apache.ignite.internal.raft.Marshaller;
 import 
org.apache.ignite.internal.raft.storage.impl.StripeAwareLogManager.Stripe;
@@ -269,10 +270,25 @@ public class NodeOptions extends RpcOptions implements 
Copiable<NodeOptions> {
 
     private Marshaller commandsMarshaller;
 
+    private RaftMetricSource raftMetrics;
+
     public NodeOptions() {
         raftOptions.setRaftMessagesFactory(getRaftMessagesFactory());
     }
 
+    /**
+    * Gets raft metrics.
+    *
+    * @return Raft metrics.
+    */
+    public RaftMetricSource getRaftMetrics() {
+        return raftMetrics;
+    }
+
+    public void setRaftMetrics(RaftMetricSource raftMetrics) {
+        this.raftMetrics = raftMetrics;
+    }
+
     /**
      * @return Stripe count.
      */
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/disruptor/StripedDisruptorTest.java
 
b/modules/raft/src/test/java/org/apache/ignite/disruptor/StripedDisruptorTest.java
index b46e310ef4..8105dff254 100644
--- 
a/modules/raft/src/test/java/org/apache/ignite/disruptor/StripedDisruptorTest.java
+++ 
b/modules/raft/src/test/java/org/apache/ignite/disruptor/StripedDisruptorTest.java
@@ -49,7 +49,8 @@ public class StripedDisruptorTest extends IgniteAbstractTest {
                 NodeIdAwareTestObj::new,
                 1,
                 false,
-                false);
+                false,
+                null);
 
         var nodeId1 = new NodeId("grp1", new PeerId("foo"));
         var nodeId2 = new NodeId("grp2", new PeerId("foo"));
@@ -100,7 +101,8 @@ public class StripedDisruptorTest extends 
IgniteAbstractTest {
                 NodeIdAwareTestObj::new,
                 5,
                 false,
-                false);
+                false,
+                null);
 
         GroupAwareTestObjHandler handler = new GroupAwareTestObjHandler();
 
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/LozaTest.java 
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/LozaTest.java
index 1a9b70cd68..01fbc54856 100644
--- a/modules/raft/src/test/java/org/apache/ignite/internal/raft/LozaTest.java
+++ b/modules/raft/src/test/java/org/apache/ignite/internal/raft/LozaTest.java
@@ -27,6 +27,7 @@ import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExten
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.lang.NodeStoppingException;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.MessagingService;
 import org.apache.ignite.internal.raft.configuration.RaftConfiguration;
@@ -65,7 +66,7 @@ public class LozaTest extends IgniteAbstractTest {
         
Mockito.doReturn(mock(MessagingService.class)).when(clusterNetSvc).messagingService();
         
Mockito.doReturn(mock(TopologyService.class)).when(clusterNetSvc).topologyService();
 
-        Loza loza = new Loza(clusterNetSvc, raftConfiguration, workDir, new 
HybridClockImpl());
+        Loza loza = new Loza(clusterNetSvc, new NoOpMetricManager(), 
raftConfiguration, workDir, new HybridClockImpl());
 
         assertThat(loza.startAsync(), willCompleteSuccessfully());
 
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/FSMCallerTest.java
 
b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/FSMCallerTest.java
index 671b5bd0a9..518ded3da4 100644
--- 
a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/FSMCallerTest.java
+++ 
b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/FSMCallerTest.java
@@ -99,11 +99,12 @@ public class FSMCallerTest extends BaseIgniteAbstractTest {
         opts.setClosureQueue(this.closureQueue);
         opts.setRaftMessagesFactory(new RaftMessagesFactory());
         opts.setfSMCallerExecutorDisruptor(disruptor = new 
StripedDisruptor<>("test", "TestFSMDisruptor",
-            1024,
-            () -> new FSMCallerImpl.ApplyTask(),
-            1,
-            false,
-            false));
+                1024,
+                () -> new FSMCallerImpl.ApplyTask(),
+                1,
+                false,
+                false,
+                null));
         assertTrue(this.fsmCaller.init(opts));
     }
 
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/ReadOnlyServiceTest.java
 
b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/ReadOnlyServiceTest.java
index b5f84b829a..be3e148b3c 100644
--- 
a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/ReadOnlyServiceTest.java
+++ 
b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/ReadOnlyServiceTest.java
@@ -89,11 +89,12 @@ public class ReadOnlyServiceTest extends 
BaseIgniteAbstractTest {
         opts.setNode(this.node);
         opts.setRaftOptions(raftOptions);
         opts.setReadOnlyServiceDisruptor(disruptor = new 
StripedDisruptor<>("test", "TestReadOnlyServiceDisruptor",
-            1024,
-            () -> new ReadOnlyServiceImpl.ReadIndexEvent(),
-            1,
-            false,
-            false));
+                1024,
+                () -> new ReadOnlyServiceImpl.ReadIndexEvent(),
+                1,
+                false,
+                false,
+                null));
         NodeOptions nodeOptions = new NodeOptions();
         ExecutorService executor = JRaftUtils.createExecutor("test-executor", 
Utils.cpus());
         executors.add(executor);
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerTest.java
 
b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerTest.java
index d2661b7d0f..4049034280 100644
--- 
a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerTest.java
+++ 
b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerTest.java
@@ -102,11 +102,12 @@ public class LogManagerTest extends BaseStorageTest {
         opts.setLogStorage(this.logStorage);
         opts.setRaftOptions(raftOptions);
         opts.setLogManagerDisruptor(disruptor = new StripedDisruptor<>("test", 
"TestLogManagerDisruptor",
-            1024,
-            () -> new LogManagerImpl.StableClosureEvent(),
-            1,
-            false,
-            false));
+                1024,
+                () -> new LogManagerImpl.StableClosureEvent(),
+                1,
+                false,
+                false,
+                null));
         assertTrue(this.logManager.init(opts));
     }
 
diff --git a/modules/replicator/build.gradle b/modules/replicator/build.gradle
index 08d76b32be..81ce518d27 100644
--- a/modules/replicator/build.gradle
+++ b/modules/replicator/build.gradle
@@ -44,12 +44,14 @@ dependencies {
     integrationTestImplementation project(':ignite-placement-driver-api')
     integrationTestImplementation project(':ignite-network-api')
     integrationTestImplementation project(':ignite-cluster-management')
+    integrationTestImplementation project(':ignite-metrics')
     integrationTestImplementation testFixtures(project)
     integrationTestImplementation testFixtures(project(':ignite-core'))
     integrationTestImplementation 
testFixtures(project(':ignite-configuration'))
     integrationTestImplementation testFixtures(project(':ignite-network'))
     integrationTestImplementation 
testFixtures(project(':ignite-placement-driver-api'))
     integrationTestImplementation 
testFixtures(project(':ignite-failure-handler'))
+    integrationTestImplementation testFixtures(project(':ignite-metrics'))
 
     testImplementation testFixtures(project(':ignite-core'))
     testImplementation testFixtures(project(':ignite-placement-driver-api'))
diff --git 
a/modules/replicator/src/integrationTest/java/org/apache/ignite/internal/replicator/ItPlacementDriverReplicaSideTest.java
 
b/modules/replicator/src/integrationTest/java/org/apache/ignite/internal/replicator/ItPlacementDriverReplicaSideTest.java
index 98f68d570f..28d9bc8aee 100644
--- 
a/modules/replicator/src/integrationTest/java/org/apache/ignite/internal/replicator/ItPlacementDriverReplicaSideTest.java
+++ 
b/modules/replicator/src/integrationTest/java/org/apache/ignite/internal/replicator/ItPlacementDriverReplicaSideTest.java
@@ -64,6 +64,7 @@ import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.TestClockService;
 import org.apache.ignite.internal.lang.IgniteTriConsumer;
 import org.apache.ignite.internal.lang.NodeStoppingException;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NetworkMessageHandler;
 import org.apache.ignite.internal.network.StaticNodeFinder;
@@ -170,6 +171,7 @@ public class ItPlacementDriverReplicaSideTest extends 
IgniteAbstractTest {
 
             var raftManager = new Loza(
                     clusterService,
+                    new NoOpMetricManager(),
                     raftConfiguration,
                     workDir.resolve(nodeName + "_loza"),
                     clock,
diff --git a/modules/runner/build.gradle b/modules/runner/build.gradle
index 6db1d35296..aae26f8d83 100644
--- a/modules/runner/build.gradle
+++ b/modules/runner/build.gradle
@@ -174,6 +174,7 @@ dependencies {
     integrationTestImplementation 
testFixtures(project(':ignite-placement-driver-api'))
     integrationTestImplementation testFixtures(project(':ignite-jdbc'))
     integrationTestImplementation 
testFixtures(project(':ignite-failure-handler'))
+    integrationTestImplementation testFixtures(project(':ignite-metrics:'))
     integrationTestImplementation libs.jetbrains.annotations
     integrationTestImplementation libs.awaitility
     integrationTestImplementation libs.rocksdb.jni
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/ItDistributedConfigurationPropertiesTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/ItDistributedConfigurationPropertiesTest.java
index 048c70ca47..a8c311b84e 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/ItDistributedConfigurationPropertiesTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/ItDistributedConfigurationPropertiesTest.java
@@ -60,6 +60,7 @@ import 
org.apache.ignite.internal.metastorage.MetaStorageManager;
 import 
org.apache.ignite.internal.metastorage.configuration.MetaStorageConfiguration;
 import org.apache.ignite.internal.metastorage.impl.MetaStorageManagerImpl;
 import 
org.apache.ignite.internal.metastorage.server.SimpleInMemoryKeyValueStorage;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
 import org.apache.ignite.internal.network.utils.ClusterServiceTestUtils;
@@ -155,7 +156,13 @@ public class ItDistributedConfigurationPropertiesTest 
extends BaseIgniteAbstract
 
             var raftGroupEventsClientListener = new 
RaftGroupEventsClientListener();
 
-            raftManager = new Loza(clusterService, raftConfiguration, workDir, 
clock, raftGroupEventsClientListener);
+            raftManager = new Loza(
+                    clusterService,
+                    new NoOpMetricManager(),
+                    raftConfiguration,
+                    workDir, clock,
+                    raftGroupEventsClientListener
+            );
 
             var clusterStateStorage = new TestClusterStateStorage();
             var logicalTopology = new LogicalTopologyImpl(clusterStateStorage);
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItDistributedConfigurationStorageTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItDistributedConfigurationStorageTest.java
index a44ded2b20..ce8d0f5dd8 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItDistributedConfigurationStorageTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItDistributedConfigurationStorageTest.java
@@ -50,6 +50,7 @@ import 
org.apache.ignite.internal.metastorage.MetaStorageManager;
 import 
org.apache.ignite.internal.metastorage.configuration.MetaStorageConfiguration;
 import org.apache.ignite.internal.metastorage.impl.MetaStorageManagerImpl;
 import 
org.apache.ignite.internal.metastorage.server.SimpleInMemoryKeyValueStorage;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
 import org.apache.ignite.internal.network.utils.ClusterServiceTestUtils;
@@ -126,7 +127,14 @@ public class ItDistributedConfigurationStorageTest extends 
BaseIgniteAbstractTes
 
             var raftGroupEventsClientListener = new 
RaftGroupEventsClientListener();
 
-            raftManager = new Loza(clusterService, raftConfiguration, workDir, 
clock, raftGroupEventsClientListener);
+            raftManager = new Loza(
+                    clusterService,
+                    new NoOpMetricManager(),
+                    raftConfiguration,
+                    workDir,
+                    clock,
+                    raftGroupEventsClientListener
+            );
 
             var clusterStateStorage = new TestClusterStateStorage();
             var logicalTopology = new LogicalTopologyImpl(clusterStateStorage);
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 c2b9b80c29..b88f8d3b99 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
@@ -139,7 +139,8 @@ import org.apache.ignite.internal.metastorage.dsl.Operation;
 import org.apache.ignite.internal.metastorage.impl.MetaStorageManagerImpl;
 import 
org.apache.ignite.internal.metastorage.server.persistence.RocksDbKeyValueStorage;
 import org.apache.ignite.internal.metastorage.server.raft.MetastorageGroupId;
-import org.apache.ignite.internal.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.MetricManagerImpl;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.MessagingService;
 import org.apache.ignite.internal.network.NettyBootstrapFactory;
 import org.apache.ignite.internal.network.NettyWorkersRegistrar;
@@ -353,7 +354,7 @@ public class ItIgniteNodeRestartTest extends 
BaseIgniteRestartTest {
 
         var raftGroupEventsClientListener = new 
RaftGroupEventsClientListener();
 
-        var raftMgr = new Loza(clusterSvc, raftConfiguration, dir, 
hybridClock, raftGroupEventsClientListener);
+        var raftMgr = new Loza(clusterSvc, new NoOpMetricManager(), 
raftConfiguration, dir, hybridClock, raftGroupEventsClientListener);
 
         var clusterStateStorage = new 
RocksDbClusterStateStorage(dir.resolve("cmg"), name);
 
@@ -632,7 +633,7 @@ public class ItIgniteNodeRestartTest extends 
BaseIgniteRestartTest {
                 lowWatermark
         );
 
-        var metricManager = new MetricManager();
+        var metricManager = new MetricManagerImpl();
 
         SqlQueryProcessor qryEngine = new SqlQueryProcessor(
                 registry,
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItRaftCommandLeftInLogUntilRestartTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItRaftCommandLeftInLogUntilRestartTest.java
index 620b143eeb..5e54b3dea0 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItRaftCommandLeftInLogUntilRestartTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItRaftCommandLeftInLogUntilRestartTest.java
@@ -249,7 +249,8 @@ public class ItRaftCommandLeftInLogUntilRestartTest extends 
ClusterPerClassInteg
                 () -> new ApplyTask(),
                 1,
                 false,
-                false
+                false,
+                null
         ) {
             @Override
             public RingBuffer<ApplyTask> subscribe(NodeId group, 
EventHandler<ApplyTask> handler,
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 2dfee695f7..c90b014454 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
@@ -133,6 +133,7 @@ import 
org.apache.ignite.internal.metastorage.impl.MetaStorageManagerImpl;
 import 
org.apache.ignite.internal.metastorage.server.persistence.RocksDbKeyValueStorage;
 import org.apache.ignite.internal.metastorage.server.raft.MetastorageGroupId;
 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;
 import org.apache.ignite.internal.network.ChannelType;
@@ -418,7 +419,7 @@ public class IgniteImpl implements Ignite {
 
         vaultMgr = createVault(workDir);
 
-        metricManager = new MetricManager();
+        metricManager = new MetricManagerImpl();
 
         ConfigurationModules modules = 
loadConfigurationModules(serviceProviderClassLoader);
 
@@ -492,6 +493,7 @@ public class IgniteImpl implements Ignite {
 
         raftMgr = new Loza(
                 clusterSvc,
+                metricManager,
                 raftConfiguration,
                 workDir,
                 clock,
@@ -1237,6 +1239,11 @@ public class IgniteImpl implements Ignite {
         return failureProcessor;
     }
 
+    @TestOnly
+    public MetricManager metricManager() {
+        return metricManager;
+    }
+
     /** {@inheritDoc} */
     @Override
     public IgniteTransactions transactions() {
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ExecutionServiceImplTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ExecutionServiceImplTest.java
index de88550306..5c5e170041 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ExecutionServiceImplTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ExecutionServiceImplTest.java
@@ -81,7 +81,7 @@ import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.TestClockService;
 import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.lang.RunnableX;
-import org.apache.ignite.internal.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.network.ClusterNodeImpl;
 import org.apache.ignite.internal.network.NetworkMessage;
 import org.apache.ignite.internal.sql.engine.InternalSqlRow;
@@ -191,8 +191,15 @@ public class ExecutionServiceImplTest extends 
BaseIgniteAbstractTest {
     public void init() {
         testCluster = new TestCluster();
         executionServices = 
nodeNames.stream().map(this::create).collect(Collectors.toList());
-        prepareService = new PrepareServiceImpl("test", 0, 
CaffeineCacheFactory.INSTANCE, null, PLANNING_TIMEOUT, PLANNING_THREAD_COUNT,
-                new MetricManager());
+        prepareService = new PrepareServiceImpl(
+                "test",
+                0,
+                CaffeineCacheFactory.INSTANCE,
+                null,
+                PLANNING_TIMEOUT,
+                PLANNING_THREAD_COUNT,
+                new MetricManagerImpl()
+        );
         parserService = new ParserServiceImpl();
 
         prepareService.start();
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java
index 8bc31f96e5..4194a187f1 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java
@@ -76,7 +76,7 @@ import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.TestClockService;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
-import org.apache.ignite.internal.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.sql.engine.SqlQueryProcessor;
 import org.apache.ignite.internal.sql.engine.exec.ExecutableTable;
 import org.apache.ignite.internal.sql.engine.exec.ExecutableTableRegistry;
@@ -624,7 +624,7 @@ public class TestBuilders {
             var parserService = new ParserServiceImpl();
             var prepareService = new PrepareServiceImpl(clusterName, 0, 
CaffeineCacheFactory.INSTANCE,
                     new DdlSqlToCommandConverter(), PLANNING_TIMEOUT, 
PLANNING_THREAD_COUNT,
-                    mock(MetricManager.class));
+                    mock(MetricManagerImpl.class));
 
             Map<String, List<String>> owningNodesByTableName = new HashMap<>();
             for (Entry<String, Map<String, ScannableTable>> entry : 
nodeName2tableName2table.entrySet()) {
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 035fdb0a83..c7933d3828 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
@@ -33,7 +33,7 @@ import org.apache.calcite.plan.volcano.VolcanoPlanner;
 import org.apache.calcite.plan.volcano.VolcanoTimeoutException;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.RelVisitor;
-import org.apache.ignite.internal.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
 import org.apache.ignite.internal.sql.engine.prepare.IgnitePlanner;
 import org.apache.ignite.internal.sql.engine.prepare.PlanningContext;
@@ -65,7 +65,7 @@ public class PlannerTimeoutTest extends AbstractPlannerTest {
         BaseQueryContext ctx = 
baseQueryContext(Collections.singletonList(schema), null);
 
         PrepareService prepareService = new PrepareServiceImpl("test", 0,
-                CaffeineCacheFactory.INSTANCE, null, plannerTimeout, 1, new 
MetricManager());
+                CaffeineCacheFactory.INSTANCE, null, plannerTimeout, 1, new 
MetricManagerImpl());
         prepareService.start();
         try {
             ParserService parserService = new ParserServiceImpl();
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 0546995ff2..1527410a57 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
@@ -36,7 +36,7 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.tools.Frameworks;
-import org.apache.ignite.internal.metrics.MetricManager;
+import org.apache.ignite.internal.metrics.MetricManagerImpl;
 import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
 import 
org.apache.ignite.internal.sql.engine.prepare.ddl.DdlSqlToCommandConverter;
 import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
@@ -293,7 +293,7 @@ public class PrepareServiceImplTest extends 
BaseIgniteAbstractTest {
 
     private static PrepareService createPlannerService() {
         PrepareService service = new PrepareServiceImpl("test", 1_000, 
CaffeineCacheFactory.INSTANCE,
-                mock(DdlSqlToCommandConverter.class), 5_000, 2, 
mock(MetricManager.class));
+                mock(DdlSqlToCommandConverter.class), 5_000, 2, 
mock(MetricManagerImpl.class));
 
         createdServices.add(service);
 
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 b57a2f9f20..352e02d69f 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 java.util.Collections;
 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.sql.engine.framework.TestBuilders;
 import org.apache.ignite.internal.sql.engine.planner.AbstractPlannerTest;
@@ -46,7 +47,7 @@ public class PlanningCacheMetricsTest extends 
AbstractPlannerTest {
 
     @Test
     public void plannerCacheStatisticsTest() throws Exception {
-        MetricManager metricManager = new MetricManager();
+        MetricManager metricManager = new MetricManagerImpl();
         // Run clean up tasks in the current thread, so no eviction event is 
delayed.
         CacheFactory cacheFactory = CaffeineCacheFactory.create(Runnable::run);
         PrepareService prepareService = new PrepareServiceImpl("test", 2, 
cacheFactory, null, 15_000L, 2, metricManager);
diff --git a/modules/table/build.gradle b/modules/table/build.gradle
index a9cce38262..327a2b3366 100644
--- a/modules/table/build.gradle
+++ b/modules/table/build.gradle
@@ -109,6 +109,7 @@ dependencies {
     
testFixturesImplementation(testFixtures(project(':ignite-placement-driver-api')))
     testFixturesImplementation(testFixtures(project(':ignite-low-watermark')))
     
testFixturesImplementation(testFixtures(project(':ignite-failure-handler')))
+    testFixturesImplementation(testFixtures(project(':ignite-metrics')))
     testFixturesImplementation libs.jetbrains.annotations
     testFixturesImplementation libs.fastutil.core
     testFixturesImplementation libs.mockito.core
@@ -137,6 +138,7 @@ dependencies {
     integrationTestImplementation project(':ignite-sql-engine')
     integrationTestImplementation project(':ignite-failure-handler')
     integrationTestImplementation project(':ignite-low-watermark')
+    integrationTestImplementation project(':ignite-metrics')
     integrationTestImplementation(testFixtures(project))
     integrationTestImplementation(testFixtures(project(':ignite-api')))
     integrationTestImplementation(testFixtures(project(':ignite-core')))
@@ -154,6 +156,7 @@ dependencies {
     integrationTestImplementation(testFixtures(project(':ignite-runner')))
     
integrationTestImplementation(testFixtures(project(':ignite-low-watermark')))
     
integrationTestImplementation(testFixtures(project(':ignite-failure-handler')))
+    integrationTestImplementation(testFixtures(project(':ignite-metrics')))
     integrationTestImplementation libs.fastutil.core
     integrationTestImplementation libs.jetbrains.annotations
     integrationTestImplementation libs.calcite.core
diff --git 
a/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ReplicasSafeTimePropagationTest.java
 
b/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ReplicasSafeTimePropagationTest.java
index 223e1ae39b..4884d64653 100644
--- 
a/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ReplicasSafeTimePropagationTest.java
+++ 
b/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ReplicasSafeTimePropagationTest.java
@@ -46,6 +46,7 @@ import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.TestClockService;
 import org.apache.ignite.internal.lang.NodeStoppingException;
 import org.apache.ignite.internal.lang.SafeTimeReorderException;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
 import org.apache.ignite.internal.network.utils.ClusterServiceTestUtils;
@@ -262,6 +263,7 @@ public class ReplicasSafeTimePropagationTest extends 
IgniteAbstractTest {
 
             raftManager = new Loza(
                     clusterService,
+                    new NoOpMetricManager(),
                     raftConfiguration,
                     workDir.resolve(nodeName + "_loza"),
                     new HybridClockImpl(),
diff --git 
a/modules/table/src/integrationTest/java/org/apache/ignite/internal/rebalance/ItRebalanceDistributedTest.java
 
b/modules/table/src/integrationTest/java/org/apache/ignite/internal/rebalance/ItRebalanceDistributedTest.java
index 73b885de9b..0c742a9801 100644
--- 
a/modules/table/src/integrationTest/java/org/apache/ignite/internal/rebalance/ItRebalanceDistributedTest.java
+++ 
b/modules/table/src/integrationTest/java/org/apache/ignite/internal/rebalance/ItRebalanceDistributedTest.java
@@ -139,6 +139,7 @@ import 
org.apache.ignite.internal.metastorage.impl.MetaStorageManagerImpl;
 import org.apache.ignite.internal.metastorage.server.KeyValueStorage;
 import 
org.apache.ignite.internal.metastorage.server.SimpleInMemoryKeyValueStorage;
 import 
org.apache.ignite.internal.metastorage.server.persistence.RocksDbKeyValueStorage;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.DefaultMessagingService;
 import org.apache.ignite.internal.network.StaticNodeFinder;
@@ -1034,7 +1035,14 @@ public class ItRebalanceDistributedTest extends 
BaseIgniteAbstractTest {
 
             var raftGroupEventsClientListener = new 
RaftGroupEventsClientListener();
 
-            raftManager = spy(new Loza(clusterService, raftConfiguration, dir, 
hybridClock, raftGroupEventsClientListener));
+            raftManager = spy(new Loza(
+                    clusterService,
+                    new NoOpMetricManager(),
+                    raftConfiguration,
+                    dir,
+                    hybridClock,
+                    raftGroupEventsClientListener
+            ));
 
             var clusterStateStorage = new TestClusterStateStorage();
             var logicalTopology = new LogicalTopologyImpl(clusterStateStorage);
diff --git 
a/modules/table/src/testFixtures/java/org/apache/ignite/distributed/ItTxTestCluster.java
 
b/modules/table/src/testFixtures/java/org/apache/ignite/distributed/ItTxTestCluster.java
index 7f57021b55..a7b3fe44ab 100644
--- 
a/modules/table/src/testFixtures/java/org/apache/ignite/distributed/ItTxTestCluster.java
+++ 
b/modules/table/src/testFixtures/java/org/apache/ignite/distributed/ItTxTestCluster.java
@@ -83,6 +83,7 @@ import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.lowwatermark.LowWatermark;
 import org.apache.ignite.internal.lowwatermark.TestLowWatermark;
+import org.apache.ignite.internal.metrics.NoOpMetricManager;
 import org.apache.ignite.internal.network.ClusterService;
 import org.apache.ignite.internal.network.NodeFinder;
 import org.apache.ignite.internal.network.StaticNodeFinder;
@@ -388,6 +389,7 @@ public class ItTxTestCluster {
 
             var raftSrv = new Loza(
                     clusterService,
+                    new NoOpMetricManager(),
                     raftConfig,
                     workDir.resolve("node" + i),
                     clock

Reply via email to