blob: 9f108d0310eb74218af370cb10c97276fb2ae12f [file] [log] [blame]
/*
* 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.IgniteCache;
import org.apache.ignite.configuration.CacheConfiguration;
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.junit.Test;
/**
* Check logging local node metrics
*/
@SuppressWarnings({"ProhibitedExceptionDeclared"})
@GridCommonTest(group = "Kernal")
public class GridNodeMetricsLogSelfTest extends GridCommonAbstractTest {
/** Executor name for setExecutorConfiguration */
private static final String CUSTOM_EXECUTOR_0 = "Custom executor 0";
/** Executor name for setExecutorConfiguration */
private static final String CUSTOM_EXECUTOR_1 = "Custom executor 1";
/** */
public static final String IN_MEMORY_REGION = "userTransientDataRegion";
/** */
private GridStringLogger strLog = new GridStringLogger(false, this.log);
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
cfg.setMetricsLogFrequency(1000);
cfg.setExecutorConfiguration(new ExecutorConfiguration(CUSTOM_EXECUTOR_0),
new ExecutorConfiguration(CUSTOM_EXECUTOR_1));
cfg.setGridLogger(strLog);
return cfg;
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
stopAllGrids();
}
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
strLog.reset();
strLog.logLength(300_000);
startGrids(2);
}
/**
* @throws Exception If failed.
*/
@Test
public void testNodeMetricsLog() throws Exception {
IgniteCache<Integer, String> cache1 = grid(0).createCache("TestCache1");
IgniteCache<Integer, String> cache2 = grid(1).createCache(
new CacheConfiguration<Integer, String>("TestCache2")
.setDataRegionName(persistenceEnabled() ? IN_MEMORY_REGION : "default"));
cache1.put(1, "one");
cache2.put(2, "two");
Thread.sleep(10_000);
// Check that nodes are alive.
assertEquals("one", cache1.get(1));
assertEquals("two", cache2.get(2));
String logOutput = strLog.toString();
checkNodeMetricsFormat(logOutput);
checkOffHeapMetrics(logOutput);
checkDataRegionsMetrics(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.
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).*Cluster \\[hosts=.*, CPUs=.*, servers=.*, clients=.*, topVer=.*, minorTopVer=.*].*"));
assertTrue(msg, fullLog.matches("(?s).*Network \\[addrs=\\[.*], localHost=.*, discoPort=.*, commPort=.*].*"));
assertTrue(msg, fullLog.matches("(?s).*CPU \\[CPUs=.*, curLoad=.*, avgLoad=.*, GC=.*].*"));
assertTrue(msg, fullLog.matches("(?s).*Page memory \\[pages=.*].*"));
assertTrue(msg, fullLog.matches("(?s).*Heap \\[used=.*, free=.*, comm=.*].*"));
assertTrue(msg, fullLog.matches("(?s).*Off-heap memory \\[used=.*, free=.*, allocated=.*].*"));
assertTrue(msg, fullLog.matches("(?s).* region \\[type=internal, persistence=(true|false), lazyAlloc=(true|false).*"));
assertTrue(msg, fullLog.matches("(?s).* region \\[type=default, persistence=(true|false), lazyAlloc=(true|false).*"));
assertTrue(msg, fullLog.matches("(?s).*... initCfg=.*, maxCfg=.*, usedRam=.*, freeRam=.*, allocRam=.*].*"));
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).*Striped 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 checkDataRegionsMetrics(String logOutput) {
Set<String> regions = new HashSet<>();
Matcher matcher = Pattern.compile("(?m).{2,} {3}(?<name>.+) region \\[type=(default|internal|user), " +
"persistence=(?<persistent>true|false), lazyAlloc=(true|false),\\s*\\.\\.\\.\\s*" +
"initCfg=(?<init>[-\\d]+)MB, maxCfg=(?<max>[-\\d]+)MB, usedRam=(?<used>[-\\d]+).*MB, " +
"freeRam=(?<free>[-.\\d]+)%, allocRam=(?<alloc>[-\\d]+)MB(, allocTotal=(?<total>[-\\d]+)MB)?]")
.matcher(logOutput);
while (matcher.find()) {
String subj = logOutput.substring(matcher.start(), matcher.end());
int init = Integer.parseInt(matcher.group("init"));
int max = Integer.parseInt(matcher.group("max"));
int used = Integer.parseInt(matcher.group("used"));
double free = Double.parseDouble(matcher.group("free"));
int alloc = Integer.parseInt(matcher.group("alloc"));
boolean persistent = Boolean.parseBoolean(matcher.group("persistent"));
assertTrue(init + " should be non negative: " + subj, init >= 0);
assertTrue(max + " is less then " + init + ": " + subj, max >= init);
assertTrue(used + " should be non negative: " + subj, used >= 0);
assertTrue(alloc + " is less then " + used + ": " + subj, alloc >= used);
assertTrue(free + " is not between 0 and 100: " + subj, 0 <= free && free <= 100);
if (persistent) {
int total = Integer.parseInt(matcher.group("total"));
assertTrue(total + " is less then " + used + ": " + subj, total >= used);
}
else
assertTrue(F.isEmpty(matcher.group("total")));
String regName = matcher.group("name").trim();
regions.add(regName);
}
Set<String> expRegions = grid(0).context().cache().context().database().dataRegions().stream()
.map(v -> v.config().getName().trim())
.collect(Collectors.toSet());
assertFalse("No data regions in the log.", regions.isEmpty());
assertEquals("Unexpected names of data regions.", expRegions, regions);
}
/**
* Check memory metrics values.
*
* @param logOutput Logging output.
*/
protected void checkOffHeapMetrics(String logOutput) {
Matcher matcher = Pattern.compile("Off-heap memory " +
"\\[used=(?<used>[-.\\d]*).*, free=(?<free>[-.\\d]*).*, allocated=(?<comm>[-.\\d]*).*]")
.matcher(logOutput);
assertTrue("Off-heap metrics not found in the log.", 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);
}
/** */
protected boolean persistenceEnabled() {
return false;
}
}