IGNITE-9305 Wrong off-heap size is reported for a node - Fixes #4593.

Signed-off-by: Dmitriy Pavlov <dpav...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/813f0977
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/813f0977
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/813f0977

Branch: refs/heads/ignite-gg-14206
Commit: 813f0977b14089dc5b3572a589e3e9716337134c
Parents: feb97c3
Author: pereslegin-pa <xxt...@gmail.com>
Authored: Wed Sep 26 20:04:56 2018 +0300
Committer: Dmitriy Pavlov <dpav...@apache.org>
Committed: Wed Sep 26 20:04:56 2018 +0300

----------------------------------------------------------------------
 .../apache/ignite/internal/IgniteKernal.java    | 257 ++++++++++++-------
 .../persistence/DataRegionMetricsImpl.java      |   6 -
 .../GridCacheDatabaseSharedManager.java         |   2 +-
 .../internal/GridNodeMetricsLogPdsSelfTest.java | 122 +++++++++
 .../internal/GridNodeMetricsLogSelfTest.java    | 113 +++++---
 .../IgniteBasicWithPersistenceTestSuite.java    |   3 +
 .../Cache/DataRegionMetricsTest.cs              |   1 -
 .../Cache/MemoryMetricsTest.cs                  |   1 -
 8 files changed, 377 insertions(+), 128 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/813f0977/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java 
b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 45e05ec..f07b83f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -127,6 +127,7 @@ import 
org.apache.ignite.internal.processors.cache.IgniteInternalCache;
 import 
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
 import org.apache.ignite.internal.processors.cache.mvcc.MvccProcessorImpl;
 import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
+import 
org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
 import 
org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor;
 import 
org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
 import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
@@ -1234,96 +1235,7 @@ public class IgniteKernal implements IgniteEx, 
IgniteMXBean, Externalizable {
                 private final DecimalFormat dblFmt = new DecimalFormat("#.##");
 
                 @Override public void run() {
-                    if (log.isInfoEnabled()) {
-                        try {
-                            ClusterMetrics m = cluster().localNode().metrics();
-
-                            double cpuLoadPct = m.getCurrentCpuLoad() * 100;
-                            double avgCpuLoadPct = m.getAverageCpuLoad() * 100;
-                            double gcPct = m.getCurrentGcCpuLoad() * 100;
-
-                            //Heap params
-                            long heapUsed = m.getHeapMemoryUsed();
-                            long heapMax = m.getHeapMemoryMaximum();
-
-                            long heapUsedInMBytes = heapUsed / 1024 / 1024;
-                            long heapCommInMBytes = m.getHeapMemoryCommitted() 
/ 1024 / 1024;
-
-                            double freeHeapPct = heapMax > 0 ? 
((double)((heapMax - heapUsed) * 100)) / heapMax : -1;
-
-                            //Non heap params
-                            long nonHeapUsed = m.getNonHeapMemoryUsed();
-                            long nonHeapMax = m.getNonHeapMemoryMaximum();
-
-                            long nonHeapUsedInMBytes = nonHeapUsed / 1024 / 
1024;
-                            long nonHeapCommInMBytes = 
m.getNonHeapMemoryCommitted() / 1024 / 1024;
-
-                            double freeNonHeapPct = nonHeapMax > 0 ? 
((double)((nonHeapMax - nonHeapUsed) * 100)) / nonHeapMax : -1;
-
-                            int hosts = 0;
-                            int nodes = 0;
-                            int cpus = 0;
-
-                            try {
-                                ClusterMetrics metrics = cluster().metrics();
-
-                                Collection<ClusterNode> nodes0 = 
cluster().nodes();
-
-                                hosts = U.neighborhood(nodes0).size();
-                                nodes = metrics.getTotalNodes();
-                                cpus = metrics.getTotalCpus();
-                            }
-                            catch (IgniteException ignore) {
-                                // No-op.
-                            }
-
-                            int loadedPages = 0;
-
-                            Collection<DataRegion> policies = 
ctx.cache().context().database().dataRegions();
-
-                            if (!F.isEmpty(policies)) {
-                                for (DataRegion memPlc : policies)
-                                    loadedPages += 
memPlc.pageMemory().loadedPages();
-                            }
-
-                            String id = U.id8(localNode().id());
-
-                            String msg = NL +
-                                "Metrics for local node (to disable set 
'metricsLogFrequency' to 0)" + NL +
-                                "    ^-- Node [id=" + id + (name() != null ? 
", name=" + name() : "") + ", uptime=" +
-                                getUpTimeFormatted() + "]" + NL +
-                                "    ^-- H/N/C [hosts=" + hosts + ", nodes=" + 
nodes + ", CPUs=" + cpus + "]" + NL +
-                                "    ^-- CPU [cur=" + 
dblFmt.format(cpuLoadPct) + "%, avg=" +
-                                dblFmt.format(avgCpuLoadPct) + "%, GC=" + 
dblFmt.format(gcPct) + "%]" + NL +
-                                "    ^-- PageMemory [pages=" + loadedPages + 
"]" + NL +
-                                "    ^-- Heap [used=" + 
dblFmt.format(heapUsedInMBytes) + "MB, free=" +
-                                dblFmt.format(freeHeapPct) + "%, comm=" + 
dblFmt.format(heapCommInMBytes) + "MB]" + NL +
-                                "    ^-- Non heap [used=" + 
dblFmt.format(nonHeapUsedInMBytes) + "MB, free=" +
-                                dblFmt.format(freeNonHeapPct) + "%, comm=" + 
dblFmt.format(nonHeapCommInMBytes) + "MB]" + NL +
-                                "    ^-- Outbound messages queue [size=" + 
m.getOutboundMessagesQueueSize() + "]" + NL +
-                                "    ^-- " + createExecutorDescription("Public 
thread pool", execSvc) + NL +
-                                "    ^-- " + createExecutorDescription("System 
thread pool", sysExecSvc);
-
-                            if (customExecSvcs != null) {
-                                StringBuilder customSvcsMsg = new 
StringBuilder();
-
-                                for (Map.Entry<String, ? extends 
ExecutorService> entry : customExecSvcs.entrySet()) {
-                                    customSvcsMsg.append(NL).append("    ^-- ")
-                                        
.append(createExecutorDescription(entry.getKey(), entry.getValue()));
-                                }
-
-                                msg = msg + customSvcsMsg;
-                            }
-
-                            if (log.isInfoEnabled())
-                                log.info(msg);
-
-                            
ctx.cache().context().database().dumpStatistics(log);
-                        }
-                        catch (IgniteClientDisconnectedException ignore) {
-                            // No-op.
-                        }
-                    }
+                    ackNodeMetrics(dblFmt, execSvc, sysExecSvc, 
customExecSvcs);
                 }
             }, metricsLogFreq, metricsLogFreq);
         }
@@ -2026,6 +1938,171 @@ public class IgniteKernal implements IgniteEx, 
IgniteMXBean, Externalizable {
     }
 
     /**
+     * Logs out node metrics.
+     *
+     * @param dblFmt Decimal format.
+     * @param execSvc Executor service.
+     * @param sysExecSvc System executor service.
+     * @param customExecSvcs Custom named executors.
+     */
+    private void ackNodeMetrics(DecimalFormat dblFmt,
+        ExecutorService execSvc,
+        ExecutorService sysExecSvc,
+        Map<String, ? extends ExecutorService> customExecSvcs
+    ) {
+        if (!log.isInfoEnabled())
+            return;
+
+        try {
+            ClusterMetrics m = cluster().localNode().metrics();
+
+            final int MByte = 1024 * 1024;
+
+            double cpuLoadPct = m.getCurrentCpuLoad() * 100;
+            double avgCpuLoadPct = m.getAverageCpuLoad() * 100;
+            double gcPct = m.getCurrentGcCpuLoad() * 100;
+
+            // Heap params.
+            long heapUsed = m.getHeapMemoryUsed();
+            long heapMax = m.getHeapMemoryMaximum();
+
+            long heapUsedInMBytes = heapUsed / MByte;
+            long heapCommInMBytes = m.getHeapMemoryCommitted() / MByte;
+
+            double freeHeapPct = heapMax > 0 ? ((double)((heapMax - heapUsed) 
* 100)) / heapMax : -1;
+
+            int hosts = 0;
+            int nodes = 0;
+            int cpus = 0;
+
+            try {
+                ClusterMetrics metrics = cluster().metrics();
+
+                Collection<ClusterNode> nodes0 = cluster().nodes();
+
+                hosts = U.neighborhood(nodes0).size();
+                nodes = metrics.getTotalNodes();
+                cpus = metrics.getTotalCpus();
+            }
+            catch (IgniteException ignore) {
+                // No-op.
+            }
+
+            int loadedPages = 0;
+
+            // Off-heap params.
+            Collection<DataRegion> regions = 
ctx.cache().context().database().dataRegions();
+
+            StringBuilder dataRegionsInfo = new StringBuilder();
+            StringBuilder pdsRegionsInfo = new StringBuilder();
+
+            long offHeapUsedSummary = 0;
+            long offHeapMaxSummary = 0;
+            long offHeapCommSummary = 0;
+            long pdsUsedSummary = 0;
+
+            boolean persistenceDisabled = true;
+
+            if (!F.isEmpty(regions)) {
+                for (DataRegion region : regions) {
+                    long pagesCnt = region.pageMemory().loadedPages();
+
+                    long offHeapUsed = region.pageMemory().systemPageSize() * 
pagesCnt;
+                    long offHeapMax = region.config().getMaxSize();
+                    long offHeapComm = region.memoryMetrics().getOffHeapSize();
+
+                    long offHeapUsedInMBytes = offHeapUsed / MByte;
+                    long offHeapCommInMBytes = offHeapComm / MByte;
+
+                    double freeOffHeapPct = offHeapMax > 0 ?
+                        ((double)((offHeapMax - offHeapUsed) * 100)) / 
offHeapMax : -1;
+
+                    offHeapUsedSummary += offHeapUsed;
+                    offHeapMaxSummary += offHeapMax;
+                    offHeapCommSummary += offHeapComm;
+                    loadedPages += pagesCnt;
+
+                    dataRegionsInfo.append("    ^--   ")
+                        .append(region.config().getName()).append(" region")
+                        .append(" 
[used=").append(dblFmt.format(offHeapUsedInMBytes))
+                        .append("MB, 
free=").append(dblFmt.format(freeOffHeapPct))
+                        .append("%, 
comm=").append(dblFmt.format(offHeapCommInMBytes)).append("MB]")
+                        .append(NL);
+
+                    if (region.config().isPersistenceEnabled()) {
+                        long pdsUsed = 
region.memoryMetrics().getTotalAllocatedSize();
+                        long pdsUsedMBytes = pdsUsed / MByte;
+
+                        pdsUsedSummary += pdsUsed;
+
+                        // TODO 
https://issues.apache.org/jira/browse/IGNITE-9455
+                        // TODO Print actual value for meta store region when 
issue will be fixed.
+                        boolean metastore =
+                            
GridCacheDatabaseSharedManager.METASTORE_DATA_REGION_NAME.equals(region.config().getName());
+
+                        String pdsUsedSize = metastore ? "unknown" : 
dblFmt.format(pdsUsedMBytes) + "MB";
+
+                        pdsRegionsInfo.append("    ^--   ")
+                            .append(region.config().getName()).append(" 
region")
+                            .append(" [used=").append(pdsUsedSize).append("]")
+                            .append(NL);
+
+                        persistenceDisabled = false;
+                    }
+                }
+            }
+
+            long offHeapUsedInMBytes = offHeapUsedSummary / MByte;
+            long offHeapCommInMBytes = offHeapCommSummary / MByte;
+            long pdsUsedMBytes = pdsUsedSummary / MByte;
+
+            double freeOffHeapPct = offHeapMaxSummary > 0 ?
+                ((double)((offHeapMaxSummary - offHeapUsedSummary) * 100)) / 
offHeapMaxSummary : -1;
+
+            String pdsInfo = persistenceDisabled ? "" :
+                "    ^-- Ignite persistence [used=" + 
dblFmt.format(pdsUsedMBytes) + "MB]" + NL + pdsRegionsInfo;
+
+            String id = U.id8(localNode().id());
+
+            String msg = NL +
+                "Metrics for local node (to disable set 'metricsLogFrequency' 
to 0)" + NL +
+                "    ^-- Node [id=" + id + (name() != null ? ", name=" + 
name() : "") + ", uptime=" +
+                getUpTimeFormatted() + "]" + NL +
+                "    ^-- H/N/C [hosts=" + hosts + ", nodes=" + nodes + ", 
CPUs=" + cpus + "]" + NL +
+                "    ^-- CPU [cur=" + dblFmt.format(cpuLoadPct) + "%, avg=" +
+                dblFmt.format(avgCpuLoadPct) + "%, GC=" + dblFmt.format(gcPct) 
+ "%]" + NL +
+                "    ^-- PageMemory [pages=" + loadedPages + "]" + NL +
+                "    ^-- Heap [used=" + dblFmt.format(heapUsedInMBytes) + "MB, 
free=" +
+                dblFmt.format(freeHeapPct) + "%, comm=" + 
dblFmt.format(heapCommInMBytes) + "MB]" + NL +
+                "    ^-- Off-heap [used=" + dblFmt.format(offHeapUsedInMBytes) 
+ "MB, free=" +
+                dblFmt.format(freeOffHeapPct) + "%, comm=" + 
dblFmt.format(offHeapCommInMBytes) + "MB]" + NL +
+                dataRegionsInfo +
+                pdsInfo +
+                "    ^-- Outbound messages queue [size=" + 
m.getOutboundMessagesQueueSize() + "]" + NL +
+                "    ^-- " + createExecutorDescription("Public thread pool", 
execSvc) + NL +
+                "    ^-- " + createExecutorDescription("System thread pool", 
sysExecSvc);
+
+            if (customExecSvcs != null) {
+                StringBuilder customSvcsMsg = new StringBuilder();
+
+                for (Map.Entry<String, ? extends ExecutorService> entry : 
customExecSvcs.entrySet()) {
+                    customSvcsMsg.append(NL).append("    ^-- ")
+                        .append(createExecutorDescription(entry.getKey(), 
entry.getValue()));
+                }
+
+                msg += customSvcsMsg;
+            }
+
+            log.info(msg);
+
+            ctx.cache().context().database().dumpStatistics(log);
+        }
+        catch (IgniteClientDisconnectedException ignore) {
+            // No-op.
+        }
+    }
+
+    /**
      * @return Language runtime.
      */
     @SuppressWarnings("ThrowableInstanceNeverThrown")

http://git-wip-us.apache.org/repos/asf/ignite/blob/813f0977/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
index 4334c74..2408660 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
@@ -124,9 +124,6 @@ public class DataRegionMetricsImpl implements 
DataRegionMetrics, AllocatedPageTr
 
     /** {@inheritDoc} */
     @Override public long getTotalAllocatedPages() {
-        if (!metricsEnabled)
-            return 0;
-
         return totalAllocatedPages.longValue();
     }
 
@@ -280,9 +277,6 @@ public class DataRegionMetricsImpl implements 
DataRegionMetrics, AllocatedPageTr
 
     /** {@inheritDoc} */
     @Override public long getOffHeapSize() {
-        if (!metricsEnabled)
-            return 0;
-
         return offHeapSize.get();
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/813f0977/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index 4bdf5ba..fe0103a 100755
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -179,7 +179,7 @@ public class GridCacheDatabaseSharedManager extends 
IgniteCacheDatabaseSharedMan
     public static final String IGNITE_PDS_CHECKPOINT_TEST_SKIP_SYNC = 
"IGNITE_PDS_CHECKPOINT_TEST_SKIP_SYNC";
 
     /** MemoryPolicyConfiguration name reserved for meta store. */
-    private static final String METASTORE_DATA_REGION_NAME = "metastoreMemPlc";
+    public static final String METASTORE_DATA_REGION_NAME = "metastoreMemPlc";
 
     /** */
     private static final long GB = 1024L * 1024 * 1024;

http://git-wip-us.apache.org/repos/asf/ignite/blob/813f0977/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogPdsSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogPdsSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogPdsSelfTest.java
new file mode 100644
index 0000000..a768a11
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogPdsSelfTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.WALMode;
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Check logging local node metrics with PDS enabled.
+ */
+public class GridNodeMetricsLogPdsSelfTest extends GridNodeMetricsLogSelfTest {
+    /** */
+    private static final String UNKNOWN_SIZE = "unknown";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        DataStorageConfiguration memCfg = new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration()
+                    .setMaxSize(30 * 1024 * 1024)
+                    .setPersistenceEnabled(true))
+            .setWalMode(WALMode.LOG_ONLY);
+
+        cfg.setDataStorageConfiguration(memCfg);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        cleanPersistenceDir();
+
+        super.beforeTest();
+
+        grid(0).cluster().active(true);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        cleanPersistenceDir();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void checkNodeMetricsFormat(String logOutput) {
+        super.checkNodeMetricsFormat(logOutput);
+
+        String msg = "Metrics are missing in the log or have an unexpected 
format";
+
+        assertTrue(msg, logOutput.matches("(?s).*Ignite persistence 
\\[used=.*].*"));
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void checkMemoryMetrics(String logOutput) {
+        super.checkMemoryMetrics(logOutput);
+
+        boolean summaryFmtMatches = false;
+
+        Set<String> regions = new HashSet<>();
+
+        Pattern ptrn = Pattern.compile("(?m).{2,}( {3}(?<name>.+) 
region|Ignite persistence) " +
+            "\\[used=(?<used>[-.\\d]+|" + UNKNOWN_SIZE + ")?.*]");
+
+        Matcher matcher = ptrn.matcher(logOutput);
+
+        while (matcher.find()) {
+            String subj = logOutput.substring(matcher.start(), matcher.end());
+
+            assertFalse("\"used\" cannot be empty: " + subj, 
F.isEmpty(matcher.group("used")));
+
+            String usedSize = matcher.group("used");
+
+            // TODO https://issues.apache.org/jira/browse/IGNITE-9455
+            // TODO The actual value of the metric should be printed when this 
issue is solved.
+            int used = UNKNOWN_SIZE.equals(usedSize) ? 0 : 
Integer.parseInt(usedSize);
+
+            assertTrue(used + " should be non negative: " + subj, used >= 0);
+
+            String regName = matcher.group("name");
+
+            if (F.isEmpty(regName))
+                summaryFmtMatches = true;
+            else
+                regions.add(regName);
+        }
+
+        assertTrue("Persistence metrics have unexpected format.", 
summaryFmtMatches);
+
+        Set<String> expRegions = 
grid(0).context().cache().context().database().dataRegions().stream()
+            .filter(v -> v.config().isPersistenceEnabled())
+            .map(v -> v.config().getName().trim())
+            .collect(Collectors.toSet());
+
+        assertEquals(expRegions, regions);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/813f0977/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java
index 9edebd5..4389338 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java
@@ -17,18 +17,18 @@
 
 package org.apache.ignite.internal;
 
-
-import java.io.StringWriter;
-import org.apache.ignite.Ignite;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.configuration.ExecutorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.testframework.GridStringLogger;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.testframework.junits.common.GridCommonTest;
-import org.apache.log4j.Layout;
-import org.apache.log4j.Logger;
-import org.apache.log4j.SimpleLayout;
-import org.apache.log4j.WriterAppender;
 
 /**
  * Check logging local node metrics
@@ -42,6 +42,9 @@ public class GridNodeMetricsLogSelfTest extends 
GridCommonAbstractTest {
     /** Executor name for setExecutorConfiguration */
     private static final String CUSTOM_EXECUTOR_1 = "Custom executor 1";
 
+    /** */
+    private GridStringLogger strLog = new GridStringLogger(false, this.log);
+
     /** {@inheritDoc} */
     @SuppressWarnings({"unchecked"})
     @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
@@ -52,6 +55,8 @@ public class GridNodeMetricsLogSelfTest extends 
GridCommonAbstractTest {
         cfg.setExecutorConfiguration(new 
ExecutorConfiguration(CUSTOM_EXECUTOR_0),
             new ExecutorConfiguration(CUSTOM_EXECUTOR_1));
 
+        cfg.setGridLogger(strLog);
+
         return cfg;
     }
 
@@ -60,55 +65,105 @@ public class GridNodeMetricsLogSelfTest extends 
GridCommonAbstractTest {
         stopAllGrids();
     }
 
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        strLog.reset();
+
+        strLog.logLength(300_000);
+
+        startGrids(2);
+    }
+
     /**
      * @throws Exception If failed.
      */
     public void testNodeMetricsLog() throws Exception {
-        // Log to string, to check log content
-        Layout layout = new SimpleLayout();
-
-        StringWriter strWr = new StringWriter();
-
-        WriterAppender app = new WriterAppender(layout, strWr);
-
-        Logger.getRootLogger().addAppender(app);
-
-        Ignite g1 = startGrid(1);
-
-        IgniteCache<Integer, String> cache1 = g1.createCache("TestCache1");
+        IgniteCache<Integer, String> cache1 = 
grid(0).createCache("TestCache1");
+        IgniteCache<Integer, String> cache2 = 
grid(1).createCache("TestCache2");
 
         cache1.put(1, "one");
-
-        Ignite g2 = startGrid(2);
-
-        IgniteCache<Integer, String> cache2 = g2.createCache("TestCache2");
-
         cache2.put(2, "two");
 
         Thread.sleep(10_000);
 
-        //Check that nodes are alie
+        // Check that nodes are alive.
         assertEquals("one", cache1.get(1));
         assertEquals("two", cache2.get(2));
 
-        String fullLog = strWr.toString();
+        String logOutput = strLog.toString();
 
-        Logger.getRootLogger().removeAppender(app);
+        checkNodeMetricsFormat(logOutput);
+
+        checkMemoryMetrics(logOutput);
+    }
 
+    /**
+     * Check node metrics format.
+     *
+     * @param fullLog Logging output.
+     */
+    protected void checkNodeMetricsFormat(String fullLog) {
         String msg = "Metrics are missing in the log or have an unexpected 
format";
 
-        // don't check the format strictly, but check that all expected 
metrics are present
+        // Don't check the format strictly, but check that all expected 
metrics are present.
         assertTrue(msg, fullLog.contains("Metrics for local node (to disable 
set 'metricsLogFrequency' to 0)"));
         assertTrue(msg, fullLog.matches("(?s).*Node \\[id=.*, name=.*, 
uptime=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*H/N/C \\[hosts=.*, nodes=.*, 
CPUs=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*CPU \\[cur=.*, avg=.*, 
GC=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*PageMemory \\[pages=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*Heap \\[used=.*, free=.*, 
comm=.*].*"));
-        assertTrue(msg, fullLog.matches("(?s).*Non heap \\[used=.*, free=.*, 
comm=.*].*"));
+        assertTrue(msg, fullLog.matches("(?s).*Off-heap \\[used=.*, free=.*, 
comm=.*].*"));
+        assertTrue(msg, fullLog.matches("(?s).* region \\[used=.*, free=.*, 
comm=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*Outbound messages queue 
\\[size=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*Public thread pool 
\\[active=.*, idle=.*, qSize=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*System thread pool 
\\[active=.*, idle=.*, qSize=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*" + CUSTOM_EXECUTOR_0 + " 
\\[active=.*, idle=.*, qSize=.*].*"));
         assertTrue(msg, fullLog.matches("(?s).*" + CUSTOM_EXECUTOR_1 + " 
\\[active=.*, idle=.*, qSize=.*].*"));
     }
+
+    /**
+     * Check memory metrics values.
+     *
+     * @param logOutput Logging output.
+     */
+    protected void checkMemoryMetrics(String logOutput) {
+        boolean summaryFmtMatches = false;
+
+        Set<String> regions = new HashSet<>();
+
+        Matcher matcher = Pattern.compile("(?m).{2,}( {3}(?<name>.+) 
region|Off-heap) " +
+                "\\[used=(?<used>[-.\\d]*).*, free=(?<free>[-.\\d]*).*, 
comm=(?<comm>[-.\\d]*).*]")
+            .matcher(logOutput);
+
+        while (matcher.find()) {
+            String subj = logOutput.substring(matcher.start(), matcher.end());
+
+            assertFalse("\"used\" cannot be empty: " + subj, 
F.isEmpty(matcher.group("used")));
+            assertFalse("\"free\" cannot be empty: " + subj, 
F.isEmpty(matcher.group("free")));
+            assertFalse("\"comm\" cannot be empty: " + subj, 
F.isEmpty(matcher.group("comm")));
+
+            int used = Integer.parseInt(matcher.group("used"));
+            int comm = Integer.parseInt(matcher.group("comm"));
+            double free = Double.parseDouble(matcher.group("free"));
+
+            assertTrue(used + " should be non negative: " + subj, used >= 0);
+            assertTrue(comm + " is less then " + used + ": " + subj, comm >= 
used);
+            assertTrue(free + " is not between 0 and 100: " + subj, 0 <= free 
&& free <= 100);
+
+            String regName = matcher.group("name");
+
+            if (F.isEmpty(regName))
+                summaryFmtMatches = true;
+            else
+                regions.add(regName.trim());
+        }
+
+        assertTrue("Off-heap metrics have unexpected format.", 
summaryFmtMatches);
+
+        Set<String> expRegions = 
grid(0).context().cache().context().database().dataRegions().stream()
+            .map(v -> v.config().getName().trim())
+            .collect(Collectors.toSet());
+
+        assertEquals("Off-heap per-region metrics have unexpected format.", 
expRegions, regions);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/813f0977/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java
 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java
index 3171754..7ce6209 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java
@@ -22,6 +22,7 @@ import junit.framework.TestSuite;
 import org.apache.ignite.failure.IoomFailureHandlerTest;
 import org.apache.ignite.failure.SystemWorkersTerminationTest;
 import org.apache.ignite.internal.ClusterBaselineNodesMetricsSelfTest;
+import org.apache.ignite.internal.GridNodeMetricsLogPdsSelfTest;
 import 
org.apache.ignite.internal.processors.service.ServiceDeploymentOnActivationTest;
 import 
org.apache.ignite.internal.processors.service.ServiceDeploymentOutsideBaselineTest;
 import org.apache.ignite.marshaller.GridMarshallerMappingConsistencyTest;
@@ -59,6 +60,8 @@ public class IgniteBasicWithPersistenceTestSuite extends 
TestSuite {
         suite.addTestSuite(GridCommandHandlerTest.class);
         suite.addTestSuite(GridInternalTaskUnusedWalSegmentsTest.class);
 
+        suite.addTestSuite(GridNodeMetricsLogPdsSelfTest.class);
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/813f0977/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs
index b172eaf..15cf4db 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs
@@ -104,7 +104,6 @@ namespace Apache.Ignite.Core.Tests.Cache
             Assert.AreEqual(0, metrics.EvictionRate);
             Assert.AreEqual(0, metrics.LargeEntriesPagesPercentage);
             Assert.AreEqual(0, metrics.PageFillFactor);
-            Assert.AreEqual(0, metrics.TotalAllocatedPages);
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/813f0977/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs
index 67319f4..92f9b4d 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs
@@ -92,7 +92,6 @@ namespace Apache.Ignite.Core.Tests.Cache
             Assert.AreEqual(0, metrics.EvictionRate);
             Assert.AreEqual(0, metrics.LargeEntriesPagesPercentage);
             Assert.AreEqual(0, metrics.PageFillFactor);
-            Assert.AreEqual(0, metrics.TotalAllocatedPages);
         }
 
         /// <summary>

Reply via email to