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

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

commit 974f1a1ee7ef93df7576990922237b3f07565cb4
Author: Kirill Gusakov <[email protected]>
AuthorDate: Tue Nov 1 20:47:47 2022 +0400

    IGNITE-17989 Added Jvm memory usage metrics' source. Fixes #1288
    
    Signed-off-by: Slava Koptilin <[email protected]>
---
 .../cli/call/metric/ItMetricCallsTest.java         |   9 +-
 .../commands/metric/ItNodeMetricCommandTest.java   |   3 +-
 .../internal/rest/ItGeneratedRestClientTest.java   |   9 +-
 .../metrics/exporters/ItJvmMetricSourceTest.java   |  86 ++++++++++
 .../exporters/ItMetricExportersLoadingTest.java    |   2 +-
 .../metrics/exporters/TestSimpleExporter.java      |  77 +++++++++
 .../TestSimpleExporterConfigurationSchema.java     |  28 ++++
 .../internal/metrics/sources/JvmMetricSource.java  | 177 +++++++++++++++++++++
 .../metrics/sources/JvmMetricSourceTest.java       | 135 ++++++++++++++++
 .../org/apache/ignite/internal/app/IgniteImpl.java |   4 +
 10 files changed, 525 insertions(+), 5 deletions(-)

diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/call/metric/ItMetricCallsTest.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/call/metric/ItMetricCallsTest.java
index 1037927cff..4f07187407 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/call/metric/ItMetricCallsTest.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/call/metric/ItMetricCallsTest.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.cli.call.metric;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
 
 import jakarta.inject.Inject;
 import java.util.List;
@@ -28,6 +29,7 @@ import 
org.apache.ignite.internal.cli.call.node.metric.NodeMetricListCall;
 import org.apache.ignite.internal.cli.core.call.CallOutput;
 import org.apache.ignite.internal.cli.core.call.StringCallInput;
 import org.apache.ignite.rest.client.model.MetricSource;
+import org.hamcrest.MatcherAssert;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
 
@@ -51,8 +53,13 @@ class ItMetricCallsTest extends 
CallInitializedIntegrationTestBase {
 
         // Then
         assertThat(output.hasError()).isFalse();
+
+        List<MetricSource> expectedMetricSources = List.of(
+                new MetricSource().name("jvm").enabled(false)
+        );
+
         // And
-        assertThat(output.body()).isEmpty();
+        MatcherAssert.assertThat(output.body(), 
containsInAnyOrder(expectedMetricSources.toArray()));
     }
 
     @Test
diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/metric/ItNodeMetricCommandTest.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/metric/ItNodeMetricCommandTest.java
index 18d6aa8251..7842587a16 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/metric/ItNodeMetricCommandTest.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/metric/ItNodeMetricCommandTest.java
@@ -36,7 +36,8 @@ class ItNodeMetricCommandTest extends 
CliCommandTestInitializedIntegrationBase {
                 this::assertExitCodeIsZero,
                 this::assertErrOutputIsEmpty,
                 () -> assertOutputIs("Enabled metric sources:" + 
System.lineSeparator()
-                        + "Disabled metric sources:" + System.lineSeparator())
+                        + "Disabled metric sources:" + System.lineSeparator()
+                        + "jvm" + System.lineSeparator())
         );
     }
 
diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/rest/ItGeneratedRestClientTest.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/rest/ItGeneratedRestClientTest.java
index 72a18a67e4..ebe2ab44cd 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/rest/ItGeneratedRestClientTest.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/rest/ItGeneratedRestClientTest.java
@@ -22,8 +22,8 @@ import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.testNodeN
 import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
@@ -57,6 +57,7 @@ import org.apache.ignite.rest.client.invoker.ApiException;
 import org.apache.ignite.rest.client.invoker.Configuration;
 import org.apache.ignite.rest.client.model.ClusterState;
 import org.apache.ignite.rest.client.model.InitCommand;
+import org.apache.ignite.rest.client.model.MetricSource;
 import org.apache.ignite.rest.client.model.NodeState;
 import org.apache.ignite.rest.client.model.Problem;
 import org.junit.jupiter.api.AfterEach;
@@ -327,7 +328,11 @@ public class ItGeneratedRestClientTest {
 
     @Test
     void nodeMetricList() throws ApiException {
-        assertThat(nodeMetricApi.listNodeMetrics(), empty());
+        List<MetricSource> metricSources = List.of(
+                new MetricSource().name("jvm").enabled(false)
+        );
+
+        assertThat(nodeMetricApi.listNodeMetrics(), 
containsInAnyOrder(metricSources.toArray()));
     }
 
     @Test
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
new file mode 100644
index 0000000000..a931afbeed
--- /dev/null
+++ 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/ItJvmMetricSourceTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+import 
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.configuration.MetricConfiguration;
+import org.apache.ignite.internal.metrics.sources.JvmMetricSource;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * Suite to test, that enabled by default jvm metrics aren't broken.
+ */
+@ExtendWith(ConfigurationExtension.class)
+public class ItJvmMetricSourceTest {
+    @InjectConfiguration(
+            value = "mock.exporters = {"
+                    + "simple = {exporterName = simple}"
+                    + "}",
+            polymorphicExtensions = {
+                    TestSimpleExporterConfigurationSchema.class
+            }
+    )
+    private MetricConfiguration simpleConfiguration;
+
+    @Test
+    public void testMemoryUsageMetric() throws Exception {
+        MetricManager metricManager = new MetricManager();
+
+        metricManager.configure(simpleConfiguration);
+
+        Map<String, MetricExporter> exporters = new HashMap<>();
+
+        TestSimpleExporter simpleExporter = new TestSimpleExporter();
+
+        exporters.put(simpleExporter.name(), simpleExporter);
+
+        metricManager.registerSource(new JvmMetricSource());
+
+        metricManager.start(exporters);
+
+        metricManager.enable("jvm");
+
+        var jvmMetrics = simpleExporter.pull().get("jvm");
+
+        assertPositiveLongValue(jvmMetrics.get("memory.heap.init"));
+        assertPositiveLongValue(jvmMetrics.get("memory.heap.used"));
+        assertPositiveLongValue(jvmMetrics.get("memory.heap.committed"));
+        assertPositiveLongValue(jvmMetrics.get("memory.heap.max"));
+
+
+        assertNotNull(jvmMetrics.get("memory.non-heap.init"));
+        assertNotNull(jvmMetrics.get("memory.non-heap.used"));
+        assertNotNull(jvmMetrics.get("memory.non-heap.committed"));
+        assertNotNull(jvmMetrics.get("memory.non-heap.max"));
+
+        metricManager.stop();
+    }
+
+    private void assertPositiveLongValue(String metric) {
+        assertThat(Long.parseLong(metric), greaterThan(0L));
+    }
+}
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 500582fa28..181a95fde8 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
@@ -33,7 +33,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
 /**
  * Integration test for metrics' exporters loading.
  */
-@ExtendWith({ConfigurationExtension.class})
+@ExtendWith(ConfigurationExtension.class)
 public class ItMetricExportersLoadingTest {
     @InjectConfiguration(
             value = "mock.exporters = {"
diff --git 
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestSimpleExporter.java
 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestSimpleExporter.java
new file mode 100644
index 0000000000..4f3ed8eb5d
--- /dev/null
+++ 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestSimpleExporter.java
@@ -0,0 +1,77 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.ignite.internal.metrics.Metric;
+import org.apache.ignite.internal.metrics.MetricSet;
+
+/**
+ * Simple metrics exporter for test purposes.
+ * It has a trivial API to receive all available metrics as map: (sourceName 
-> [(metricName -> metricValue), ...])
+ */
+public class TestSimpleExporter extends 
BasicMetricExporter<TestSimpleExporterView> {
+    /** Exporter name. */
+    static final String EXPORTER_NAME = "simple";
+
+    /**
+     * Returns all metrics as map (sourceName -> [(metricName -> metricValue), 
...]).
+     *
+     * @return All available metrics.
+     */
+    Map<String, Map<String, String>> pull() {
+        Map<String, Map<String, String>> results = new HashMap<>();
+
+        for (MetricSet metricSet : metrics().get1().values()) {
+            Map<String, String> metricSetMetrics = new HashMap<>();
+
+            for (Metric metric : metricSet) {
+                metricSetMetrics.put(metric.name(), metric.getValueAsString());
+            }
+
+            results.put(metricSet.name(), metricSetMetrics);
+        }
+
+        return results;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void stop() {
+        // No-op
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String name() {
+        return EXPORTER_NAME;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void addMetricSet(MetricSet metricSet) {
+        // No-op
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void removeMetricSet(String metricSetName) {
+        // No-op
+    }
+}
diff --git 
a/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestSimpleExporterConfigurationSchema.java
 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestSimpleExporterConfigurationSchema.java
new file mode 100644
index 0000000000..69fed37863
--- /dev/null
+++ 
b/modules/metrics/src/integrationTest/java/org/apache/ignite/internal/metrics/exporters/TestSimpleExporterConfigurationSchema.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+import org.apache.ignite.configuration.annotation.PolymorphicConfigInstance;
+import 
org.apache.ignite.internal.metrics.exporters.configuration.ExporterConfigurationSchema;
+
+/**
+ * Empty configuration for {@link TestSimpleExporter}.
+ */
+@PolymorphicConfigInstance(TestSimpleExporter.EXPORTER_NAME)
+public class TestSimpleExporterConfigurationSchema extends 
ExporterConfigurationSchema {
+}
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
new file mode 100644
index 0000000000..908d94c44f
--- /dev/null
+++ 
b/modules/metrics/src/main/java/org/apache/ignite/internal/metrics/sources/JvmMetricSource.java
@@ -0,0 +1,177 @@
+/*
+ * 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.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryUsage;
+import java.util.HashMap;
+import java.util.function.Supplier;
+import org.apache.ignite.internal.metrics.LongGauge;
+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;
+
+/**
+ * Metric source, which provides JVM metrics like memory usage, gc stats etc.
+ */
+public class JvmMetricSource implements MetricSource {
+
+    /** Source name. */
+    private static final String SOURCE_NAME = "jvm";
+
+    /** Timeout for memory usage stats cache. */
+    private static final long MEMORY_USAGE_CACHE_TIMEOUT = 1000;
+
+    /** JVM standard MXBean to provide information about memory usage. */
+    private final MemoryMXBean memoryMxBean;
+
+    /** True, if source is enabled, false otherwise. */
+    private boolean enabled;
+
+    /**
+     * Constructor.
+     *
+     * @param memoryMxBean MXBean implementation to receive memory info.
+     */
+    JvmMetricSource(MemoryMXBean memoryMxBean) {
+        this.memoryMxBean = memoryMxBean;
+    }
+
+    /**
+     * Constructs new metric source with standard MemoryMXBean as metric 
provider.
+     */
+    public JvmMetricSource() {
+        memoryMxBean = ManagementFactory.getMemoryMXBean();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String name() {
+        return SOURCE_NAME;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public synchronized @Nullable MetricSet enable() {
+        var metrics = new HashMap<String, Metric>();
+
+        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()));
+        metrics.put("memory.heap.used",
+                new LongGauge("memory.heap.used",
+                        "Current used amount of heap memory",
+                        () -> heapMemoryUsage.get().getUsed()));
+        metrics.put("memory.heap.committed",
+                new LongGauge("memory.heap.committed",
+                        "Committed amount of heap memory",
+                        () -> heapMemoryUsage.get().getCommitted()));
+        metrics.put("memory.heap.max",
+                new LongGauge("memory.heap.max",
+                        "Maximum amount of heap memory",
+                        () -> 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()));
+        metrics.put("memory.non-heap.used",
+                new LongGauge("memory.non-heap.used",
+                        "Used amount of non-heap memory",
+                        () -> nonHeapMemoryUsage.get().getUsed()));
+        metrics.put("memory.non-heap.committed",
+                new LongGauge("memory.non-heap.committed",
+                        "Committed amount of non-heap memory",
+                        () -> nonHeapMemoryUsage.get().getCommitted()));
+        metrics.put("memory.non-heap.max",
+                new LongGauge("memory.non-heap.max",
+                        "Maximum amount of non-heap memory",
+                        () -> nonHeapMemoryUsage.get().getMax()));
+
+        enabled = true;
+
+        return new MetricSet(SOURCE_NAME, metrics);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public synchronized void disable() {
+        enabled = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public synchronized boolean enabled() {
+        return enabled;
+    }
+
+    /**
+     * Simple wrapper for memoization memory usage stats.
+     */
+    private static class CachedMemoryUsage {
+        /** Source of memory usage stats. */
+        private final Supplier<MemoryUsage> source;
+
+        /** Timeout of cache in ms. */
+        private final long timeout;
+
+        /** Last update time in ms. */
+        private volatile long lastUpdateTime;
+
+        /** Last received from source value. */
+        private volatile MemoryUsage currentVal;
+
+        /**
+         * Constructor.
+         *
+         * @param source Source of memory usage data.
+         * @param timeout Cache timeout in millis.
+         */
+        private CachedMemoryUsage(Supplier<MemoryUsage> source, long timeout) {
+            this.source = source;
+            this.timeout = timeout;
+
+            update();
+        }
+
+        /**
+         * Returns current cached value.
+         *
+         * @return Current cached value.
+         */
+        private MemoryUsage get() {
+            if ((System.currentTimeMillis() - lastUpdateTime) > timeout) {
+                update();
+            }
+
+            return currentVal;
+        }
+
+        /**
+         * Update cache value and last update time.
+         */
+        private synchronized void update() {
+            currentVal = source.get();
+
+            lastUpdateTime = System.currentTimeMillis();
+        }
+    }
+}
diff --git 
a/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/sources/JvmMetricSourceTest.java
 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/sources/JvmMetricSourceTest.java
new file mode 100644
index 0000000000..98ba6de4d4
--- /dev/null
+++ 
b/modules/metrics/src/test/java/org/apache/ignite/internal/metrics/sources/JvmMetricSourceTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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 static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryUsage;
+import java.util.concurrent.locks.LockSupport;
+import javax.management.ObjectName;
+import org.apache.ignite.internal.metrics.LongMetric;
+import org.junit.jupiter.api.Test;
+
+/** Tests for jvm system metrics. */
+public class JvmMetricSourceTest {
+    @Test
+    void testMemoryMetric() {
+        var memoryBean = new MemoryBean(5, 15, 20, 90,
+                100, 115, 120, 200);
+        var metricSource = new JvmMetricSource(memoryBean);
+
+        var metricSet = metricSource.enable();
+
+        assertEquals(memoryBean.heapInit, 
metricSet.<LongMetric>get("memory.heap.init").value());
+        assertEquals(memoryBean.heapUsed, 
metricSet.<LongMetric>get("memory.heap.used").value());
+        assertEquals(memoryBean.heapCommitted, 
metricSet.<LongMetric>get("memory.heap.committed").value());
+        assertEquals(memoryBean.heapMax, 
metricSet.<LongMetric>get("memory.heap.max").value());
+
+        assertEquals(memoryBean.nonHeapInit, 
metricSet.<LongMetric>get("memory.non-heap.init").value());
+        assertEquals(memoryBean.nonHeapUsed, 
metricSet.<LongMetric>get("memory.non-heap.used").value());
+        assertEquals(memoryBean.nonHeapCommitted, 
metricSet.<LongMetric>get("memory.non-heap.committed").value());
+        assertEquals(memoryBean.nonHeapMax, 
metricSet.<LongMetric>get("memory.non-heap.max").value());
+
+        memoryBean.heapUsed += 1;
+        memoryBean.heapCommitted += 1;
+
+        memoryBean.nonHeapUsed += 1;
+        memoryBean.nonHeapCommitted += 1;
+
+        // wait for memory usage cache update
+        while (metricSet.<LongMetric>get("memory.heap.used").value() != 
memoryBean.heapUsed) {
+            LockSupport.parkNanos(100_000_000);
+        }
+
+        assertEquals(memoryBean.heapInit, 
metricSet.<LongMetric>get("memory.heap.init").value());
+        assertEquals(memoryBean.heapUsed, 
metricSet.<LongMetric>get("memory.heap.used").value());
+        assertEquals(memoryBean.heapCommitted, 
metricSet.<LongMetric>get("memory.heap.committed").value());
+        assertEquals(memoryBean.heapMax, 
metricSet.<LongMetric>get("memory.heap.max").value());
+
+        assertEquals(memoryBean.nonHeapInit, 
metricSet.<LongMetric>get("memory.non-heap.init").value());
+        assertEquals(memoryBean.nonHeapUsed, 
metricSet.<LongMetric>get("memory.non-heap.used").value());
+        assertEquals(memoryBean.nonHeapCommitted, 
metricSet.<LongMetric>get("memory.non-heap.committed").value());
+        assertEquals(memoryBean.nonHeapMax, 
metricSet.<LongMetric>get("memory.non-heap.max").value());
+    }
+
+    /**
+     * Test implementation of {@link java.lang.management.MemoryMXBean},
+     * which open for mutations in scope of the current test.
+     *
+     */
+    private class MemoryBean implements MemoryMXBean {
+        public long heapInit;
+        public long heapUsed;
+        public long heapCommitted;
+        public long heapMax;
+
+        public long nonHeapInit;
+        public long nonHeapUsed;
+        public long nonHeapCommitted;
+        public long nonHeapMax;
+
+        private MemoryBean(long heapInit, long heapUsed, long heapCommitted, 
long heapMax,
+                long nonHeapInit, long nonHeapUsed, long nonHeapCommitted, 
long nonHeapMax) {
+            this.heapInit = heapInit;
+            this.heapUsed = heapUsed;
+            this.heapCommitted = heapCommitted;
+            this.heapMax = heapMax;
+
+            this.nonHeapInit = nonHeapInit;
+            this.nonHeapUsed = nonHeapUsed;
+            this.nonHeapCommitted = nonHeapCommitted;
+            this.nonHeapMax = nonHeapMax;
+        }
+
+        @Override
+        public int getObjectPendingFinalizationCount() {
+            throw new UnsupportedOperationException("Not supported in test 
implementation");
+        }
+
+        @Override
+        public MemoryUsage getHeapMemoryUsage() {
+            return new MemoryUsage(heapInit, heapUsed, heapCommitted, heapMax);
+        }
+
+        @Override
+        public MemoryUsage getNonHeapMemoryUsage() {
+            return new MemoryUsage(nonHeapInit, nonHeapUsed, nonHeapCommitted, 
nonHeapMax);
+        }
+
+        @Override
+        public boolean isVerbose() {
+            throw new UnsupportedOperationException("Not supported in test 
implementation");
+        }
+
+        @Override
+        public void setVerbose(boolean value) {
+            throw new UnsupportedOperationException("Not supported in test 
implementation");
+        }
+
+        @Override
+        public void gc() {
+            throw new UnsupportedOperationException("Not supported in test 
implementation");
+        }
+
+        @Override
+        public ObjectName getObjectName() {
+            throw new UnsupportedOperationException("Not supported in test 
implementation");
+        }
+    }
+}
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 45d099b1a7..233d11181b 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
@@ -63,6 +63,9 @@ import 
org.apache.ignite.internal.metastorage.server.persistence.RocksDbKeyValue
 import org.apache.ignite.internal.metrics.MetricManager;
 import org.apache.ignite.internal.metrics.configuration.MetricConfiguration;
 import org.apache.ignite.internal.metrics.rest.MetricRestFactory;
+import org.apache.ignite.internal.metrics.sources.JvmMetricSource;
+import org.apache.ignite.internal.network.configuration.NetworkConfiguration;
+import 
org.apache.ignite.internal.network.configuration.NetworkConfigurationSchema;
 import org.apache.ignite.internal.raft.Loza;
 import org.apache.ignite.internal.raft.configuration.RaftConfiguration;
 import 
org.apache.ignite.internal.raft.storage.impl.VolatileLogStorageFactoryCreator;
@@ -469,6 +472,7 @@ public class IgniteImpl implements Ignite {
      */
     public CompletableFuture<Ignite> start(@Language("HOCON") @Nullable String 
cfg) {
         try {
+            metricManager.registerSource(new JvmMetricSource());
 
             lifecycleManager.startComponent(longJvmPauseDetector);
 

Reply via email to