/*
* 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.geode.management.internal.cli.commands;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.sql.Time;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.zip.DataFormatException;
import java.util.zip.GZIPInputStream;
import javax.management.ObjectName;
import org.apache.geode.LogWriter;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.execute.Execution;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.FunctionException;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.distributed.internal.deadlock.DeadlockDetector;
import org.apache.geode.distributed.internal.deadlock.Dependency;
import org.apache.geode.distributed.internal.deadlock.DependencyGraph;
import org.apache.geode.distributed.internal.deadlock.GemFireDeadlockDetector;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.i18n.LocalizedStrings;
import org.apache.geode.internal.logging.InternalLogWriter;
import org.apache.geode.internal.logging.LogWriterImpl;
import org.apache.geode.management.CacheServerMXBean;
import org.apache.geode.management.DistributedRegionMXBean;
import org.apache.geode.management.DistributedSystemMXBean;
import org.apache.geode.management.JVMMetrics;
import org.apache.geode.management.ManagementService;
import org.apache.geode.management.MemberMXBean;
import org.apache.geode.management.RegionMXBean;
import org.apache.geode.management.cli.CliMetaData;
import org.apache.geode.management.cli.ConverterHint;
import org.apache.geode.management.cli.Result;
import org.apache.geode.management.internal.MBeanJMXAdapter;
import org.apache.geode.management.internal.ManagementConstants;
import org.apache.geode.management.internal.SystemManagementService;
import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
import org.apache.geode.management.internal.cli.CliUtil;
import org.apache.geode.management.internal.cli.CliUtil.DeflaterInflaterData;
import org.apache.geode.management.internal.cli.GfshParseResult;
import org.apache.geode.management.internal.cli.GfshParser;
import org.apache.geode.management.internal.cli.LogWrapper;
import org.apache.geode.management.internal.cli.domain.StackTracesPerMember;
import org.apache.geode.management.internal.cli.functions.ChangeLogLevelFunction;
import org.apache.geode.management.internal.cli.functions.GarbageCollectionFunction;
import org.apache.geode.management.internal.cli.functions.GetStackTracesFunction;
import org.apache.geode.management.internal.cli.functions.LogFileFunction;
import org.apache.geode.management.internal.cli.functions.NetstatFunction;
import org.apache.geode.management.internal.cli.functions.NetstatFunction.NetstatFunctionArgument;
import org.apache.geode.management.internal.cli.functions.NetstatFunction.NetstatFunctionResult;
import org.apache.geode.management.internal.cli.functions.ShutDownFunction;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.cli.remote.CommandExecutionContext;
import org.apache.geode.management.internal.cli.result.CommandResultException;
import org.apache.geode.management.internal.cli.result.CompositeResultData;
import org.apache.geode.management.internal.cli.result.CompositeResultData.SectionResultData;
import org.apache.geode.management.internal.cli.result.ErrorResultData;
import org.apache.geode.management.internal.cli.result.InfoResultData;
import org.apache.geode.management.internal.cli.result.ResultBuilder;
import org.apache.geode.management.internal.cli.result.ResultData;
import org.apache.geode.management.internal.cli.result.ResultDataException;
import org.apache.geode.management.internal.cli.result.TabularResultData;
import org.apache.geode.management.internal.cli.shell.Gfsh;
import org.apache.geode.management.internal.cli.util.MergeLogs;
import org.apache.geode.management.internal.security.ResourceOperation;
import org.apache.geode.security.ResourcePermission.Operation;
import org.apache.geode.security.ResourcePermission.Resource;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
/**
*
* @since GemFire 7.0
*/
public class MiscellaneousCommands implements CommandMarker {
public static final String NETSTAT_FILE_REQUIRED_EXTENSION = ".txt";
public final static String FORMAT = "yyyy/MM/dd/HH/mm/ss/SSS/z";
public final static String ONLY_DATE_FORMAT = "yyyy/MM/dd";
public final static String DEFAULT_TIME_OUT = "10";
private final GetStackTracesFunction getStackTracesFunction = new GetStackTracesFunction();
private Gfsh getGfsh() {
return Gfsh.getCurrentInstance();
}
public void shutdownNode(final long timeout, final Set<DistributedMember> includeMembers)
throws TimeoutException, InterruptedException, ExecutionException {
Cache cache = CacheFactory.getAnyInstance();
LogWriter logger = cache.getLogger();
ExecutorService exec = Executors.newSingleThreadExecutor();
try {
final Function shutDownFunction = new ShutDownFunction();
logger.info("Gfsh executing shutdown on members " + includeMembers);
Callable<String> shutdownNodes = new Callable<String>() {
@Override
public String call() {
try {
Execution execution = FunctionService.onMembers(includeMembers);
execution.execute(shutDownFunction);
} catch (FunctionException functionEx) {
// Expected Exception as the function is shutting down the target members and the result
// collector will get member departed exception
}
return "SUCCESS";
}
};
Future<String> result = exec.submit(shutdownNodes);
result.get(timeout, TimeUnit.MILLISECONDS);
} catch (TimeoutException te) {
logger.error("TimeoutException in shutting down members." + includeMembers);
throw te;
} catch (InterruptedException e) {
logger.error("InterruptedException in shutting down members." + includeMembers);
throw e;
} catch (ExecutionException e) {
logger.error("ExecutionException in shutting down members." + includeMembers);
throw e;
} finally {
exec.shutdownNow();
}
}
@CliCommand(value = CliStrings.SHUTDOWN, help = CliStrings.SHUTDOWN__HELP)
@CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_LIFECYCLE},
interceptor = "org.apache.geode.management.internal.cli.commands.MiscellaneousCommands$Interceptor")
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.MANAGE)
public Result shutdown(
@CliOption(key = CliStrings.SHUTDOWN__TIMEOUT, unspecifiedDefaultValue = DEFAULT_TIME_OUT,
help = CliStrings.SHUTDOWN__TIMEOUT__HELP) int userSpecifiedTimeout,
@CliOption(key = CliStrings.INCLUDE_LOCATORS, unspecifiedDefaultValue = "false",
help = CliStrings.INCLUDE_LOCATORS_HELP) boolean shutdownLocators) {
try {
if (userSpecifiedTimeout < Integer.parseInt(DEFAULT_TIME_OUT)) {
return ResultBuilder.createInfoResult(CliStrings.SHUTDOWN__MSG__IMPROPER_TIMEOUT);
}
// convert to mili-seconds
long timeout = userSpecifiedTimeout * 1000;
Cache cache = CacheFactory.getAnyInstance();
int numDataNodes = CliUtil.getAllNormalMembers(cache).size();
Set<DistributedMember> locators = CliUtil.getAllMembers(cache);
Set<DistributedMember> dataNodes = CliUtil.getAllNormalMembers(cache);
locators.removeAll(dataNodes);
if (!shutdownLocators && numDataNodes == 0) {
return ResultBuilder.createInfoResult(CliStrings.SHUTDOWN__MSG__NO_DATA_NODE_FOUND);
}
GemFireCacheImpl gemFireCache = (GemFireCacheImpl) cache;
String managerName =
gemFireCache.getJmxManagerAdvisor().getDistributionManager().getId().getId();
final DistributedMember manager = CliUtil.getDistributedMemberByNameOrId(managerName);
dataNodes.remove(manager);
// shut down all data members excluding this manager if manager is a data node
long timeElapsed = shutDownNodeWithTimeOut(timeout, dataNodes);
timeout = timeout - timeElapsed;
// shut down locators one by one
if (shutdownLocators) {
if (manager == null) {
return ResultBuilder.createUserErrorResult(CliStrings.SHUTDOWN__MSG__MANAGER_NOT_FOUND);
}
// remove current locator as that would get shutdown last
if (locators.contains(manager)) {
locators.remove(manager);
}
for (DistributedMember locator : locators) {
Set<DistributedMember> lsSet = new HashSet<DistributedMember>();
lsSet.add(locator);
long elapsedTime = shutDownNodeWithTimeOut(timeout, lsSet);
timeout = timeout - elapsedTime;
}
}
if (locators.contains(manager) && !shutdownLocators) { // This means manager is a locator and
// shutdownLocators is false. Hence we
// should not stop the manager
return ResultBuilder.createInfoResult("Shutdown is triggered");
}
// now shut down this manager
Set<DistributedMember> mgrSet = new HashSet<DistributedMember>();
mgrSet.add(manager);
// No need to check further timeout as this is the last node we will be
// shutting down
shutDownNodeWithTimeOut(timeout, mgrSet);
} catch (TimeoutException tex) {
return ResultBuilder.createInfoResult(CliStrings.SHUTDOWN_TIMEDOUT);
} catch (Exception ex) {
ex.printStackTrace();
return ResultBuilder.createUserErrorResult(ex.getMessage());
}
// @TODO. List all the nodes which could be successfully shutdown
return ResultBuilder.createInfoResult("Shutdown is triggered");
}
/**
*
* @param timeout user specified timeout
* @param nodesToBeStopped list of nodes to be stopped
* @return Elapsed time to shutdown the given nodes;
* @throws ExecutionException
* @throws InterruptedException
*/
private long shutDownNodeWithTimeOut(long timeout, Set<DistributedMember> nodesToBeStopped)
throws TimeoutException, InterruptedException, ExecutionException {
long shutDownTimeStart = System.currentTimeMillis();
shutdownNode(timeout, nodesToBeStopped);
long shutDownTimeEnd = System.currentTimeMillis();
long timeElapsed = shutDownTimeEnd - shutDownTimeStart;
if (timeElapsed > timeout || Boolean.getBoolean("ThrowTimeoutException")) { // The second check
// for
// ThrowTimeoutException
// is a test hook
throw new TimeoutException();
}
return timeElapsed;
}
/**
* Interceptor used by gfsh to intercept execution of shutdownall.
*/
public static class Interceptor extends AbstractCliAroundInterceptor {
@Override
public Result preExecution(GfshParseResult parseResult) {
// This hook is for testing purpose only.
if (Boolean.getBoolean(CliStrings.IGNORE_INTERCEPTORS)) {
return ResultBuilder.createInfoResult(CliStrings.SHUTDOWN__MSG__SHUTDOWN_ENTIRE_DS);
}
Response response = readYesNo(CliStrings.SHUTDOWN__MSG__WARN_USER, Response.YES);
if (response == Response.NO) {
return ResultBuilder
.createShellClientAbortOperationResult(CliStrings.SHUTDOWN__MSG__ABORTING_SHUTDOWN);
} else {
return ResultBuilder.createInfoResult(CliStrings.SHUTDOWN__MSG__SHUTDOWN_ENTIRE_DS);
}
}
@Override
public Result postExecution(GfshParseResult parseResult, Result commandResult) {
return commandResult;
}
}
@CliCommand(value = CliStrings.GC, help = CliStrings.GC__HELP)
@CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_DEBUG_UTIL})
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.MANAGE)
public Result gc(
@CliOption(key = CliStrings.GC__GROUP,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
help = CliStrings.GC__GROUP__HELP) String[] groups,
@CliOption(key = CliStrings.GC__MEMBER, optionContext = ConverterHint.ALL_MEMBER_IDNAME,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
help = CliStrings.GC__MEMBER__HELP) String memberId) {
Cache cache = CacheFactory.getAnyInstance();
Result result = null;
CompositeResultData gcResultTable = ResultBuilder.createCompositeResultData();
TabularResultData resultTable = gcResultTable.addSection().addTable("Table1");
String headerText = "GC Summary";
resultTable.setHeader(headerText);
Set<DistributedMember> dsMembers = new HashSet<DistributedMember>();
if (memberId != null && memberId.length() > 0) {
DistributedMember member = CliUtil.getDistributedMemberByNameOrId(memberId);
if (member == null) {
return ResultBuilder
.createGemFireErrorResult(memberId + CliStrings.GC__MSG__MEMBER_NOT_FOUND);
}
dsMembers.add(member);
result = executeAndBuildResult(cache, resultTable, dsMembers);
} else if (groups != null && groups.length > 0) {
for (String group : groups) {
dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(group));
}
result = executeAndBuildResult(cache, resultTable, dsMembers);
} else {
// gc on entire cluster
// exclude locators
dsMembers = CliUtil.getAllNormalMembers(cache);
result = executeAndBuildResult(cache, resultTable, dsMembers);
}
return result;
}
Result executeAndBuildResult(Cache cache, TabularResultData resultTable,
Set<DistributedMember> dsMembers) {
try {
List<?> resultList = null;
Function garbageCollectionFunction = new GarbageCollectionFunction();
resultList =
(List<?>) CliUtil.executeFunction(garbageCollectionFunction, null, dsMembers).getResult();
for (int i = 0; i < resultList.size(); i++) {
Object object = resultList.get(i);
if (object instanceof Exception) {
LogWrapper.getInstance().fine("Exception in GC " + ((Throwable) object).getMessage(),
((Throwable) object));
continue;
} else if (object instanceof Throwable) {
LogWrapper.getInstance().fine("Exception in GC " + ((Throwable) object).getMessage(),
((Throwable) object));
continue;
}
if (object != null) {
if (object instanceof String) {
// unexpected exception string - cache may be closed or something
return ResultBuilder.createUserErrorResult((String) object);
} else {
Map<String, String> resultMap = (Map<String, String>) object;
toTabularResultData(resultTable, (String) resultMap.get("MemberId"),
(String) resultMap.get("HeapSizeBeforeGC"),
(String) resultMap.get("HeapSizeAfterGC"), (String) resultMap.get("TimeSpentInGC"));
}
} else {
LogWrapper.getInstance().fine("ResultMap was null ");
}
}
} catch (Exception e) {
String stack = CliUtil.stackTraceAsString(e);
LogWrapper.getInstance().info("GC exception is " + stack);
return ResultBuilder.createGemFireErrorResult(e.getMessage() + ": " + stack);
}
return ResultBuilder.buildResult(resultTable);
}
protected void toTabularResultData(TabularResultData table, String memberId,
String heapSizeBefore, String heapSizeAfter, String timeTaken) {
table.accumulate(CliStrings.GC__MSG__MEMBER_NAME, memberId);
table.accumulate(CliStrings.GC__MSG__HEAP_SIZE_BEFORE_GC, heapSizeBefore);
table.accumulate(CliStrings.GC__MSG__HEAP_SIZE_AFTER_GC, heapSizeAfter);
table.accumulate(CliStrings.GC__MSG__TOTAL_TIME_IN_GC, timeTaken);
}
@CliCommand(value = CliStrings.NETSTAT, help = CliStrings.NETSTAT__HELP)
@CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_DEBUG_UTIL})
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
// TODO : Verify the auto-completion for multiple values.
public Result netstat(@CliOption(key = CliStrings.NETSTAT__MEMBER, mandatory = false,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
optionContext = ConverterHint.ALL_MEMBER_IDNAME,
help = CliStrings.NETSTAT__MEMBER__HELP) @CliMetaData(valueSeparator = ",") String[] members,
@CliOption(key = CliStrings.NETSTAT__GROUP, mandatory = false,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
optionContext = ConverterHint.MEMBERGROUP,
help = CliStrings.NETSTAT__GROUP__HELP) String group,
@CliOption(key = CliStrings.NETSTAT__FILE, optionContext = ConverterHint.FILE,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
help = CliStrings.NETSTAT__FILE__HELP) String saveAs,
@CliOption(key = CliStrings.NETSTAT__WITHLSOF, specifiedDefaultValue = "true",
unspecifiedDefaultValue = "false",
help = CliStrings.NETSTAT__WITHLSOF__HELP) boolean withlsof) {
Result result = null;
Map<String, DistributedMember> hostMemberMap = new HashMap<String, DistributedMember>();
Map<String, List<String>> hostMemberListMap = new HashMap<String, List<String>>();
try {
if (members != null && members.length > 0 && group != null) {
throw new IllegalArgumentException(
CliStrings.NETSTAT__MSG__ONLY_ONE_OF_MEMBER_OR_GROUP_SHOULD_BE_SPECIFIED);
}
StringBuilder resultInfo = new StringBuilder();
// Execute for remote members whose id or name matches
InternalDistributedSystem system = InternalDistributedSystem.getConnectedInstance();
if (members != null) {
Set<String> notFoundMembers = new HashSet<String>();
for (String memberIdOrName : members) {
Set<DistributedMember> membersToExecuteOn = CliUtil.getAllMembers(system);
boolean memberFound = false;
for (DistributedMember distributedMember : membersToExecuteOn) {
String memberName = distributedMember.getName();
String memberId = distributedMember.getId();
if (memberName.equals(memberIdOrName) || memberId.equals(memberIdOrName)) {
buildMaps(hostMemberMap, hostMemberListMap, memberIdOrName, distributedMember);
memberFound = true;
break;
}
}
if (!memberFound) {
notFoundMembers.add(memberIdOrName);
}
}
// if there are not found members, it's probably unknown member or member has departed
if (!notFoundMembers.isEmpty()) {
throw new IllegalArgumentException(
CliStrings.format(CliStrings.NETSTAT__MSG__COULD_NOT_FIND_MEMBERS_0,
new Object[] {CliUtil.collectionToString(notFoundMembers, -1)}));
}
} else {
Set<DistributedMember> membersToExecuteOn = null;
if (group != null) {
membersToExecuteOn = system.getGroupMembers(group);
} else {
// consider all members
membersToExecuteOn = CliUtil.getAllMembers(system);
}
for (DistributedMember distributedMember : membersToExecuteOn) {
String memberName = distributedMember.getName();
String memberId = distributedMember.getId();
String memberIdOrName =
memberName != null && !memberName.isEmpty() ? memberName : memberId;
buildMaps(hostMemberMap, hostMemberListMap, memberIdOrName, distributedMember);
}
}
String lineSeparatorToUse = null;
lineSeparatorToUse = CommandExecutionContext.getShellLineSeparator();
if (lineSeparatorToUse == null) {
lineSeparatorToUse = GfshParser.LINE_SEPARATOR;
}
NetstatFunctionArgument nfa = new NetstatFunctionArgument(lineSeparatorToUse, withlsof);
if (!hostMemberMap.isEmpty()) {
Set<DistributedMember> membersToExecuteOn =
new HashSet<DistributedMember>(hostMemberMap.values());
ResultCollector<?, ?> netstatResult =
CliUtil.executeFunction(NetstatFunction.INSTANCE, nfa, membersToExecuteOn);
List<?> resultList = (List<?>) netstatResult.getResult();
for (int i = 0; i < resultList.size(); i++) {
NetstatFunctionResult netstatFunctionResult = (NetstatFunctionResult) resultList.get(i);
DeflaterInflaterData deflaterInflaterData = netstatFunctionResult.getCompressedBytes();
try {
String remoteHost = netstatFunctionResult.getHost();
List<String> membersList = hostMemberListMap.get(remoteHost);
resultInfo.append(MessageFormat.format(netstatFunctionResult.getHeaderInfo(),
CliUtil.collectionToString(membersList, 120)));
DeflaterInflaterData uncompressedBytes = CliUtil.uncompressBytes(
deflaterInflaterData.getData(), deflaterInflaterData.getDataLength());
resultInfo.append(new String(uncompressedBytes.getData()));
} catch (DataFormatException e) {
resultInfo.append("Error in some data. Reason : " + e.getMessage());
}
}
}
InfoResultData resultData = ResultBuilder.createInfoResultData();
if (saveAs != null && !saveAs.isEmpty()) {
String saveToFile = saveAs;
if (!saveAs.endsWith(NETSTAT_FILE_REQUIRED_EXTENSION)) {
saveToFile = saveAs + NETSTAT_FILE_REQUIRED_EXTENSION;
}
resultData.addAsFile(saveToFile, resultInfo.toString(),
CliStrings.NETSTAT__MSG__SAVED_OUTPUT_IN_0, false); // Note: substitution for {0} will
// happen on client side.
} else {
resultData.addLine(resultInfo.toString());
}
result = ResultBuilder.buildResult(resultData);
} catch (IllegalArgumentException e) {
LogWrapper.getInstance()
.info(CliStrings.format(
CliStrings.NETSTAT__MSG__ERROR_OCCURRED_WHILE_EXECUTING_NETSTAT_ON_0,
new Object[] {Arrays.toString(members)}));
result = ResultBuilder.createUserErrorResult(e.getMessage());
} catch (RuntimeException e) {
LogWrapper.getInstance()
.info(CliStrings.format(
CliStrings.NETSTAT__MSG__ERROR_OCCURRED_WHILE_EXECUTING_NETSTAT_ON_0,
new Object[] {Arrays.toString(members)}), e);
result = ResultBuilder.createGemFireErrorResult(
CliStrings.format(CliStrings.NETSTAT__MSG__ERROR_OCCURRED_WHILE_EXECUTING_NETSTAT_ON_0,
new Object[] {Arrays.toString(members)}));
} finally {
hostMemberMap.clear();
hostMemberListMap.clear();
}
return result;
}
private void buildMaps(Map<String, DistributedMember> hostMemberMap,
Map<String, List<String>> hostMemberListMap, String memberIdOrName,
DistributedMember distributedMember) {
String host = distributedMember.getHost();
// Maintain one member for a host - function execution purpose - once only for a host
if (!hostMemberMap.containsKey(host)) {
hostMemberMap.put(host, distributedMember);
}
// Maintain all members for a host - display purpose
List<String> list = null;
if (!hostMemberListMap.containsKey(host)) {
list = new ArrayList<String>();
hostMemberListMap.put(host, list);
} else {
list = hostMemberListMap.get(host);
}
list.add(memberIdOrName);
}
@CliCommand(value = CliStrings.SHOW_DEADLOCK, help = CliStrings.SHOW_DEADLOCK__HELP)
@CliMetaData(shellOnly = false, relatedTopic = {CliStrings.TOPIC_GEODE_DEBUG_UTIL})
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public Result showDeadlock(@CliOption(key = CliStrings.SHOW_DEADLOCK__DEPENDENCIES__FILE,
help = CliStrings.SHOW_DEADLOCK__DEPENDENCIES__FILE__HELP,
mandatory = true) String filename) {
Result result = null;
try {
if (!filename.endsWith(".txt")) {
return ResultBuilder
.createUserErrorResult(CliStrings.format(CliStrings.INVALID_FILE_EXTENSION, ".txt"));
}
Cache cache = CacheFactory.getAnyInstance();
Set<DistributedMember> allMembers = CliUtil.getAllMembers(cache);
GemFireDeadlockDetector gfeDeadLockDetector = new GemFireDeadlockDetector(allMembers);
DependencyGraph dependencyGraph = gfeDeadLockDetector.find();
Collection<Dependency> deadlock = dependencyGraph.findCycle();
DependencyGraph deepest = null;
if (deadlock == null) {
deepest = dependencyGraph.findLongestCallChain();
if (deepest != null) {
deadlock = deepest.getEdges();
}
}
Set<Dependency> dependencies = (Set<Dependency>) dependencyGraph.getEdges();
InfoResultData resultData = ResultBuilder.createInfoResultData();
if (deadlock != null) {
if (deepest != null) {
resultData.addLine(CliStrings.SHOW_DEADLOCK__DEEPEST_FOUND);
} else {
resultData.addLine(CliStrings.SHOW_DEADLOCK__DEADLOCK__DETECTED);
}
resultData.addLine(DeadlockDetector.prettyFormat(deadlock));
} else {
resultData.addLine(CliStrings.SHOW_DEADLOCK__NO__DEADLOCK);
}
resultData.addAsFile(filename, DeadlockDetector.prettyFormat(dependencies),
MessageFormat.format(CliStrings.SHOW_DEADLOCK__DEPENDENCIES__REVIEW, filename), false);
result = ResultBuilder.buildResult(resultData);
} catch (Exception e) {
result = ResultBuilder
.createGemFireErrorResult(CliStrings.SHOW_DEADLOCK__ERROR + " : " + e.getMessage());
}
return result;
}
@CliCommand(value = CliStrings.SHOW_LOG, help = CliStrings.SHOW_LOG_HELP)
@CliMetaData(shellOnly = false, relatedTopic = {CliStrings.TOPIC_GEODE_DEBUG_UTIL})
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public Result showLog(
@CliOption(key = CliStrings.SHOW_LOG_MEMBER, optionContext = ConverterHint.ALL_MEMBER_IDNAME,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
help = CliStrings.SHOW_LOG_MEMBER_HELP, mandatory = true) String memberNameOrId,
@CliOption(key = CliStrings.SHOW_LOG_LINE_NUM, unspecifiedDefaultValue = "0",
help = CliStrings.SHOW_LOG_LINE_NUM_HELP, mandatory = false) int numberOfLines) {
Result result = null;
try {
Cache cache = CacheFactory.getAnyInstance();
SystemManagementService service =
(SystemManagementService) ManagementService.getExistingManagementService(cache);
MemberMXBean bean = null;
DistributedMember memberToBeInvoked = CliUtil.getDistributedMemberByNameOrId(memberNameOrId);
if (memberToBeInvoked != null) {
String memberId = memberToBeInvoked.getId();
if (cache.getDistributedSystem().getDistributedMember().getId().equals(memberId)) {
bean = service.getMemberMXBean();
} else {
ObjectName objectName = service.getMemberMBeanName(memberToBeInvoked);
bean = service.getMBeanProxy(objectName, MemberMXBean.class);
}
if (numberOfLines > ManagementConstants.MAX_SHOW_LOG_LINES) {
numberOfLines = ManagementConstants.MAX_SHOW_LOG_LINES;
}
if (numberOfLines == 0 || numberOfLines < 0) {
numberOfLines = ManagementConstants.DEFAULT_SHOW_LOG_LINES;
}
InfoResultData resultData = ResultBuilder.createInfoResultData();
if (bean != null) {
String log = bean.showLog(numberOfLines);
if (log != null) {
resultData.addLine(log);
} else {
resultData.addLine(CliStrings.SHOW_LOG_NO_LOG);
}
} else {
ErrorResultData errorResultData =
ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
.addLine(memberNameOrId + CliStrings.SHOW_LOG_MSG_MEMBER_NOT_FOUND);
return (ResultBuilder.buildResult(errorResultData));
}
result = ResultBuilder.buildResult(resultData);
} else {
ErrorResultData errorResultData =
ResultBuilder.createErrorResultData().setErrorCode(ResultBuilder.ERRORCODE_DEFAULT)
.addLine(memberNameOrId + CliStrings.SHOW_LOG_MSG_MEMBER_NOT_FOUND);
return (ResultBuilder.buildResult(errorResultData));
}
} catch (Exception e) {
result = ResultBuilder
.createGemFireErrorResult(CliStrings.SHOW_LOG_ERROR + CliUtil.stackTraceAsString(e));
}
return result;
}
Result exportLogsPreprocessing(String dirName, String[] groups, String memberId, String logLevel,
boolean onlyLogLevel, boolean mergeLog, String start, String end,
int numOfLogFilesForTesting) {
Result result = null;
try {
LogWrapper.getInstance().fine("Exporting logs");
Cache cache = CacheFactory.getAnyInstance();
Set<DistributedMember> dsMembers = new HashSet<DistributedMember>();
Time startTime = null, endTime = null;
if (logLevel == null || logLevel.length() == 0) {
// set default log level
logLevel = LogWriterImpl.levelToString(InternalLogWriter.INFO_LEVEL);
}
if (start != null && end == null) {
startTime = parseDate(start);
endTime = new Time(System.currentTimeMillis());
}
if (end != null && start == null) {
endTime = parseDate(end);
startTime = new Time(0);
}
if (start != null && end != null) {
startTime = parseDate(start);
endTime = parseDate(end);
if (endTime.getTime() - startTime.getTime() <= 0) {
result =
ResultBuilder.createUserErrorResult(CliStrings.EXPORT_LOGS__MSG__INVALID_TIMERANGE);
}
}
if (end == null && start == null) {
// set default time range as 1 day.
endTime = new Time(System.currentTimeMillis());
startTime = new Time(endTime.getTime() - 24 * 60 * 60 * 1000);
}
LogWrapper.getInstance().fine(
"Exporting logs startTime=" + startTime.toGMTString() + " " + startTime.toLocaleString());
LogWrapper.getInstance()
.fine("Exporting logs endTime=" + endTime.toGMTString() + " " + endTime.toLocaleString());
if (groups != null && memberId != null) {
result =
ResultBuilder.createUserErrorResult(CliStrings.EXPORT_LOGS__MSG__SPECIFY_ONE_OF_OPTION);
} else if (groups != null && groups.length > 0) {
for (String group : groups) {
Set<DistributedMember> groupMembers = cache.getDistributedSystem().getGroupMembers(group);
if (groupMembers != null && groupMembers.size() > 0) {
dsMembers.addAll(groupMembers);
}
}
if (dsMembers.size() == 0) {
result = ResultBuilder
.createUserErrorResult(CliStrings.EXPORT_LOGS__MSG__NO_GROUPMEMBER_FOUND);
}
result = export(cache, dsMembers, dirName, logLevel, onlyLogLevel ? "true" : "false",
mergeLog, startTime, endTime, numOfLogFilesForTesting);
} else if (memberId != null) {
DistributedMember member = CliUtil.getDistributedMemberByNameOrId(memberId);
if (member == null) {
result = ResultBuilder.createUserErrorResult(
CliStrings.format(CliStrings.EXPORT_LOGS__MSG__INVALID_MEMBERID, memberId));
}
dsMembers.add(member);
result = export(cache, dsMembers, dirName, logLevel, onlyLogLevel ? "true" : "false",
mergeLog, startTime, endTime, numOfLogFilesForTesting);
} else {
// run in entire DS members and get all including locators
dsMembers.addAll(CliUtil.getAllMembers(cache));
result = export(cache, dsMembers, dirName, logLevel, onlyLogLevel ? "true" : "false",
mergeLog, startTime, endTime, numOfLogFilesForTesting);
}
} catch (ParseException ex) {
LogWrapper.getInstance().fine(ex.getMessage());
result = ResultBuilder.createUserErrorResult(ex.getMessage());
} catch (Exception ex) {
LogWrapper.getInstance().fine(ex.getMessage());
result = ResultBuilder.createUserErrorResult(ex.getMessage());
}
return result;
}
@CliCommand(value = CliStrings.EXPORT_LOGS, help = CliStrings.EXPORT_LOGS__HELP)
@CliMetaData(shellOnly = false,
relatedTopic = {CliStrings.TOPIC_GEODE_SERVER, CliStrings.TOPIC_GEODE_DEBUG_UTIL})
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public Result exportLogs(
@CliOption(key = CliStrings.EXPORT_LOGS__DIR, help = CliStrings.EXPORT_LOGS__DIR__HELP,
mandatory = true) String dirName,
@CliOption(key = CliStrings.EXPORT_LOGS__GROUP,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
optionContext = ConverterHint.MEMBERGROUP,
help = CliStrings.EXPORT_LOGS__GROUP__HELP) String[] groups,
@CliOption(key = CliStrings.EXPORT_LOGS__MEMBER,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
optionContext = ConverterHint.ALL_MEMBER_IDNAME,
help = CliStrings.EXPORT_LOGS__MEMBER__HELP) String memberId,
@CliOption(key = CliStrings.EXPORT_LOGS__LOGLEVEL,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
optionContext = ConverterHint.LOG_LEVEL,
help = CliStrings.EXPORT_LOGS__LOGLEVEL__HELP) String logLevel,
@CliOption(key = CliStrings.EXPORT_LOGS__UPTO_LOGLEVEL, unspecifiedDefaultValue = "false",
help = CliStrings.EXPORT_LOGS__UPTO_LOGLEVEL__HELP) boolean onlyLogLevel,
@CliOption(key = CliStrings.EXPORT_LOGS__MERGELOG, unspecifiedDefaultValue = "false",
help = CliStrings.EXPORT_LOGS__MERGELOG__HELP) boolean mergeLog,
@CliOption(key = CliStrings.EXPORT_LOGS__STARTTIME,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
help = CliStrings.EXPORT_LOGS__STARTTIME__HELP) String start,
@CliOption(key = CliStrings.EXPORT_LOGS__ENDTIME,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
help = CliStrings.EXPORT_LOGS__ENDTIME__HELP) String end) {
Result result = null;
try {
result = exportLogsPreprocessing(dirName, groups, memberId, logLevel, onlyLogLevel, mergeLog,
start, end, 0);
} catch (Exception ex) {
LogWrapper.getInstance().fine(ex.getMessage());
result = ResultBuilder.createUserErrorResult(ex.getMessage());
}
LogWrapper.getInstance().fine("Exporting logs returning =" + result);
return result;
}
Time parseDate(String dateString) throws ParseException {
Time time = null;
try {
SimpleDateFormat df = new SimpleDateFormat(MiscellaneousCommands.FORMAT);
time = new Time(df.parse(dateString).getTime());
} catch (Exception e) {
SimpleDateFormat df = new SimpleDateFormat(MiscellaneousCommands.ONLY_DATE_FORMAT);
time = new Time(df.parse(dateString).getTime());
}
return time;
}
Result export(Cache cache, Set<DistributedMember> dsMembers, String dirName, String logLevel,
String onlyLogLevel, boolean mergeLog, Time startTime, Time endTime,
int numOfLogFilesForTesting) {
LogWrapper.getInstance()
.fine("Exporting logs in export membersize = " + dsMembers.size() + " dirname=" + dirName
+ " logLevel=" + logLevel + " onlyLogLevel=" + onlyLogLevel + " mergeLog=" + mergeLog
+ " startTime=" + startTime.toGMTString() + "endTime=" + endTime.toGMTString());
Function function = new LogFileFunction();
FunctionService.registerFunction(function);
try {
List<?> resultList = null;
List<String> logsToMerge = new ArrayList<String>();
Iterator<DistributedMember> it = dsMembers.iterator();
Object[] args = new Object[6];
args[0] = dirName;
args[1] = logLevel;
args[2] = onlyLogLevel;
args[3] = startTime.getTime();
args[4] = endTime.getTime();
args[5] = numOfLogFilesForTesting;
while (it.hasNext()) {
boolean toContinueForRestOfmembers = false;
DistributedMember member = it.next();
LogWrapper.getInstance().fine("Exporting logs copy the logs for member=" + member.getId());
try {
resultList = (ArrayList<?>) CliUtil.executeFunction(function, args, member).getResult();
} catch (Exception ex) {
LogWrapper.getInstance()
.fine(CliStrings.format(
CliStrings.EXPORT_LOGS__MSG__FAILED_TO_EXPORT_LOG_FILES_FOR_MEMBER_0,
member.getId()), ex);
// try for other members
continue;
}
if (resultList != null && !resultList.isEmpty()) {
for (int i = 0; i < resultList.size(); i++) {
Object object = resultList.get(i);
if (object instanceof Exception) {
ResultBuilder.createGemFireErrorResult(CliStrings.format(
CliStrings.EXPORT_LOGS__MSG__FAILED_TO_EXPORT_LOG_FILES_FOR_MEMBER_0,
member.getId()));
LogWrapper.getInstance().fine("Exporting logs for member=" + member.getId()
+ " exception=" + ((Throwable) object).getMessage(), ((Throwable) object));
toContinueForRestOfmembers = true;
break;
} else if (object instanceof Throwable) {
ResultBuilder.createGemFireErrorResult(CliStrings.format(
CliStrings.EXPORT_LOGS__MSG__FAILED_TO_EXPORT_LOG_FILES_FOR_MEMBER_0,
member.getId()));
Throwable th = (Throwable) object;
LogWrapper.getInstance().fine(CliUtil.stackTraceAsString((th)));
LogWrapper.getInstance().fine("Exporting logs for member=" + member.getId()
+ " exception=" + ((Throwable) object).getMessage(), ((Throwable) object));
toContinueForRestOfmembers = true;
break;
}
}
} else {
LogWrapper.getInstance().fine("Exporting logs for member=" + member.getId()
+ " resultList is either null or empty");
continue;
}
if (toContinueForRestOfmembers == true) {
LogWrapper.getInstance().fine("Exporting logs for member=" + member.getId()
+ " toContinueForRestOfmembers=" + toContinueForRestOfmembers);
// proceed for rest of the member
continue;
}
String rstList = (String) resultList.get(0);
LogWrapper.getInstance().fine("for member=" + member.getId()
+ "Successfully exported to directory=" + dirName + " rstList=" + rstList);
if (rstList == null || rstList.length() == 0) {
ResultBuilder.createGemFireErrorResult(CliStrings.format(
CliStrings.EXPORT_LOGS__MSG__FAILED_TO_EXPORT_LOG_FILES_FOR_MEMBER_0,
member.getId()));
LogWrapper.getInstance().fine("for member=" + member.getId() + "rstList is null");
continue;
} else if (rstList.contains("does not exist or cannot be created")) {
LogWrapper.getInstance()
.fine("for member=" + member.getId() + " does not exist or cannot be created");
return ResultBuilder.createInfoResult(CliStrings
.format(CliStrings.EXPORT_LOGS__MSG__TARGET_DIR_CANNOT_BE_CREATED, dirName));
} else if (rstList.contains(
LocalizedStrings.InternalDistributedSystem_THIS_CONNECTION_TO_A_DISTRIBUTED_SYSTEM_HAS_BEEN_DISCONNECTED
.toLocalizedString())) {
LogWrapper.getInstance()
.fine("for member=" + member.getId()
+ LocalizedStrings.InternalDistributedSystem_THIS_CONNECTION_TO_A_DISTRIBUTED_SYSTEM_HAS_BEEN_DISCONNECTED
.toLocalizedString());
// proceed for rest of the members
continue;
}
// maintain list of log files to merge only when merge option is true.
if (mergeLog == true) {
StringTokenizer st = new StringTokenizer(rstList, ";");
while (st.hasMoreTokens()) {
logsToMerge.add(st.nextToken());
}
}
}
// merge log files
if (mergeLog == true) {
LogWrapper.getInstance().fine("Successfully exported to directory=" + dirName
+ " and now merging logsToMerge=" + logsToMerge.size());
mergeLogs(logsToMerge);
return ResultBuilder
.createInfoResult("Successfully exported and merged in directory " + dirName);
}
LogWrapper.getInstance().fine("Successfully exported to directory without merging" + dirName);
return ResultBuilder.createInfoResult("Successfully exported to directory " + dirName);
} catch (Exception ex) {
LogWrapper.getInstance().info(ex.getMessage(), ex);
return ResultBuilder.createUserErrorResult(
CliStrings.EXPORT_LOGS__MSG__FUNCTION_EXCEPTION + ((LogFileFunction) function).getId());
}
}
Result mergeLogs(List<String> logsToMerge) {
// create a new process for merging
LogWrapper.getInstance().fine("Exporting logs merging logs" + logsToMerge.size());
if (logsToMerge.size() > 1) {
List<String> commandList = new ArrayList<String>();
commandList.add(System.getProperty("java.home") + File.separatorChar + "bin"
+ File.separatorChar + "java");
commandList.add("-classpath");
commandList.add(System.getProperty("java.class.path", "."));
commandList.add(MergeLogs.class.getName());
commandList
.add(logsToMerge.get(0).substring(0, logsToMerge.get(0).lastIndexOf(File.separator) + 1));
ProcessBuilder procBuilder = new ProcessBuilder(commandList);
StringBuilder output = new StringBuilder();
String errorString = new String();
try {
LogWrapper.getInstance().fine("Exporting logs now merging logs");
Process mergeProcess = procBuilder.redirectErrorStream(true).start();
mergeProcess.waitFor();
InputStream inputStream = mergeProcess.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = br.readLine()) != null) {
output.append(line).append(GfshParser.LINE_SEPARATOR);
}
mergeProcess.destroy();
} catch (Exception e) {
LogWrapper.getInstance().fine(e.getMessage());
return ResultBuilder.createUserErrorResult(
CliStrings.EXPORT_LOGS__MSG__FUNCTION_EXCEPTION + "Could not merge");
} finally {
if (errorString != null) {
output.append(errorString).append(GfshParser.LINE_SEPARATOR);
LogWrapper.getInstance().fine("Exporting logs after merging logs " + output);
}
}
if (output.toString().contains("Sucessfully merged logs")) {
LogWrapper.getInstance().fine("Exporting logs Sucessfully merged logs");
return ResultBuilder.createInfoResult("Successfully merged");
} else {
LogWrapper.getInstance().fine("Could not merge");
return ResultBuilder.createUserErrorResult(
CliStrings.EXPORT_LOGS__MSG__FUNCTION_EXCEPTION + "Could not merge");
}
}
return ResultBuilder.createInfoResult("Only one log file, nothing to merge");
}
/****
* Current implementation supports writing it to a file and returning the location of the file
*
* @param memberNameOrId
* @return Stack Trace
*/
@CliCommand(value = CliStrings.EXPORT_STACKTRACE, help = CliStrings.EXPORT_STACKTRACE__HELP)
@CliMetaData(shellOnly = false, relatedTopic = {CliStrings.TOPIC_GEODE_DEBUG_UTIL})
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public Result exportStackTrace(@CliOption(key = CliStrings.EXPORT_STACKTRACE__MEMBER,
optionContext = ConverterHint.ALL_MEMBER_IDNAME,
help = CliStrings.EXPORT_STACKTRACE__HELP) String memberNameOrId,
@CliOption(key = CliStrings.EXPORT_STACKTRACE__GROUP,
optionContext = ConverterHint.ALL_MEMBER_IDNAME,
help = CliStrings.EXPORT_STACKTRACE__GROUP) String group,
@CliOption(key = CliStrings.EXPORT_STACKTRACE__FILE,
help = CliStrings.EXPORT_STACKTRACE__FILE__HELP) String fileName,
@CliOption(key = CliStrings.EXPORT_STACKTRACE__FAIL__IF__FILE__PRESENT,
unspecifiedDefaultValue = "false",
help = CliStrings.EXPORT_STACKTRACE__FAIL__IF__FILE__PRESENT__HELP) boolean failIfFilePresent) {
Result result = null;
StringBuffer filePrefix = new StringBuffer("stacktrace");
try {
if (fileName == null) {
fileName = filePrefix.append("_").append(System.currentTimeMillis()).toString();
}
final File outFile = new File(fileName);
if (outFile.exists() && failIfFilePresent) {
return ResultBuilder.createShellClientErrorResult(CliStrings.format(
CliStrings.EXPORT_STACKTRACE__ERROR__FILE__PRESENT, outFile.getCanonicalPath()));
}
Cache cache = CacheFactory.getAnyInstance();
GemFireCacheImpl gfeCacheImpl = (GemFireCacheImpl) cache;
InternalDistributedSystem ads = gfeCacheImpl.getSystem();
InfoResultData resultData = ResultBuilder.createInfoResultData();
Map<String, byte[]> dumps = new HashMap<String, byte[]>();
Set<DistributedMember> targetMembers = null;
if ((group == null || group.isEmpty())
&& (memberNameOrId == null || memberNameOrId.isEmpty())) {
targetMembers = CliUtil.getAllMembers(cache);
} else {
targetMembers = CliUtil.findMembersOrThrow(group, memberNameOrId);
}
ResultCollector<?, ?> rc =
CliUtil.executeFunction(getStackTracesFunction, null, targetMembers);
ArrayList<Object> resultList = (ArrayList<Object>) rc.getResult();
for (Object resultObj : resultList) {
if (resultObj instanceof StackTracesPerMember) {
StackTracesPerMember stackTracePerMember = (StackTracesPerMember) resultObj;
dumps.put(stackTracePerMember.getMemberNameOrId(), stackTracePerMember.getStackTraces());
}
}
String filePath = writeStacksToFile(dumps, fileName);
resultData.addLine(CliStrings.format(CliStrings.EXPORT_STACKTRACE__SUCCESS, filePath));
resultData.addLine(CliStrings.EXPORT_STACKTRACE__HOST + ads.getDistributedMember().getHost());
result = ResultBuilder.buildResult(resultData);
} catch (CommandResultException crex) {
return crex.getResult();
} catch (Exception ex) {
result = ResultBuilder
.createGemFireErrorResult(CliStrings.EXPORT_STACKTRACE__ERROR + ex.getMessage());
}
return result;
}
/**
* Interceptor used by gfsh to intercept execution of shutdownall.
*/
public static class ExportStackTraceInterceptor extends AbstractCliAroundInterceptor {
@Override
public Result preExecution(GfshParseResult parseResult) {
Map<String, String> paramValueMap = parseResult.getParamValueStrings();
String fileName = paramValueMap.get(CliStrings.EXPORT_STACKTRACE__FILE);
Response response = readYesNo(
CliStrings.format(CliStrings.EXPORT_STACKTRACE_WARN_USER, fileName), Response.YES);
if (response == Response.NO) {
return ResultBuilder
.createShellClientAbortOperationResult(CliStrings.EXPORT_STACKTRACE_MSG_ABORTING);
} else {
// we dont to show any info result
return ResultBuilder.createInfoResult("");
}
}
@Override
public Result postExecution(GfshParseResult parseResult, Result commandResult) {
return commandResult;
}
}
/***
* Writes the Stack traces member-wise to a text file
*
* @param dumps - Map containing key : member , value : zipped stack traces
* @param fileName - Name of the file to which the stack-traces are written to
* @return Canonical path of the file which contains the stack-traces
* @throws IOException
*/
private String writeStacksToFile(Map<String, byte[]> dumps, String fileName) throws IOException {
String filePath = null;
OutputStream os = null;
PrintWriter ps = null;
File outputFile = null;
try {
outputFile = new File(fileName);
os = new FileOutputStream(outputFile);
ps = new PrintWriter(os);
for (Map.Entry<String, byte[]> entry : dumps.entrySet()) {
ps.append("*** Stack-trace for member " + entry.getKey() + " ***");
ps.flush();
GZIPInputStream zipIn = new GZIPInputStream(new ByteArrayInputStream(entry.getValue()));
BufferedInputStream bin = new BufferedInputStream(zipIn);
byte[] buffer = new byte[10000];
int count;
while ((count = bin.read(buffer)) != -1) {
os.write(buffer, 0, count);
}
ps.append('\n');
}
ps.flush();
filePath = outputFile.getCanonicalPath();
} finally {
os.close();
}
return filePath;
}
@CliCommand(value = CliStrings.SHOW_METRICS, help = CliStrings.SHOW_METRICS__HELP)
@CliMetaData(shellOnly = false, relatedTopic = {CliStrings.TOPIC_GEODE_STATISTICS})
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public Result showMetrics(
@CliOption(key = {CliStrings.SHOW_METRICS__MEMBER},
optionContext = ConverterHint.ALL_MEMBER_IDNAME,
help = CliStrings.SHOW_METRICS__MEMBER__HELP) String memberNameOrId,
@CliOption(key = {CliStrings.SHOW_METRICS__REGION}, optionContext = ConverterHint.REGIONPATH,
help = CliStrings.SHOW_METRICS__REGION__HELP) String regionName,
@CliOption(key = {CliStrings.SHOW_METRICS__FILE},
help = CliStrings.SHOW_METRICS__FILE__HELP) String export_to_report_to,
@CliOption(key = {CliStrings.SHOW_METRICS__CACHESERVER__PORT},
help = CliStrings.SHOW_METRICS__CACHESERVER__PORT__HELP) String cacheServerPortString,
@CliOption(key = {CliStrings.SHOW_METRICS__CATEGORY},
help = CliStrings.SHOW_METRICS__CATEGORY__HELP) @CliMetaData(
valueSeparator = ",") String[] categories) {
Result result = null;
try {
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
if (!export_to_report_to.endsWith(".csv")) {
return ResultBuilder
.createUserErrorResult(CliStrings.format(CliStrings.INVALID_FILE_EXTENSION, ".csv"));
}
}
if (regionName != null && !regionName.isEmpty()) {
if (!org.apache.geode.internal.lang.StringUtils.isBlank(cacheServerPortString)) {
return ResultBuilder
.createUserErrorResult(CliStrings.SHOW_METRICS__CANNOT__USE__CACHESERVERPORT);
}
// MBean names contain the forward slash
if (!regionName.startsWith("/")) {
regionName = "/" + regionName;
}
if (memberNameOrId == null || memberNameOrId.isEmpty()) {
result = ResultBuilder.buildResult(
getDistributedRegionMetrics(regionName, export_to_report_to, categories));
} else {
DistributedMember member = CliUtil.getDistributedMemberByNameOrId(memberNameOrId);
if (member != null) {
result = ResultBuilder.buildResult(
getRegionMetricsFromMember(regionName, member, export_to_report_to, categories));
} else {
ErrorResultData erd = ResultBuilder.createErrorResultData();
erd.addLine(
CliStrings.format(CliStrings.MEMBER_NOT_FOUND_ERROR_MESSAGE, memberNameOrId));
result = ResultBuilder.buildResult(erd);
}
}
} else if (memberNameOrId != null && !memberNameOrId.isEmpty()) {
DistributedMember member = CliUtil.getDistributedMemberByNameOrId(memberNameOrId);
if (member != null) {
int cacheServerPort = -1;
if (cacheServerPortString != null && !cacheServerPortString.isEmpty()) {
try {
cacheServerPort = Integer.parseInt(cacheServerPortString);
} catch (NumberFormatException nfe) {
return ResultBuilder.createUserErrorResult("Invalid port");
}
}
result = ResultBuilder.buildResult(
getMemberMetrics(member, export_to_report_to, categories, cacheServerPort));
} else {
ErrorResultData erd = ResultBuilder.createErrorResultData();
erd.addLine(CliStrings.format(CliStrings.MEMBER_NOT_FOUND_ERROR_MESSAGE, memberNameOrId));
result = ResultBuilder.buildResult(erd);
}
} else {
if (!org.apache.geode.internal.lang.StringUtils.isBlank(cacheServerPortString)) {
return ResultBuilder
.createUserErrorResult(CliStrings.SHOW_METRICS__CANNOT__USE__CACHESERVERPORT);
}
result = ResultBuilder.buildResult(getSystemWideMetrics(export_to_report_to, categories));
}
} catch (Exception e) {
return ResultBuilder.createGemFireErrorResult("#SB" + CliUtil.stackTraceAsString(e));
}
return result;
}
/****
* Gets the system wide metrics
*
* @param export_to_report_to
* @return ResultData with required System wide statistics or ErrorResultData if DS MBean is not
* found to gather metrics
* @throws Exception
*/
private ResultData getSystemWideMetrics(String export_to_report_to, String[] categoriesArr)
throws Exception {
final Cache cache = CacheFactory.getAnyInstance();
final ManagementService managmentService = ManagementService.getManagementService(cache);
DistributedSystemMXBean dsMxBean = managmentService.getDistributedSystemMXBean();
StringBuilder csvBuilder = null;
if (dsMxBean != null) {
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
csvBuilder = new StringBuilder();
csvBuilder.append("Category");
csvBuilder.append(',');
csvBuilder.append(CliStrings.SHOW_METRICS__METRIC__HEADER);
csvBuilder.append(',');
csvBuilder.append(CliStrings.SHOW_METRICS__VALUE__HEADER);
csvBuilder.append('\n');
}
CompositeResultData crd = ResultBuilder.createCompositeResultData();
SectionResultData section = crd.addSection();
TabularResultData metricsTable = section.addTable();
Map<String, Boolean> categoriesMap = getSystemMetricsCategories();
if (categoriesArr != null && categoriesArr.length != 0) {
Set<String> categories = createSet(categoriesArr);
Set<String> checkSet = new HashSet<String>(categoriesMap.keySet());
Set<String> userCategories = getSetDifference(categories, checkSet);
// Checking if the categories specified by the user are valid or not
if (userCategories.isEmpty()) {
for (String category : checkSet) {
categoriesMap.put(category, false);
}
for (String category : categories) {
categoriesMap.put(category.toLowerCase(), true);
}
} else {
StringBuilder sb = new StringBuilder();
sb.append("Invalid Categories\n");
for (String category : userCategories) {
sb.append(category);
sb.append('\n');
}
return ResultBuilder.createErrorResultData().addLine(sb.toString());
}
}
metricsTable.setHeader("Cluster-wide Metrics");
if (categoriesMap.get("cluster").booleanValue()) {
writeToTableAndCsv(metricsTable, "cluster", "totalHeapSize", dsMxBean.getTotalHeapSize(),
csvBuilder);
}
if (categoriesMap.get("cache").booleanValue()) {
writeToTableAndCsv(metricsTable, "cache", "totalRegionEntryCount",
dsMxBean.getTotalRegionEntryCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalRegionCount", dsMxBean.getTotalRegionCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalMissCount", dsMxBean.getTotalMissCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalHitCount", dsMxBean.getTotalHitCount(),
csvBuilder);
}
if (categoriesMap.get("diskstore").booleanValue()) {
writeToTableAndCsv(metricsTable, "diskstore", "totalDiskUsage",
dsMxBean.getTotalDiskUsage(), csvBuilder); // deadcoded to workaround bug 46397
writeToTableAndCsv(metricsTable, ""/* 46608 */, "diskReadsRate",
dsMxBean.getDiskReadsRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "diskWritesRate", dsMxBean.getDiskWritesRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "flushTimeAvgLatency",
dsMxBean.getDiskFlushAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalBackupInProgress",
dsMxBean.getTotalBackupInProgress(), csvBuilder);
}
if (categoriesMap.get("query").booleanValue()) {
writeToTableAndCsv(metricsTable, "query", "activeCQCount", dsMxBean.getActiveCQCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "queryRequestRate", dsMxBean.getQueryRequestRate(),
csvBuilder);
}
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
crd.addAsFile(export_to_report_to, csvBuilder.toString(),
"Cluster wide metrics exported to {0}.", false);
}
return crd;
} else {
String errorMessage =
CliStrings.format(CliStrings.SHOW_METRICS__ERROR, "Distributed System MBean not found");
return ResultBuilder.createErrorResultData().addLine(errorMessage);
}
}
/***
* Gets the Cluster wide metrics for a given member
*
* @param distributedMember
* @param export_to_report_to
* @return ResultData with required Member statistics or ErrorResultData if MemberMbean is not
* found to gather metrics
* @throws ResultDataException if building result fails
*/
private ResultData getMemberMetrics(DistributedMember distributedMember,
String export_to_report_to, String[] categoriesArr, int cacheServerPort)
throws ResultDataException {
final Cache cache = CacheFactory.getAnyInstance();
final SystemManagementService managementService =
(SystemManagementService) ManagementService.getManagementService(cache);
ObjectName memberMBeanName = managementService.getMemberMBeanName(distributedMember);
MemberMXBean memberMxBean =
managementService.getMBeanInstance(memberMBeanName, MemberMXBean.class);
ObjectName csMxBeanName = null;
CacheServerMXBean csMxBean = null;
if (memberMxBean != null) {
if (cacheServerPort != -1) {
csMxBeanName =
managementService.getCacheServerMBeanName(cacheServerPort, distributedMember);
csMxBean = managementService.getMBeanInstance(csMxBeanName, CacheServerMXBean.class);
if (csMxBean == null) {
ErrorResultData erd = ResultBuilder.createErrorResultData();
erd.addLine(CliStrings.format(CliStrings.SHOW_METRICS__CACHE__SERVER__NOT__FOUND,
cacheServerPort, MBeanJMXAdapter.getMemberNameOrId(distributedMember)));
return erd;
}
}
JVMMetrics jvmMetrics = memberMxBean.showJVMMetrics();
CompositeResultData crd = ResultBuilder.createCompositeResultData();
SectionResultData section = crd.addSection();
TabularResultData metricsTable = section.addTable();
metricsTable.setHeader("Member Metrics");
StringBuilder csvBuilder = null;
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
csvBuilder = new StringBuilder();
csvBuilder.append("Category");
csvBuilder.append(',');
csvBuilder.append(CliStrings.SHOW_METRICS__METRIC__HEADER);
csvBuilder.append(',');
csvBuilder.append(CliStrings.SHOW_METRICS__VALUE__HEADER);
csvBuilder.append('\n');
}
Map<String, Boolean> categoriesMap = getMemberMetricsCategories();
if (categoriesArr != null && categoriesArr.length != 0) {
Set<String> categories = createSet(categoriesArr);
Set<String> checkSet = new HashSet<String>(categoriesMap.keySet());
Set<String> userCategories = getSetDifference(categories, checkSet);
// Checking if the categories specified by the user are valid or not
if (userCategories.isEmpty()) {
for (String category : checkSet) {
categoriesMap.put(category, false);
}
for (String category : categories) {
categoriesMap.put(category.toLowerCase(), true);
}
} else {
StringBuilder sb = new StringBuilder();
sb.append("Invalid Categories\n");
for (String category : userCategories) {
sb.append(category);
sb.append('\n');
}
return ResultBuilder.createErrorResultData().addLine(sb.toString());
}
}
/****
* Member Metrics
*/
// member, jvm, region, serialization, communication, function, transaction, diskstore, lock,
// eviction, distribution
if (categoriesMap.get("member").booleanValue()) {
writeToTableAndCsv(metricsTable, "member", "upTime", memberMxBean.getMemberUpTime(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "cpuUsage", memberMxBean.getCpuUsage(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "currentHeapSize", memberMxBean.getCurrentHeapSize(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "maximumHeapSize", memberMxBean.getMaximumHeapSize(),
csvBuilder);
}
/****
* JVM Metrics
*/
if (categoriesMap.get("jvm").booleanValue()) {
writeToTableAndCsv(metricsTable, "jvm ", "jvmThreads ", jvmMetrics.getTotalThreads(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "fileDescriptorLimit",
memberMxBean.getFileDescriptorLimit(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalFileDescriptorOpen",
memberMxBean.getTotalFileDescriptorOpen(), csvBuilder);
}
/***
* Member wide region metrics
*/
if (categoriesMap.get("region").booleanValue()) {
writeToTableAndCsv(metricsTable, "region ", "totalRegionCount ",
memberMxBean.getTotalRegionCount(), csvBuilder);
String[] regionNames = memberMxBean.listRegions();
if (regionNames != null) {
for (int i = 0; i < regionNames.length; i++) {
if (i == 0) {
writeToTableAndCsv(metricsTable, "", "listOfRegions", regionNames[i].substring(1),
csvBuilder);
} else {
writeToTableAndCsv(metricsTable, "", "", regionNames[i].substring(1), csvBuilder);
}
}
}
String[] rootRegionNames = memberMxBean.getRootRegionNames();
if (rootRegionNames != null) {
for (int i = 0; i < rootRegionNames.length; i++) {
if (i == 0) {
writeToTableAndCsv(metricsTable, "", "rootRegions", rootRegionNames[i], csvBuilder);
} else {
writeToTableAndCsv(metricsTable, "", "", rootRegionNames[i], csvBuilder);
}
}
}
writeToTableAndCsv(metricsTable, "", "totalRegionEntryCount",
memberMxBean.getTotalRegionEntryCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalBucketCount", memberMxBean.getTotalBucketCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalPrimaryBucketCount",
memberMxBean.getTotalPrimaryBucketCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "getsAvgLatency", memberMxBean.getGetsAvgLatency(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putsAvgLatency", memberMxBean.getPutsAvgLatency(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "createsRate", memberMxBean.getCreatesRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "destroyRate", memberMxBean.getDestroysRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putAllAvgLatency", memberMxBean.getPutAllAvgLatency(),
csvBuilder);
// Not available from stats. After Stats re-org it will be avaialble
// writeToTableAndCsv(metricsTable, "", "getAllAvgLatency",
// memberMxBean.getGetAllAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalMissCount", memberMxBean.getTotalMissCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalHitCount", memberMxBean.getTotalHitCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "getsRate", memberMxBean.getGetsRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "putsRate", memberMxBean.getPutsRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "cacheWriterCallsAvgLatency",
memberMxBean.getCacheWriterCallsAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "cacheListenerCallsAvgLatency",
memberMxBean.getCacheListenerCallsAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalLoadsCompleted",
memberMxBean.getTotalLoadsCompleted(), csvBuilder);
}
/******
* SERIALIZATION
*/
if (categoriesMap.get("serialization").booleanValue()) {
writeToTableAndCsv(metricsTable, "serialization", "serializationRate",
memberMxBean.getSerializationRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "serializationLatency",
memberMxBean.getSerializationRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "deserializationRate",
memberMxBean.getDeserializationRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "deserializationLatency",
memberMxBean.getDeserializationLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "deserializationAvgLatency",
memberMxBean.getDeserializationAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "PDXDeserializationAvgLatency",
memberMxBean.getPDXDeserializationAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "PDXDeserializationRate",
memberMxBean.getPDXDeserializationRate(), csvBuilder);
}
/***
* Communication Metrics
*
*/
if (categoriesMap.get("communication").booleanValue()) {
writeToTableAndCsv(metricsTable, "communication", "bytesSentRate",
memberMxBean.getBytesSentRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "bytesReceivedRate",
memberMxBean.getBytesReceivedRate(), csvBuilder);
String[] connectedGatewayReceivers = memberMxBean.listConnectedGatewayReceivers();
writeToTableAndCsv(metricsTable, "", "connectedGatewayReceivers", connectedGatewayReceivers,
csvBuilder);
String[] connectedGatewaySenders = memberMxBean.listConnectedGatewaySenders();
writeToTableAndCsv(metricsTable, "", "connectedGatewaySenders", connectedGatewaySenders,
csvBuilder);
}
/***
* Member wide function metrics
*
*/
if (categoriesMap.get("function").booleanValue()) {
writeToTableAndCsv(metricsTable, "function", "numRunningFunctions",
memberMxBean.getNumRunningFunctions(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "functionExecutionRate",
memberMxBean.getFunctionExecutionRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "numRunningFunctionsHavingResults",
memberMxBean.getNumRunningFunctionsHavingResults(), csvBuilder);
// Not Avaialble from Stats
// writeToTableAndCsv(metricsTable, "", "funcExecutionQueueSize",
// memberMxBean.getFuncExecutionQueueSize(), csvBuilder);
}
/***
* totalTransactionsCount currentTransactionalThreadIds transactionCommitsAvgLatency
* transactionCommittedTotalCount transactionRolledBackTotalCount transactionCommitsRate
*/
if (categoriesMap.get("transaction").booleanValue()) {
writeToTableAndCsv(metricsTable, "transaction", "totalTransactionsCount",
memberMxBean.getTotalTransactionsCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "transactionCommitsAvgLatency",
memberMxBean.getTransactionCommitsAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "transactionCommittedTotalCount",
memberMxBean.getTransactionCommittedTotalCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "transactionRolledBackTotalCount",
memberMxBean.getTransactionRolledBackTotalCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "transactionCommitsRate",
memberMxBean.getTransactionCommitsRate(), csvBuilder);
}
/***
* Member wide disk metrics
*/
if (categoriesMap.get("diskstore").booleanValue()) {
writeToTableAndCsv(metricsTable, "diskstore", "totalDiskUsage",
memberMxBean.getTotalDiskUsage(), csvBuilder); // deadcoded to workaround bug 46397
writeToTableAndCsv(metricsTable, ""/* 46608 */, "diskReadsRate",
memberMxBean.getDiskReadsRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "diskWritesRate", memberMxBean.getDiskWritesRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "flushTimeAvgLatency",
memberMxBean.getDiskFlushAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalQueueSize",
memberMxBean.getTotalDiskTasksWaiting(), csvBuilder); // deadcoded to workaround bug
// 46397
writeToTableAndCsv(metricsTable, "", "totalBackupInProgress",
memberMxBean.getTotalBackupInProgress(), csvBuilder);
}
/***
* Member wide Lock
*/
if (categoriesMap.get("lock").booleanValue()) {
writeToTableAndCsv(metricsTable, "lock", "lockWaitsInProgress",
memberMxBean.getLockWaitsInProgress(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalLockWaitTime",
memberMxBean.getTotalLockWaitTime(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalNumberOfLockService",
memberMxBean.getTotalNumberOfLockService(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "requestQueues", memberMxBean.getLockRequestQueues(),
csvBuilder);
}
/****
* Eviction
*/
if (categoriesMap.get("eviction").booleanValue()) {
writeToTableAndCsv(metricsTable, "eviction", "lruEvictionRate",
memberMxBean.getLruEvictionRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "lruDestroyRate", memberMxBean.getLruDestroyRate(),
csvBuilder);
}
/***
* Distribution
*/
if (categoriesMap.get("distribution").booleanValue()) {
writeToTableAndCsv(metricsTable, "distribution", "getInitialImagesInProgress",
memberMxBean.getInitialImagesInProgres(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "getInitialImageTime",
memberMxBean.getInitialImageTime(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "getInitialImageKeysReceived",
memberMxBean.getInitialImageKeysReceived(), csvBuilder);
}
/***
* OffHeap
*/
if (categoriesMap.get("offheap").booleanValue()) {
writeToTableAndCsv(metricsTable, "offheap", "maxMemory", memberMxBean.getOffHeapMaxMemory(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "freeMemory", memberMxBean.getOffHeapFreeMemory(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "usedMemory", memberMxBean.getOffHeapUsedMemory(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "objects", memberMxBean.getOffHeapObjects(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "fragmentation",
memberMxBean.getOffHeapFragmentation(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "compactionTime",
memberMxBean.getOffHeapCompactionTime(), csvBuilder);
}
/***
* CacheServer stats
*/
if (csMxBean != null) {
writeToTableAndCsv(metricsTable, "cache-server", "clientConnectionCount",
csMxBean.getClientConnectionCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "hostnameForClients", csMxBean.getHostNameForClients(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "getRequestAvgLatency",
csMxBean.getGetRequestAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "putRequestAvgLatency",
csMxBean.getPutRequestAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalConnectionsTimedOut",
csMxBean.getTotalConnectionsTimedOut(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "threadQueueSize", csMxBean.getPutRequestAvgLatency(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "connectionThreads", csMxBean.getConnectionThreads(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "connectionLoad", csMxBean.getConnectionLoad(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "loadPerConnection", csMxBean.getLoadPerConnection(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "queueLoad", csMxBean.getQueueLoad(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "loadPerQueue", csMxBean.getLoadPerQueue(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "getRequestRate", csMxBean.getGetRequestRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putRequestRate", csMxBean.getPutRequestRate(),
csvBuilder);
/*****
* Notification
*/
writeToTableAndCsv(metricsTable, "notification", "numClientNotificationRequests",
csMxBean.getNumClientNotificationRequests(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "clientNotificationRate",
csMxBean.getClientNotificationRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "clientNotificationAvgLatency",
csMxBean.getClientNotificationAvgLatency(), csvBuilder);
/***
* Query
*/
writeToTableAndCsv(metricsTable, "query", "activeCQCount", csMxBean.getActiveCQCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "query", "queryRequestRate",
csMxBean.getQueryRequestRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "indexCount", csMxBean.getIndexCount(), csvBuilder);
String[] indexList = csMxBean.getIndexList();
writeToTableAndCsv(metricsTable, "", "index list", indexList, csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalIndexMaintenanceTime",
csMxBean.getTotalIndexMaintenanceTime(), csvBuilder);
}
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
crd.addAsFile(export_to_report_to, csvBuilder.toString(), "Member metrics exported to {0}.",
false);
}
return crd;
} else {
ErrorResultData erd = ResultBuilder.createErrorResultData();
String errorMessage = CliStrings.format(CliStrings.SHOW_METRICS__ERROR, "Member MBean for "
+ MBeanJMXAdapter.getMemberNameOrId(distributedMember) + " not found");
return ResultBuilder.createErrorResultData().addLine(errorMessage);
}
}
/****
* Gets the Cluster-wide metrics for a region
*
* @param regionName
* @return ResultData containing the table
* @throws ResultDataException if building result fails
*/
private ResultData getDistributedRegionMetrics(String regionName, String export_to_report_to,
String[] categoriesArr) throws ResultDataException {
final Cache cache = CacheFactory.getAnyInstance();
final ManagementService managementService = ManagementService.getManagementService(cache);
DistributedRegionMXBean regionMxBean = managementService.getDistributedRegionMXBean(regionName);
if (regionMxBean != null) {
CompositeResultData crd = ResultBuilder.createCompositeResultData();
SectionResultData section = crd.addSection();
TabularResultData metricsTable = section.addTable();
metricsTable.setHeader("Cluster-wide Region Metrics");
StringBuilder csvBuilder = null;
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
csvBuilder = new StringBuilder();
csvBuilder.append("Category");
csvBuilder.append(',');
csvBuilder.append(CliStrings.SHOW_METRICS__METRIC__HEADER);
csvBuilder.append(',');
csvBuilder.append(CliStrings.SHOW_METRICS__VALUE__HEADER);
csvBuilder.append('\n');
}
Map<String, Boolean> categoriesMap = getSystemRegionMetricsCategories();
if (categoriesArr != null && categoriesArr.length != 0) {
Set<String> categories = createSet(categoriesArr);
Set<String> checkSet = new HashSet<String>(categoriesMap.keySet());
Set<String> userCategories = getSetDifference(categories, checkSet);
// Checking if the categories specified by the user are valid or not
if (userCategories.isEmpty()) {
for (String category : checkSet) {
categoriesMap.put(category, false);
}
for (String category : categories) {
categoriesMap.put(category.toLowerCase(), true);
}
} else {
StringBuilder sb = new StringBuilder();
sb.append("Invalid Categories\n");
for (String category : userCategories) {
sb.append(category);
sb.append('\n');
}
return ResultBuilder.createErrorResultData().addLine(sb.toString());
}
}
/***
* General System metrics
*/
// cluster, region, partition , diskstore, callback, eviction
if (categoriesMap.get("cluster").booleanValue()) {
writeToTableAndCsv(metricsTable, "cluster", "member count", regionMxBean.getMemberCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "region entry count",
regionMxBean.getSystemRegionEntryCount(), csvBuilder);
}
if (categoriesMap.get("region").booleanValue()) {
writeToTableAndCsv(metricsTable, "region", "lastModifiedTime",
regionMxBean.getLastModifiedTime(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "lastAccessedTime", regionMxBean.getLastAccessedTime(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "missCount", regionMxBean.getMissCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "hitCount", regionMxBean.getHitCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "hitRatio", regionMxBean.getHitRatio(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "getsRate", regionMxBean.getGetsRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "putsRate", regionMxBean.getPutsRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "createsRate", regionMxBean.getCreatesRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "destroyRate", regionMxBean.getDestroyRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putAllRate", regionMxBean.getPutAllRate(),
csvBuilder);
}
if (categoriesMap.get("partition").booleanValue()) {
writeToTableAndCsv(metricsTable, "partition", "putLocalRate",
regionMxBean.getPutLocalRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "putRemoteRate", regionMxBean.getPutRemoteRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putRemoteLatency", regionMxBean.getPutRemoteLatency(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putRemoteAvgLatency",
regionMxBean.getPutRemoteAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "bucketCount", regionMxBean.getBucketCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "primaryBucketCount",
regionMxBean.getPrimaryBucketCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "numBucketsWithoutRedundancy",
regionMxBean.getNumBucketsWithoutRedundancy(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalBucketSize", regionMxBean.getTotalBucketSize(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "averageBucketSize", regionMxBean.getAvgBucketSize(),
csvBuilder);
}
/*****
* Disk store
*/
if (categoriesMap.get("diskstore").booleanValue()) {
writeToTableAndCsv(metricsTable, "diskstore", "totalEntriesOnlyOnDisk",
regionMxBean.getTotalEntriesOnlyOnDisk(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "diskReadsRate", regionMxBean.getDiskReadsRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "diskWritesRate", regionMxBean.getDiskWritesRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalDiskWriteInProgress",
regionMxBean.getTotalDiskWritesProgress(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "diskTaskWaiting", regionMxBean.getDiskTaskWaiting(),
csvBuilder);
}
/*****
* LISTENER
*/
if (categoriesMap.get("callback").booleanValue()) {
writeToTableAndCsv(metricsTable, "callback", "cacheWriterCallsAvgLatency",
regionMxBean.getCacheWriterCallsAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "cacheListenerCallsAvgLatency",
regionMxBean.getCacheListenerCallsAvgLatency(), csvBuilder);
}
/****
* Eviction
*/
if (categoriesMap.get("eviction").booleanValue()) {
writeToTableAndCsv(metricsTable, "eviction", "lruEvictionRate",
regionMxBean.getLruEvictionRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "lruDestroyRate", regionMxBean.getLruDestroyRate(),
csvBuilder);
}
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
crd.addAsFile(export_to_report_to, csvBuilder.toString(),
"Aggregate Region Metrics exported to {0}.", false);
}
return crd;
} else {
ErrorResultData erd = ResultBuilder.createErrorResultData();
String errorMessage = CliStrings.format(CliStrings.SHOW_METRICS__ERROR,
"Distributed Region MBean for " + regionName + " not found");
erd.addLine(errorMessage);
return erd;
}
}
/***
* Gets the metrics of region on a given member
*
* @param regionName
* @param distributedMember
* @param export_to_report_to
* @return ResultData with required Region statistics or ErrorResultData if Region MBean is not
* found to gather metrics
* @throws ResultDataException if building result fails
*/
private ResultData getRegionMetricsFromMember(String regionName,
DistributedMember distributedMember, String export_to_report_to, String[] categoriesArr)
throws ResultDataException {
final Cache cache = CacheFactory.getAnyInstance();
final SystemManagementService managementService =
(SystemManagementService) ManagementService.getManagementService(cache);
ObjectName regionMBeanName =
managementService.getRegionMBeanName(distributedMember, regionName);
RegionMXBean regionMxBean =
managementService.getMBeanInstance(regionMBeanName, RegionMXBean.class);
if (regionMxBean != null) {
CompositeResultData crd = ResultBuilder.createCompositeResultData();
SectionResultData section = crd.addSection();
TabularResultData metricsTable = section.addTable();
metricsTable.setHeader("Metrics for region:" + regionName + " On Member "
+ MBeanJMXAdapter.getMemberNameOrId(distributedMember));
StringBuilder csvBuilder = null;
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
csvBuilder = new StringBuilder();
csvBuilder.append("Category");
csvBuilder.append(',');
csvBuilder.append(CliStrings.SHOW_METRICS__METRIC__HEADER);
csvBuilder.append(',');
csvBuilder.append(CliStrings.SHOW_METRICS__VALUE__HEADER);
csvBuilder.append('\n');
}
/****
* Region Metrics
*/
Map<String, Boolean> categoriesMap = getRegionMetricsCategories();
if (categoriesArr != null && categoriesArr.length != 0) {
Set<String> categories = createSet(categoriesArr);
Set<String> checkSet = new HashSet<String>(categoriesMap.keySet());
Set<String> userCategories = getSetDifference(categories, checkSet);
// Checking if the categories specified by the user are valid or not
if (userCategories.isEmpty()) {
for (String category : checkSet) {
categoriesMap.put(category, false);
}
for (String category : categories) {
categoriesMap.put(category.toLowerCase(), true);
}
} else {
StringBuilder sb = new StringBuilder();
sb.append("Invalid Categories\n");
for (String category : userCategories) {
sb.append(category);
sb.append('\n');
}
return ResultBuilder.createErrorResultData().addLine(sb.toString());
}
}
if (categoriesMap.get("region").booleanValue()) {
writeToTableAndCsv(metricsTable, "region", "lastModifiedTime",
regionMxBean.getLastModifiedTime(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "lastAccessedTime", regionMxBean.getLastAccessedTime(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "missCount", regionMxBean.getMissCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "hitCount", regionMxBean.getHitCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "hitRatio", regionMxBean.getHitRatio(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "getsRate", regionMxBean.getGetsRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "putsRate", regionMxBean.getPutsRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "createsRate", regionMxBean.getCreatesRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "destroyRate", regionMxBean.getDestroyRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putAllRate", regionMxBean.getPutAllRate(),
csvBuilder);
}
if (categoriesMap.get("partition").booleanValue()) {
writeToTableAndCsv(metricsTable, "partition", "putLocalRate",
regionMxBean.getPutLocalRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "putRemoteRate", regionMxBean.getPutRemoteRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putRemoteLatency", regionMxBean.getPutRemoteLatency(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "putRemoteAvgLatency",
regionMxBean.getPutRemoteAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "bucketCount", regionMxBean.getBucketCount(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "primaryBucketCount",
regionMxBean.getPrimaryBucketCount(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "configuredRedundancy",
regionMxBean.getConfiguredRedundancy(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "actualRedundancy", regionMxBean.getActualRedundancy(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "numBucketsWithoutRedundancy",
regionMxBean.getNumBucketsWithoutRedundancy(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalBucketSize", regionMxBean.getTotalBucketSize(),
csvBuilder);
// writeToTableAndCsv(metricsTable, "", "averageBucketSize",
// regionMxBean.getAvgBucketSize(), csvBuilder);
}
/*****
* Disk store
*/
if (categoriesMap.get("diskstore").booleanValue()) {
writeToTableAndCsv(metricsTable, "diskstore", "totalEntriesOnlyOnDisk",
regionMxBean.getTotalEntriesOnlyOnDisk(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "diskReadsRate", "" + regionMxBean.getDiskReadsRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "diskWritesRate", regionMxBean.getDiskWritesRate(),
csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalDiskWriteInProgress",
regionMxBean.getTotalDiskWritesProgress(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "diskTaskWaiting", regionMxBean.getDiskTaskWaiting(),
csvBuilder);
}
/*****
* LISTENER
*/
if (categoriesMap.get("callback").booleanValue()) {
writeToTableAndCsv(metricsTable, "callback", "cacheWriterCallsAvgLatency",
regionMxBean.getCacheWriterCallsAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "cacheListenerCallsAvgLatency",
regionMxBean.getCacheListenerCallsAvgLatency(), csvBuilder);
}
/****
* Eviction
*/
if (categoriesMap.get("eviction").booleanValue()) {
writeToTableAndCsv(metricsTable, "eviction", "lruEvictionRate",
regionMxBean.getLruEvictionRate(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "lruDestroyRate", regionMxBean.getLruDestroyRate(),
csvBuilder);
}
if (export_to_report_to != null && !export_to_report_to.isEmpty()) {
crd.addAsFile(export_to_report_to, csvBuilder.toString(), "Region Metrics exported to {0}.",
false);
}
return crd;
} else {
ErrorResultData erd = ResultBuilder.createErrorResultData();
String errorMessage = CliStrings.format(CliStrings.SHOW_METRICS__ERROR,
"Region MBean for " + regionName + " on member "
+ MBeanJMXAdapter.getMemberNameOrId(distributedMember) + " not found");
erd.addLine(errorMessage);
return erd;
}
}
/***
* Writes an entry to a TabularResultData and writes a comma separated entry to a string builder
*
* @param metricsTable
* @param type
* @param metricName
* @param metricValue
* @param csvBuilder
*/
private void writeToTableAndCsv(TabularResultData metricsTable, String type, String metricName,
long metricValue, StringBuilder csvBuilder) {
metricsTable.accumulate(CliStrings.SHOW_METRICS__TYPE__HEADER, type);
metricsTable.accumulate(CliStrings.SHOW_METRICS__METRIC__HEADER, metricName);
metricsTable.accumulate(CliStrings.SHOW_METRICS__VALUE__HEADER, metricValue);
if (csvBuilder != null) {
csvBuilder.append(type);
csvBuilder.append(',');
csvBuilder.append(metricName);
csvBuilder.append(',');
csvBuilder.append(metricValue);
csvBuilder.append('\n');
}
}
/***
*
* @param metricsTable
* @param type
* @param metricName
* @param metricValue
* @param csvBuilder
*/
private void writeToTableAndCsv(TabularResultData metricsTable, String type, String metricName,
double metricValue, StringBuilder csvBuilder) {
metricsTable.accumulate(CliStrings.SHOW_METRICS__TYPE__HEADER, type);
metricsTable.accumulate(CliStrings.SHOW_METRICS__METRIC__HEADER, metricName);
metricsTable.accumulate(CliStrings.SHOW_METRICS__VALUE__HEADER, Double.valueOf(metricValue));
if (csvBuilder != null) {
csvBuilder.append(type);
csvBuilder.append(',');
csvBuilder.append(metricName);
csvBuilder.append(',');
csvBuilder.append(metricValue);
csvBuilder.append('\n');
}
}
private Set<String> createSet(String[] categories) {
Set<String> categoriesSet = new HashSet<String>();
for (String category : categories) {
categoriesSet.add(category);
}
return categoriesSet;
}
/****
* Defines and returns map of categories for System metrics.
*
* @return map with categories for system metrics and display flag set to true
*/
private Map<String, Boolean> getSystemMetricsCategories() {
Map<String, Boolean> categories = new HashMap<String, Boolean>();
categories.put("cluster", true);
categories.put("cache", true);
categories.put("diskstore", true);
categories.put("query", true);
return categories;
}
/****
* Defines and returns map of categories for Region Metrics
*
* @return map with categories for region metrics and display flag set to true
*/
private Map<String, Boolean> getRegionMetricsCategories() {
Map<String, Boolean> categories = new HashMap<String, Boolean>();
categories.put("region", true);
categories.put("partition", true);
categories.put("diskstore", true);
categories.put("callback", true);
categories.put("gatewayreceiver", true);
categories.put("distribution", true);
categories.put("query", true);
categories.put("eviction", true);
return categories;
}
/****
* Defines and returns map of categories for system-wide region metrics
*
* @return map with categories for system wide region metrics and display flag set to true
*/
private Map<String, Boolean> getSystemRegionMetricsCategories() {
Map<String, Boolean> categories = getRegionMetricsCategories();
categories.put("cluster", true);
return categories;
}
/*****
* Defines and returns map of categories for member metrics
*
* @return map with categories for member metrics and display flag set to true
*/
private Map<String, Boolean> getMemberMetricsCategories() {
Map<String, Boolean> categories = new HashMap<String, Boolean>();
categories.put("member", true);
categories.put("jvm", true);
categories.put("region", true);
categories.put("serialization", true);
categories.put("communication", true);
categories.put("function", true);
categories.put("transaction", true);
categories.put("diskstore", true);
categories.put("lock", true);
categories.put("eviction", true);
categories.put("distribution", true);
categories.put("offheap", true);
return categories;
}
/***
* Converts an array of strings to a String delimited by a new line character for display purposes
*
* @param names
* @param startIndex
* @return a String delimited by a new line character for display purposes
*/
private String formatNames(String[] names, int startIndex) {
StringBuilder sb = new StringBuilder();
if (names != null) {
for (String name : names) {
sb.append(name.substring(startIndex));
sb.append('\n');
}
}
return sb.toString();
}
private void writeToTableAndCsv(TabularResultData metricsTable, String type, String metricName,
String metricValue[], StringBuilder csvBuilder) {
if (metricValue != null) {
for (int i = 0; i < metricValue.length; i++) {
if (i == 0) {
writeToTableAndCsv(metricsTable, type, metricName, metricValue[i], csvBuilder);
} else {
writeToTableAndCsv(metricsTable, "", "", metricValue[i], csvBuilder);
}
}
}
}
/***
* Writes to a TabularResultData and also appends a CSV string to a String builder
*
* @param metricsTable
* @param type
* @param metricName
* @param metricValue
* @param csvBuilder
*/
private void writeToTableAndCsv(TabularResultData metricsTable, String type, String metricName,
String metricValue, StringBuilder csvBuilder) {
metricsTable.accumulate(CliStrings.SHOW_METRICS__TYPE__HEADER, type);
metricsTable.accumulate(CliStrings.SHOW_METRICS__METRIC__HEADER, metricName);
metricsTable.accumulate(CliStrings.SHOW_METRICS__VALUE__HEADER, metricValue);
if (csvBuilder != null) {
csvBuilder.append(type);
csvBuilder.append(',');
csvBuilder.append(metricName);
csvBuilder.append(',');
csvBuilder.append(metricValue);
csvBuilder.append('\n');
}
}
@CliCommand(value = CliStrings.CHANGE_LOGLEVEL, help = CliStrings.CHANGE_LOGLEVEL__HELP)
@CliMetaData(relatedTopic = {CliStrings.TOPIC_CHANGELOGLEVEL})
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.WRITE)
public Result changeLogLevel(
@CliOption(key = CliStrings.CHANGE_LOGLEVEL__MEMBER, unspecifiedDefaultValue = "",
help = CliStrings.CHANGE_LOGLEVEL__MEMBER__HELP) String[] memberIds,
@CliOption(key = CliStrings.CHANGE_LOGLEVEL__GROUPS, unspecifiedDefaultValue = "",
help = CliStrings.CHANGE_LOGLEVEL__GROUPS__HELP) String[] grps,
@CliOption(key = CliStrings.CHANGE_LOGLEVEL__LOGLEVEL,
optionContext = ConverterHint.LOG_LEVEL, mandatory = true, unspecifiedDefaultValue = "",
help = CliStrings.CHANGE_LOGLEVEL__LOGLEVEL__HELP) String logLevel) {
try {
if ((memberIds == null || memberIds.length == 0) && (grps == null || grps.length == 0)) {
return ResultBuilder
.createUserErrorResult(CliStrings.CHANGE_LOGLEVEL__MSG__SPECIFY_GRP_OR_MEMBER);
}
if (logLevel == null || logLevel.length() == 0) {
return ResultBuilder
.createUserErrorResult(CliStrings.CHANGE_LOGLEVEL__MSG__SPECIFY_LOG_LEVEL);
}
Cache cache = GemFireCacheImpl.getInstance();
LogWriter logger = cache.getLogger();
boolean validLogLevel = false;
for (int i = 0; i < LogWriterImpl.allLevels.length - 1; i++) {
if (LogWriterImpl.allLevels[i] == LogWriterImpl.levelNameToCode(logLevel)) {
validLogLevel = true;
break;
}
}
if (!validLogLevel) {
return ResultBuilder
.createUserErrorResult(CliStrings.CHANGE_LOGLEVEL__MSG__INVALID_LOG_LEVEL);
}
Set<DistributedMember> dsMembers = new HashSet<DistributedMember>();
Set<DistributedMember> ds = CliUtil.getAllMembers(cache);
if (grps != null && grps.length > 0) {
for (String grp : grps) {
dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(grp));
}
}
if (memberIds != null && memberIds.length > 0) {
for (String member : memberIds) {
Iterator<DistributedMember> it = ds.iterator();
while (it.hasNext()) {
DistributedMember mem = it.next();
if (mem.getName() == null ? false
: mem.getName().equals(member) || mem.getId().equals(member)) {
dsMembers.add(mem);
break;
}
}
}
}
if (dsMembers.size() == 0) {
return ResultBuilder.createGemFireErrorResult(CliStrings.CHANGE_LOGLEVEL__MSG_NO_MEMBERS);
}
Function logFunction = new ChangeLogLevelFunction();
FunctionService.registerFunction(logFunction);
Object[] functionArgs = new Object[1];
functionArgs[0] = logLevel;
CompositeResultData compositeResultData = ResultBuilder.createCompositeResultData();
SectionResultData section = compositeResultData.addSection("section");
TabularResultData resultTable = section.addTable("ChangeLogLevel");
resultTable = resultTable.setHeader("Summary");
Execution execution = FunctionService.onMembers(dsMembers).withArgs(functionArgs);
if (execution == null) {
return ResultBuilder.createUserErrorResult(CliStrings.CHANGE_LOGLEVEL__MSG__CANNOT_EXECUTE);
}
List<?> resultList = (List<?>) execution.execute(logFunction).getResult();
for (Object object : resultList) {
try {
if (object instanceof Throwable) {
logger.warning(
"Exception in ChangeLogLevelFunction " + ((Throwable) object).getMessage(),
((Throwable) object));
continue;
}
if (object != null) {
Map<String, String> resultMap = (Map<String, String>) object;
Entry<String, String> entry = resultMap.entrySet().iterator().next();
if (entry.getValue().contains("ChangeLogLevelFunction exception")) {
resultTable.accumulate(CliStrings.CHANGE_LOGLEVEL__COLUMN_MEMBER, entry.getKey());
resultTable.accumulate(CliStrings.CHANGE_LOGLEVEL__COLUMN_STATUS, "false");
} else {
resultTable.accumulate(CliStrings.CHANGE_LOGLEVEL__COLUMN_MEMBER, entry.getKey());
resultTable.accumulate(CliStrings.CHANGE_LOGLEVEL__COLUMN_STATUS, "true");
}
}
} catch (Exception ex) {
LogWrapper.getInstance().warning("change log level command exception " + ex);
continue;
}
}
Result result = ResultBuilder.buildResult(compositeResultData);
logger.info("change log-level command result=" + result);
return result;
} catch (Exception ex) {
GemFireCacheImpl.getInstance().getLogger().error("GFSH Changeloglevel exception: " + ex);
return ResultBuilder.createUserErrorResult(ex.getMessage());
}
}
@CliAvailabilityIndicator({CliStrings.SHUTDOWN, CliStrings.GC, CliStrings.SHOW_DEADLOCK,
CliStrings.SHOW_METRICS, CliStrings.SHOW_LOG, CliStrings.EXPORT_STACKTRACE,
CliStrings.NETSTAT, CliStrings.EXPORT_LOGS, CliStrings.CHANGE_LOGLEVEL})
public boolean shutdownCommandAvailable() {
boolean isAvailable = true; // always available on server
if (CliUtil.isGfshVM()) { // in gfsh check if connected
isAvailable = getGfsh() != null && getGfsh().isConnectedAndReady();
}
return isAvailable;
}
private Set<String> getSetDifference(Set<String> set1, Set<String> set2) {
Set<String> setDifference = new HashSet<String>();
for (String element : set1) {
if (!(set2.contains(element.toLowerCase()))) {
setDifference.add(element);
}
}
return setDifference;
}
}