You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2017/08/11 22:06:32 UTC
[4/4] geode git commit: GEODE-3265: Refactoring MiscellaneousCommands
GEODE-3265: Refactoring MiscellaneousCommands
This closes #696
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/63169699
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/63169699
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/63169699
Branch: refs/heads/develop
Commit: 63169699e933f6e0fdd90b95ed039e4e3c92c32c
Parents: cf91426
Author: YehEmily <em...@gmail.com>
Authored: Mon Aug 7 15:37:23 2017 -0700
Committer: Kirk Lund <kl...@apache.org>
Committed: Fri Aug 11 14:54:59 2017 -0700
----------------------------------------------------------------------
.../cli/commands/ChangeLogLevelCommand.java | 163 ++
.../cli/commands/ExportStackTraceCommand.java | 157 ++
.../internal/cli/commands/GCCommand.java | 131 ++
.../cli/commands/MiscellaneousCommands.java | 1927 ------------------
.../internal/cli/commands/NetstatCommand.java | 212 ++
.../cli/commands/ShowDeadlockCommand.java | 92 +
.../internal/cli/commands/ShowLogCommand.java | 102 +
.../cli/commands/ShowMetricsCommand.java | 1085 ++++++++++
.../internal/cli/commands/ShutdownCommand.java | 209 ++
.../MiscellaneousCommandsController.java | 16 +-
.../cli/commands/LogLevelInterceptorTest.java | 19 +-
.../MiscellaneousCommandsDUnitTest.java | 136 +-
12 files changed, 2244 insertions(+), 2005 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/63169699/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ChangeLogLevelCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ChangeLogLevelCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ChangeLogLevelCommand.java
new file mode 100644
index 0000000..823c113
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ChangeLogLevelCommand.java
@@ -0,0 +1,163 @@
+/*
+ * 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.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.LogWriter;
+import org.apache.geode.cache.execute.Execution;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionService;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.logging.log4j.LogLevel;
+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.cli.AbstractCliAroundInterceptor;
+import org.apache.geode.management.internal.cli.CliUtil;
+import org.apache.geode.management.internal.cli.GfshParseResult;
+import org.apache.geode.management.internal.cli.LogWrapper;
+import org.apache.geode.management.internal.cli.functions.ChangeLogLevelFunction;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.CompositeResultData;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.result.TabularResultData;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission;
+
+public class ChangeLogLevelCommand implements GfshCommand {
+ @CliCommand(value = CliStrings.CHANGE_LOGLEVEL, help = CliStrings.CHANGE_LOGLEVEL__HELP)
+ @CliMetaData(relatedTopic = {CliStrings.TOPIC_LOGS},
+ interceptor = "org.apache.geode.management.internal.cli.commands.ChangeLogLevelCommand$ChangeLogLevelCommandInterceptor")
+ @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
+ operation = ResourcePermission.Operation.WRITE)
+ public Result changeLogLevel(
+ @CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
+ help = CliStrings.CHANGE_LOGLEVEL__MEMBER__HELP) String[] memberIds,
+ @CliOption(key = {CliStrings.GROUP, CliStrings.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);
+ }
+
+ InternalCache cache = GemFireCacheImpl.getInstance();
+ LogWriter logger = cache.getLogger();
+
+ Set<DistributedMember> dsMembers = new HashSet<>();
+ 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) {
+ for (DistributedMember mem : ds) {
+ if (mem.getName() != null
+ && (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();
+ CompositeResultData.SectionResultData section = compositeResultData.addSection("section");
+ TabularResultData resultTable = section.addTable("ChangeLogLevel");
+ resultTable = resultTable.setHeader("Summary");
+
+ Execution execution = FunctionService.onMembers(dsMembers).setArguments(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;
+ Map.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);
+ }
+ }
+
+ 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());
+ }
+ }
+
+ public static class ChangeLogLevelCommandInterceptor extends AbstractCliAroundInterceptor {
+ @Override
+ public Result preExecution(GfshParseResult parseResult) {
+ Map<String, String> arguments = parseResult.getParamValueStrings();
+ // validate log level
+ String logLevel = arguments.get("loglevel");
+ if (StringUtils.isBlank(logLevel) || LogLevel.getLevel(logLevel) == null) {
+ return ResultBuilder.createUserErrorResult("Invalid log level: " + logLevel);
+ }
+
+ return ResultBuilder.createInfoResult("");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/63169699/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportStackTraceCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportStackTraceCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportStackTraceCommand.java
new file mode 100644
index 0000000..4f8693d
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportStackTraceCommand.java
@@ -0,0 +1,157 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.GZIPInputStream;
+
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.execute.ResultCollector;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.cache.InternalCache;
+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.cli.CliUtil;
+import org.apache.geode.management.internal.cli.domain.StackTracesPerMember;
+import org.apache.geode.management.internal.cli.functions.GetStackTracesFunction;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.InfoResultData;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission;
+
+public class ExportStackTraceCommand implements GfshCommand {
+ private final GetStackTracesFunction getStackTracesFunction = new GetStackTracesFunction();
+
+ /**
+ * Current implementation supports writing it to a file and returning the location of the file
+ */
+ @CliCommand(value = CliStrings.EXPORT_STACKTRACE, help = CliStrings.EXPORT_STACKTRACE__HELP)
+ @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_DEBUG_UTIL})
+ @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
+ operation = ResourcePermission.Operation.READ)
+ public Result exportStackTrace(@CliOption(key = {CliStrings.MEMBER, CliStrings.MEMBERS},
+ optionContext = ConverterHint.ALL_MEMBER_IDNAME,
+ help = CliStrings.EXPORT_STACKTRACE__HELP) String[] memberNameOrId,
+
+ @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+ optionContext = ConverterHint.ALL_MEMBER_IDNAME, help = CliStrings.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;
+ StringBuilder filePrefix = new StringBuilder("stacktrace");
+
+ if (fileName == null) {
+ fileName = filePrefix.append("_").append(System.currentTimeMillis()).toString();
+ }
+ final File outFile = new File(fileName);
+ try {
+ if (outFile.exists() && failIfFilePresent) {
+ return ResultBuilder.createShellClientErrorResult(CliStrings.format(
+ CliStrings.EXPORT_STACKTRACE__ERROR__FILE__PRESENT, outFile.getCanonicalPath()));
+ }
+
+
+ InternalCache cache = getCache();
+ InternalDistributedSystem ads = cache.getInternalDistributedSystem();
+
+ InfoResultData resultData = ResultBuilder.createInfoResultData();
+
+ Map<String, byte[]> dumps = new HashMap<>();
+ Set<DistributedMember> targetMembers = CliUtil.findMembers(group, memberNameOrId);
+ if (targetMembers.isEmpty()) {
+ return ResultBuilder.createUserErrorResult(CliStrings.NO_MEMBERS_FOUND_MESSAGE);
+ }
+
+ 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 (IOException ex) {
+ result = ResultBuilder
+ .createGemFireErrorResult(CliStrings.EXPORT_STACKTRACE__ERROR + ex.getMessage());
+ }
+ return result;
+ }
+
+ /***
+ * 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;
+ PrintWriter ps;
+ File outputFile;
+
+ outputFile = new File(fileName);
+ try (OutputStream os = new FileOutputStream(outputFile)) {
+ ps = new PrintWriter(os);
+
+ for (Map.Entry<String, byte[]> entry : dumps.entrySet()) {
+ ps.append("*** Stack-trace for member ").append(entry.getKey()).append(" ***");
+ 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();
+ }
+
+ return filePath;
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/63169699/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GCCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GCCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GCCommand.java
new file mode 100644
index 0000000..4884d6d
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GCCommand.java
@@ -0,0 +1,131 @@
+/*
+ * 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.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.cache.InternalCache;
+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.cli.CliUtil;
+import org.apache.geode.management.internal.cli.LogWrapper;
+import org.apache.geode.management.internal.cli.functions.GarbageCollectionFunction;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.CompositeResultData;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.result.TabularResultData;
+import org.apache.geode.management.internal.security.ResourceOperation;
+import org.apache.geode.security.ResourcePermission;
+
+public class GCCommand implements GfshCommand {
+ @CliCommand(value = CliStrings.GC, help = CliStrings.GC__HELP)
+ @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_DEBUG_UTIL})
+ @ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
+ operation = ResourcePermission.Operation.MANAGE)
+ public Result gc(
+ @CliOption(key = {CliStrings.GROUP, CliStrings.GROUPS},
+ help = CliStrings.GC__GROUP__HELP) String[] groups,
+ @CliOption(key = CliStrings.MEMBER, optionContext = ConverterHint.ALL_MEMBER_IDNAME,
+ help = CliStrings.GC__MEMBER__HELP) String memberId) {
+ InternalCache cache = getCache();
+ Result result;
+ CompositeResultData gcResultTable = ResultBuilder.createCompositeResultData();
+ TabularResultData resultTable = gcResultTable.addSection().addTable("Table1");
+ String headerText = "GC Summary";
+ resultTable.setHeader(headerText);
+ Set<DistributedMember> dsMembers = new HashSet<>();
+ 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(resultTable, dsMembers);
+ } else if (groups != null && groups.length > 0) {
+ for (String group : groups) {
+ dsMembers.addAll(cache.getDistributedSystem().getGroupMembers(group));
+ }
+ result = executeAndBuildResult(resultTable, dsMembers);
+
+ } else {
+ // gc on entire cluster
+ // exclude locators
+ dsMembers = CliUtil.getAllNormalMembers(cache);
+ result = executeAndBuildResult(resultTable, dsMembers);
+
+ }
+ return result;
+ }
+
+ private Result executeAndBuildResult(TabularResultData resultTable,
+ Set<DistributedMember> dsMembers) {
+ try {
+ List<?> resultList;
+ Function garbageCollectionFunction = new GarbageCollectionFunction();
+ resultList =
+ (List<?>) CliUtil.executeFunction(garbageCollectionFunction, null, dsMembers).getResult();
+
+ for (Object object : resultList) {
+ 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, resultMap.get("MemberId"),
+ resultMap.get("HeapSizeBeforeGC"), resultMap.get("HeapSizeAfterGC"),
+ 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);
+ }
+
+ private 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);
+ }
+}