You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2017/02/13 19:05:42 UTC
[2/2] geode git commit: GEODE-2416: Collect together artifacts from
individual servers into a single zip file
GEODE-2416: Collect together artifacts from individual servers into a single zip file
- GEODE-2414: Determine a mechanism to stream a zip file from server to locator
- GEODE-2415: Write a function to return a zip file for a single server
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/d5d7e800
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/d5d7e800
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/d5d7e800
Branch: refs/heads/feature/GEODE-2267
Commit: d5d7e80011d1cc11468be769acd2bc1b517b766d
Parents: 652e9a5
Author: Jared Stewart <js...@pivotal.io>
Authored: Sun Feb 12 11:30:58 2017 -0800
Committer: Jinmei Liao <ji...@pivotal.io>
Committed: Mon Feb 13 10:58:47 2017 -0800
----------------------------------------------------------------------
.../cli/commands/MiscellaneousCommands.java | 312 ++++---------------
.../cli/functions/ExportLogsFunction.java | 185 +++++++++++
.../cli/util/ExportLogsCacheWriter.java | 75 +++++
.../internal/cli/util/LogExporter.java | 136 ++++++++
.../management/internal/cli/util/LogFilter.java | 113 +++++++
.../internal/cli/util/LogLevelExtractor.java | 65 ++++
.../internal/configuration/utils/ZipUtils.java | 3 +-
.../internal/cli/commands/ExportLogsDUnit.java | 122 ++++++++
...laneousCommandsExportLogsPart1DUnitTest.java | 137 --------
...laneousCommandsExportLogsPart2DUnitTest.java | 141 ---------
...laneousCommandsExportLogsPart3DUnitTest.java | 155 ---------
...laneousCommandsExportLogsPart4DUnitTest.java | 137 --------
.../cli/functions/ExportLogsFunctionTest.java | 118 +++++++
.../internal/cli/util/LogExporterTest.java | 104 +++++++
.../internal/cli/util/LogFilterTest.java | 126 ++++++++
.../cli/util/LogLevelExtractorTest.java | 61 ++++
.../configuration/EventTestCacheWriter.java | 36 +++
.../test/dunit/rules/LocatorStarterRule.java | 11 +
.../test/dunit/rules/ServerStarterRule.java | 9 +-
19 files changed, 1222 insertions(+), 824 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommands.java
index bbf0542..b30633a 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommands.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommands.java
@@ -24,10 +24,10 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
-import java.sql.Time;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.text.MessageFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -38,7 +38,6 @@ 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;
@@ -50,9 +49,11 @@ import java.util.zip.DataFormatException;
import java.util.zip.GZIPInputStream;
import javax.management.ObjectName;
+import org.apache.commons.io.FileUtils;
import org.apache.geode.LogWriter;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.cache.Region;
import org.apache.geode.cache.execute.Execution;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.FunctionException;
@@ -65,8 +66,7 @@ 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.LogService;
import org.apache.geode.internal.logging.LogWriterImpl;
import org.apache.geode.management.CacheServerMXBean;
import org.apache.geode.management.DistributedRegionMXBean;
@@ -89,9 +89,9 @@ 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.ExportLogsFunction;
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;
@@ -109,17 +109,19 @@ 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.cli.util.ExportLogsCacheWriter;
+import org.apache.geode.management.internal.configuration.utils.ZipUtils;
import org.apache.geode.management.internal.security.ResourceOperation;
import org.apache.geode.security.ResourcePermission.Operation;
import org.apache.geode.security.ResourcePermission.Resource;
+import org.apache.logging.log4j.Logger;
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 {
@@ -145,8 +147,6 @@ public class MiscellaneousCommands implements CommandMarker {
logger.info("Gfsh executing shutdown on members " + includeMembers);
-
-
Callable<String> shutdownNodes = new Callable<String>() {
@Override
@@ -210,8 +210,6 @@ public class MiscellaneousCommands implements CommandMarker {
locators.removeAll(dataNodes);
-
-
if (!shutdownLocators && numDataNodes == 0) {
return ResultBuilder.createInfoResult(CliStrings.SHUTDOWN__MSG__NO_DATA_NODE_FOUND);
}
@@ -248,8 +246,8 @@ public class MiscellaneousCommands implements CommandMarker {
}
if (locators.contains(manager) && !shutdownLocators) { // This means manager is a locator and
- // shutdownLocators is false. Hence we
- // should not stop the manager
+ // shutdownLocators is false. Hence we
+ // should not stop the manager
return ResultBuilder.createInfoResult("Shutdown is triggered");
}
// now shut down this manager
@@ -272,12 +270,9 @@ public class MiscellaneousCommands implements CommandMarker {
}
/**
- *
* @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 {
@@ -290,9 +285,9 @@ public class MiscellaneousCommands implements CommandMarker {
long timeElapsed = shutDownTimeEnd - shutDownTimeStart;
if (timeElapsed > timeout || Boolean.getBoolean("ThrowTimeoutException")) { // The second check
- // for
- // ThrowTimeoutException
- // is a test hook
+ // for
+ // ThrowTimeoutException
+ // is a test hook
throw new TimeoutException();
}
return timeElapsed;
@@ -532,7 +527,7 @@ public class MiscellaneousCommands implements CommandMarker {
}
resultData.addAsFile(saveToFile, resultInfo.toString(),
CliStrings.NETSTAT__MSG__SAVED_OUTPUT_IN_0, false); // Note: substitution for {0} will
- // happen on client side.
+ // happen on client side.
} else {
resultData.addLine(resultInfo.toString());
}
@@ -694,87 +689,6 @@ public class MiscellaneousCommands implements CommandMarker {
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})
@@ -789,7 +703,7 @@ public class MiscellaneousCommands implements CommandMarker {
@CliOption(key = CliStrings.EXPORT_LOGS__MEMBER,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
optionContext = ConverterHint.ALL_MEMBER_IDNAME,
- help = CliStrings.EXPORT_LOGS__MEMBER__HELP) String memberId,
+ help = CliStrings.EXPORT_LOGS__MEMBER__HELP) String[] memberIds,
@CliOption(key = CliStrings.EXPORT_LOGS__LOGLEVEL,
unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE,
optionContext = ConverterHint.LOG_LEVEL,
@@ -806,151 +720,51 @@ public class MiscellaneousCommands implements CommandMarker {
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;
- }
+ GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+ Region region = ExportLogsFunction.createOrGetExistingExportLogsRegion(true);
+ ExportLogsCacheWriter cacheWriter =
+ (ExportLogsCacheWriter) region.getAttributes().getCacheWriter();
- 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;
- }
+ // TODO: Make this work for locators as well
+ Set<DistributedMember> targetServers = CliUtil.findMembers(groups, memberIds);
+ Logger logger = LogService.getLogger();
- 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;
+ Map<String, Path> zipFilesFromMembers = new HashMap<>();
+ for (DistributedMember server : targetServers) {
+ cacheWriter.startFile(server.getName());
- 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;
- }
+ CliUtil
+ .executeFunction(new ExportLogsFunction(),
+ new ExportLogsFunction.Args(start, end, logLevel, onlyLogLevel), server)
+ .getResult();
+ Path zipFile = cacheWriter.endFile();
+ logger.info("Recieved zip file from member " + server.getId() + ": " + zipFile.toString());
+ zipFilesFromMembers.put(server.getId(), zipFile);
+ }
- 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;
- }
+ Path tempDir = Files.createTempDirectory("exportedLogs");
+ Path exportedLogsDir = tempDir.resolve("exportedLogs");
- if (toContinueForRestOfmembers == true) {
- LogWrapper.getInstance().fine("Exporting logs for member=" + member.getId()
- + " toContinueForRestOfmembers=" + toContinueForRestOfmembers);
- // proceed for rest of the member
- continue;
- }
+ for (Path zipFile : zipFilesFromMembers.values()) {
+ Path unzippedMemberDir =
+ exportedLogsDir.resolve(zipFile.getFileName().toString().replace(".zip", ""));
+ ZipUtils.unzip(zipFile.toAbsolutePath().toString(), unzippedMemberDir.toString());
+ FileUtils.deleteQuietly(zipFile.toFile());
+ }
- 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;
- }
+ Path exportedLogsZipFile = Paths.get("exportedLogs[" + System.currentTimeMillis() + "].zip");
+
+ logger.info("Zipping into: " + exportedLogsZipFile.toString());
+ ZipUtils.zipDirectory(exportedLogsDir, exportedLogsZipFile);
+ FileUtils.deleteDirectory(tempDir.toFile());
- // 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());
+ LogWrapper.getInstance().fine(ex.getMessage());
+ result = ResultBuilder.createUserErrorResult(ex.getMessage());
}
+
+ LogWrapper.getInstance().fine("Exporting logs returning =" + result);
+ return result;
}
Result mergeLogs(List<String> logsToMerge) {
@@ -1112,7 +926,7 @@ public class MiscellaneousCommands implements CommandMarker {
/***
* 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
@@ -1266,7 +1080,6 @@ public class MiscellaneousCommands implements CommandMarker {
csvBuilder.append('\n');
}
-
CompositeResultData crd = ResultBuilder.createCompositeResultData();
SectionResultData section = crd.addSection();
TabularResultData metricsTable = section.addTable();
@@ -1410,7 +1223,6 @@ public class MiscellaneousCommands implements CommandMarker {
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) {
@@ -1604,7 +1416,7 @@ public class MiscellaneousCommands implements CommandMarker {
memberMxBean.getDiskFlushAvgLatency(), csvBuilder);
writeToTableAndCsv(metricsTable, "", "totalQueueSize",
memberMxBean.getTotalDiskTasksWaiting(), csvBuilder); // deadcoded to workaround bug
- // 46397
+ // 46397
writeToTableAndCsv(metricsTable, "", "totalBackupInProgress",
memberMxBean.getTotalBackupInProgress(), csvBuilder);
}
@@ -2059,7 +1871,7 @@ public class MiscellaneousCommands implements CommandMarker {
/***
* Writes an entry to a TabularResultData and writes a comma separated entry to a string builder
- *
+ *
* @param metricsTable
* @param type
* @param metricName
@@ -2116,7 +1928,7 @@ public class MiscellaneousCommands implements CommandMarker {
/****
* 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() {
@@ -2130,7 +1942,7 @@ public class MiscellaneousCommands implements CommandMarker {
/****
* 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() {
@@ -2149,7 +1961,7 @@ public class MiscellaneousCommands implements CommandMarker {
/****
* 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() {
@@ -2160,7 +1972,7 @@ public class MiscellaneousCommands implements CommandMarker {
/*****
* 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() {
@@ -2214,7 +2026,7 @@ public class MiscellaneousCommands implements CommandMarker {
/***
* Writes to a TabularResultData and also appends a CSV string to a String builder
- *
+ *
* @param metricsTable
* @param type
* @param metricName
@@ -2280,7 +2092,6 @@ public class MiscellaneousCommands implements CommandMarker {
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));
@@ -2359,7 +2170,6 @@ public class MiscellaneousCommands implements CommandMarker {
}
-
@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})
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
new file mode 100644
index 0000000..7d196e6
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
@@ -0,0 +1,185 @@
+/*
+ * 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.functions;
+
+import static java.util.stream.Collectors.toSet;
+
+import org.apache.geode.cache.AttributesFactory;
+import org.apache.geode.cache.DataPolicy;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.Scope;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.internal.InternalEntity;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.InternalRegionArguments;
+import org.apache.geode.internal.lang.StringUtils;
+import org.apache.geode.internal.logging.InternalLogWriter;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.logging.LogWriterImpl;
+import org.apache.geode.management.internal.cli.commands.MiscellaneousCommands;
+import org.apache.geode.management.internal.cli.util.LogExporter;
+import org.apache.geode.management.internal.cli.util.LogFilter;
+import org.apache.geode.management.internal.cli.util.ExportLogsCacheWriter;
+import org.apache.geode.management.internal.configuration.domain.Configuration;
+import org.apache.logging.log4j.Logger;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Stream;
+
+public class ExportLogsFunction implements Function, InternalEntity {
+ public static final String EXPORT_LOGS_REGION = "__exportLogsRegion";
+ private static final Logger LOGGER = LogService.getLogger();
+ private static final long serialVersionUID = 1L;
+ private static final int BUFFER_SIZE = 1024;
+
+
+ @Override
+ public void execute(final FunctionContext context) {
+ try {
+ // TODO: change this to get cache from FunctionContext when it becomes available
+ GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+
+ String memberId = cache.getDistributedSystem().getMemberId();
+ LOGGER.info("ExportLogsFunction started for member {}", memberId);
+ Region exportLogsRegion = createOrGetExistingExportLogsRegion(false);
+
+ Args args = (Args) context.getArguments();
+ LogFilter logFilter =
+ new LogFilter(args.getPermittedLogLevels(), args.getStartTime(), args.getEndTime());
+ Path workingDir = Paths.get(System.getProperty("user.dir"));
+
+ Path exportedZipFile = new LogExporter(logFilter).export(workingDir);
+
+ LOGGER.info("Streaming zipped file: " + exportedZipFile.toString());
+ try (FileInputStream inputStream = new FileInputStream(exportedZipFile.toFile())) {
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) > 0) {
+ if (bytesRead == BUFFER_SIZE) {
+ exportLogsRegion.put(memberId, buffer);
+ } else {
+ exportLogsRegion.put(memberId, Arrays.copyOfRange(buffer, 0, bytesRead));
+ }
+ }
+ }
+
+ context.getResultSender().lastResult(null);
+
+ } catch (Exception e) {
+ LOGGER.error(e);
+ context.getResultSender().sendException(e);
+ }
+ }
+
+ public static Region createOrGetExistingExportLogsRegion(boolean isLocator)
+ throws IOException, ClassNotFoundException {
+ GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+
+ Region exportLogsRegion = cache.getRegion(EXPORT_LOGS_REGION);
+ if (exportLogsRegion == null) {
+ AttributesFactory<String, Configuration> regionAttrsFactory =
+ new AttributesFactory<String, Configuration>();
+ regionAttrsFactory.setDataPolicy(DataPolicy.EMPTY);
+ regionAttrsFactory.setScope(Scope.DISTRIBUTED_ACK);
+
+ if (isLocator) {
+ regionAttrsFactory.setCacheWriter(new ExportLogsCacheWriter());
+ }
+ InternalRegionArguments internalArgs = new InternalRegionArguments();
+ internalArgs.setIsUsedForMetaRegion(true);
+ exportLogsRegion =
+ cache.createVMRegion(EXPORT_LOGS_REGION, regionAttrsFactory.create(), internalArgs);
+ }
+
+ return exportLogsRegion;
+ }
+
+ @Override
+ public boolean isHA() {
+ return false;
+ }
+
+ public static class Args implements Serializable {
+ private String startTime;
+ private String endTime;
+ private String logLevel;
+ private boolean logLevelOnly;
+
+ public Args(String startTime, String endTime, String logLevel, boolean logLevelOnly) {
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.logLevel = logLevel;
+ this.logLevelOnly = logLevelOnly;
+ }
+
+ public LocalDateTime getStartTime() {
+ return parseTime(startTime);
+ }
+
+ public LocalDateTime getEndTime() {
+ return parseTime(endTime);
+ }
+
+ public Set<String> getPermittedLogLevels() {
+ if (logLevel == null || StringUtils.isBlank(logLevel)) {
+ return LogFilter.allLogLevels();
+ }
+
+ if (logLevelOnly) {
+ return Stream.of(logLevel).collect(toSet());
+ }
+
+ // Return all log levels lower than or equal to the specified logLevel
+ return Arrays.stream(InternalLogWriter.levelNames).filter((String level) -> {
+ int logLevelCode = LogWriterImpl.levelNameToCode(level);
+ int logLevelCodeThreshold = LogWriterImpl.levelNameToCode(logLevel);
+
+ return logLevelCode <= logLevelCodeThreshold;
+ }).collect(toSet());
+ }
+
+ private static LocalDateTime parseTime(String dateString) {
+ if (dateString == null) {
+ return null;
+ }
+
+ try {
+ SimpleDateFormat df = new SimpleDateFormat(MiscellaneousCommands.FORMAT);
+ return df.parse(dateString).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+ } catch (ParseException e) {
+ try {
+ SimpleDateFormat df = new SimpleDateFormat(MiscellaneousCommands.ONLY_DATE_FORMAT);
+ return df.parse(dateString).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+ } catch (ParseException e1) {
+ return null;
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/ExportLogsCacheWriter.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/ExportLogsCacheWriter.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/ExportLogsCacheWriter.java
new file mode 100644
index 0000000..5bff192
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/ExportLogsCacheWriter.java
@@ -0,0 +1,75 @@
+/*
+ * 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.util;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.geode.cache.CacheWriterException;
+import org.apache.geode.cache.EntryEvent;
+import org.apache.geode.cache.util.CacheWriterAdapter;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+
+public class ExportLogsCacheWriter extends CacheWriterAdapter implements Serializable {
+ private Path currentFile;
+ private BufferedOutputStream currentOutputStream;
+
+ @Override
+ public void beforeCreate(EntryEvent event) throws CacheWriterException {
+ if (currentOutputStream == null) {
+ throw new IllegalStateException("No file is open for writing.");
+ }
+
+ try {
+ Object newValue = event.getNewValue();
+ if (!(newValue instanceof byte[])) {
+ throw new IllegalArgumentException(
+ "Value must be a byte[]. Recieved " + newValue.getClass().getCanonicalName());
+ }
+ currentOutputStream.write((byte[]) newValue);
+ } catch (IOException e) {
+ throw new CacheWriterException(e);
+ }
+ }
+
+ public void startFile(String memberId) throws IOException {
+ if (currentFile != null || currentOutputStream != null) {
+ throw new IllegalStateException("Cannot open more than one file at once");
+ }
+
+ currentFile = Files.createTempDirectory(memberId).resolve(memberId + ".zip");
+ currentOutputStream = new BufferedOutputStream(new FileOutputStream(currentFile.toFile()));
+ }
+
+ public Path endFile() {
+ Path completedFile = currentFile;
+
+ IOUtils.closeQuietly(currentOutputStream);
+ currentOutputStream = null;
+ currentFile = null;
+
+ return completedFile;
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogExporter.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogExporter.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogExporter.java
new file mode 100644
index 0000000..f30d686
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogExporter.java
@@ -0,0 +1,136 @@
+/*
+ * 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.util;
+
+import static java.util.stream.Collectors.toList;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.geode.cache.AttributesFactory;
+import org.apache.geode.cache.DataPolicy;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.Scope;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.InternalRegionArguments;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.internal.configuration.domain.Configuration;
+import org.apache.geode.management.internal.configuration.utils.ZipUtils;
+import org.apache.logging.log4j.Logger;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.ParseException;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+public class LogExporter {
+ private static final Logger LOGGER = LogService.getLogger();
+
+ private final LogFilter logFilter;
+
+ public LogExporter(LogFilter logFilter) throws ParseException {
+ this.logFilter = logFilter;
+ }
+
+ public Path export(Path workingDir) throws IOException {
+ LOGGER.debug("Working directory is {}", workingDir);
+
+ Path tempDirectory = Files.createTempDirectory("exportLogs");
+
+ for (Path logFile : findLogFiles(workingDir)) {
+ Path filteredLogFile = tempDirectory.resolve(logFile.getFileName());
+
+ if (this.logFilter == null) {
+ Files.copy(logFile, filteredLogFile);
+ } else {
+ writeFilteredLogFile(logFile, filteredLogFile);
+ }
+ }
+
+ for (Path statFile : findStatFiles(workingDir)) {
+ Files.copy(statFile, tempDirectory);
+ }
+
+ Path zipFile = Files.createTempFile("logExport", ".zip");
+ ZipUtils.zipDirectory(tempDirectory, zipFile);
+ LOGGER.info("Zipped files to: " + zipFile);
+
+
+ FileUtils.deleteDirectory(tempDirectory.toFile());
+
+ return zipFile;
+ }
+
+ protected void writeFilteredLogFile(Path originalLogFile, Path filteredLogFile)
+ throws IOException {
+ this.logFilter.startNewFile();
+
+ try (BufferedReader reader = new BufferedReader(new FileReader(originalLogFile.toFile()))) {
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(filteredLogFile.toFile()))) {
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ LogFilter.LineFilterResult result = this.logFilter.acceptsLine(line);
+
+ if (result == LogFilter.LineFilterResult.REMAINDER_OF_FILE_REJECTED) {
+ break;
+ }
+
+ if (result == LogFilter.LineFilterResult.LINE_ACCEPTED) {
+ writeLine(line, writer);
+ }
+ }
+ }
+ }
+ }
+
+ private void writeLine(String line, BufferedWriter writer) {
+ try {
+ writer.write(line);
+ writer.newLine();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to write to log file", e);
+ }
+ }
+
+ protected List<Path> findLogFiles(Path workingDir) throws IOException {
+ Predicate<Path> logFileSelector = (Path file) -> file.toString().toLowerCase().endsWith(".log");
+ return findFiles(workingDir, logFileSelector);
+ }
+
+
+ protected List<Path> findStatFiles(Path workingDir) throws IOException {
+ Predicate<Path> statFileSelector =
+ (Path file) -> file.toString().toLowerCase().endsWith(".gfs");
+ return findFiles(workingDir, statFileSelector);
+ }
+
+ private List<Path> findFiles(Path workingDir, Predicate<Path> fileSelector) throws IOException {
+ Stream<Path> selectedFiles =
+ Files.list(workingDir).filter(fileSelector).filter(this.logFilter::acceptsFile);
+
+ return selectedFiles.collect(toList());
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogFilter.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogFilter.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogFilter.java
new file mode 100644
index 0000000..2436530
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogFilter.java
@@ -0,0 +1,113 @@
+/*
+ * 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.util;
+
+import static java.util.stream.Collectors.toSet;
+
+import org.apache.geode.internal.logging.InternalLogWriter;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.logging.log4j.Logger;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Arrays;
+import java.util.Set;
+
+public class LogFilter {
+ public enum LineFilterResult {
+ LINE_ACCEPTED, LINE_REJECTED, REMAINDER_OF_FILE_REJECTED
+ }
+
+ private static final Logger LOGGER = LogService.getLogger();
+
+ private final Set<String> permittedLogLevels;
+ private final LocalDateTime startDate;
+ private final LocalDateTime endDate;
+
+ private LineFilterResult resultOfPreviousLine = LineFilterResult.LINE_ACCEPTED;
+
+ public LogFilter(Set<String> permittedLogLevels, LocalDateTime startDate, LocalDateTime endDate) {
+ this.permittedLogLevels = (permittedLogLevels == null || permittedLogLevels.isEmpty())
+ ? allLogLevels() : permittedLogLevels;
+ this.startDate = startDate;
+ this.endDate = endDate;
+ }
+
+ public void startNewFile() {
+ this.resultOfPreviousLine = LineFilterResult.LINE_ACCEPTED;
+ }
+
+ public LineFilterResult acceptsLine(String logLine) {
+ LogLevelExtractor.Result result = LogLevelExtractor.extract(logLine);
+
+ return acceptsLogEntry(result);
+ }
+
+ protected LineFilterResult acceptsLogEntry(LogLevelExtractor.Result result) {
+ if (result == null) {
+ return resultOfPreviousLine;
+ }
+
+ return acceptsLogEntry(result.getLogLevel(), result.getLogTimestamp());
+ }
+
+ protected LineFilterResult acceptsLogEntry(String logLevel, LocalDateTime logTimestamp) {
+ if (logTimestamp == null || logLevel == null) {
+ throw new IllegalArgumentException();
+ }
+
+ LineFilterResult result;
+
+ if (endDate != null && logTimestamp.isAfter(endDate)) {
+ result = LineFilterResult.REMAINDER_OF_FILE_REJECTED;
+ } else if (startDate != null && logTimestamp.isBefore(startDate)) {
+ result = LineFilterResult.LINE_REJECTED;
+ } else {
+ result = permittedLogLevels.contains(logLevel) ? LineFilterResult.LINE_ACCEPTED
+ : LineFilterResult.LINE_REJECTED;
+ }
+
+ resultOfPreviousLine = result;
+
+ return result;
+ }
+
+ public boolean acceptsFile(Path file) {
+ if (startDate == null) {
+ return true;
+ }
+ try {
+ return (getEndTimeOf(file).isAfter(startDate));
+ } catch (IOException e) {
+ LOGGER.error("Unable to determine lastModified time", e);
+ return true;
+ }
+ }
+
+ private static LocalDateTime getEndTimeOf(Path file) throws IOException {
+ long lastModifiedMillis = file.toFile().lastModified();
+ return Instant.ofEpochMilli(lastModifiedMillis).atZone(ZoneId.systemDefault())
+ .toLocalDateTime();
+ }
+
+ public static Set<String> allLogLevels() {
+ return Arrays.stream(InternalLogWriter.levelNames).collect(toSet());
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogLevelExtractor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogLevelExtractor.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogLevelExtractor.java
new file mode 100644
index 0000000..6c15d15
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogLevelExtractor.java
@@ -0,0 +1,65 @@
+/*
+ * 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.util;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class LogLevelExtractor {
+ private static Pattern LOG_PATTERN =
+ Pattern.compile("^\\[(\\S*)\\s+([\\d\\/]+)\\s+([\\d:\\.]+)\\s+(\\S+)");
+
+ private static DateTimeFormatter LOG_TIMESTAMP_FORMATTER =
+ DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS zzz");
+ private static final String SPACE = " ";
+
+ public static Result extract(String logLine) {
+ Matcher m = LOG_PATTERN.matcher(logLine);
+ if (!m.find()) {
+ return null;
+ }
+
+ String logLevel = m.group(1);
+ String logTimestamp = m.group(2) + SPACE + m.group(3) + SPACE + m.group(4);
+
+ LocalDateTime timestamp = LocalDateTime.parse(logTimestamp, LOG_TIMESTAMP_FORMATTER);
+
+ return new Result(logLevel, timestamp);
+ }
+
+ public static class Result {
+ private String logLevel;
+ private LocalDateTime logTimestamp;
+
+ public Result(String logLevel, LocalDateTime logTimestamp) {
+ this.logLevel = logLevel;
+ this.logTimestamp = logTimestamp;
+ }
+
+ public String getLogLevel() {
+ return logLevel;
+ }
+
+ public LocalDateTime getLogTimestamp() {
+ return logTimestamp;
+ }
+
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ZipUtils.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ZipUtils.java b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ZipUtils.java
index 81161d6..6c546a7 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ZipUtils.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ZipUtils.java
@@ -41,8 +41,7 @@ import org.apache.commons.io.IOUtils;
public class ZipUtils {
public static void zipDirectory(Path sourceDirectory, Path targetFile) throws IOException {
- Path p = Files.createFile(targetFile);
- try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p))) {
+ try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(targetFile))) {
Files.walk(sourceDirectory).filter(path -> !Files.isDirectory(path)).forEach(path -> {
ZipEntry zipEntry = new ZipEntry(sourceDirectory.relativize(path).toString());
try {
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnit.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnit.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnit.java
new file mode 100644
index 0000000..5258891
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsDUnit.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ */
+
+package org.apache.geode.management.internal.cli.commands;
+
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.geode.cache.AttributesFactory;
+import org.apache.geode.cache.DataPolicy;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.RegionShortcut;
+import org.apache.geode.cache.Scope;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.InternalRegionArguments;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.internal.cli.functions.ExportLogsFunction;
+import org.apache.geode.management.internal.cli.result.CommandResult;
+import org.apache.geode.management.internal.configuration.EventTestCacheWriter;
+import org.apache.geode.management.internal.configuration.domain.Configuration;
+import org.apache.geode.management.internal.configuration.utils.ZipUtils;
+import org.apache.geode.test.dunit.rules.GfshShellConnectionRule;
+import org.apache.geode.test.dunit.rules.Locator;
+import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
+import org.apache.geode.test.dunit.rules.Server;
+import org.apache.logging.log4j.core.Appender;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.stream.Stream;
+
+
+public class ExportLogsDUnit {
+ @Rule
+ public LocatorServerStartupRule lsRule = new LocatorServerStartupRule();
+
+ @Rule
+ public GfshShellConnectionRule gfshConnector = new GfshShellConnectionRule();
+
+ private Locator locator;
+
+ @Test
+ public void testExport() throws Exception {
+ locator = lsRule.startLocatorVM(0);
+
+ Server server = lsRule.startServerVM(1, locator.getPort());
+ Server server2 = lsRule.startServerVM(2, locator.getPort());
+
+ gfshConnector.connectAndVerify(locator);
+
+ CommandResult result = gfshConnector.executeAndVerifyCommand(
+ "export logs --dir=" + lsRule.getTempFolder().getRoot().getCanonicalPath());
+
+ File locatorWorkingDir = locator.getWorkingDir();
+ List<File> zipFilesInDir = Stream.of(locatorWorkingDir.listFiles())
+ .filter(f -> f.getName().endsWith(".zip")).collect(toList());
+
+ assertThat(zipFilesInDir).hasSize(1);
+
+ File unzippedLogFileDir = lsRule.getTempFolder().newFolder("unzippedLogs");
+ ZipUtils.unzip(zipFilesInDir.get(0).getCanonicalPath(), unzippedLogFileDir.getCanonicalPath());
+
+ Set<File> actualDirs =
+ Stream.of(unzippedLogFileDir.listFiles()).filter(File::isDirectory).collect(toSet());
+
+ assertThat(actualDirs).hasSize(2);
+
+ Set<String> expectedDirNames = Stream.of(server.getName(), server2.getName()).collect(toSet());
+ Set<String> actualDirNames = actualDirs.stream().map(File::getName).collect(toSet());
+
+ assertThat(actualDirNames).isEqualTo(expectedDirNames);
+
+ System.out.println("Unzipped artifacts:");
+ for (File dir : actualDirs) {
+ Set<String> fileNamesInDir = Stream.of(dir.listFiles()).map(File::getName).collect(toSet());
+
+ System.out.println(dir.getCanonicalPath() + " : " + fileNamesInDir);
+ assertThat(fileNamesInDir).contains(dir.getName() + ".log");
+ assertThat(fileNamesInDir).hasSize(1);
+ // TODO: Verify contents of files. (Write tests for logs containing multiple log levels,
+ // where some lines get through a filter and some do not
+ }
+
+ // Ensure export logs region does not accumulate data
+ server.invoke(() -> {
+ Region exportLogsRegion = ExportLogsFunction.createOrGetExistingExportLogsRegion(false);
+ assertThat(exportLogsRegion.size()).isEqualTo(0);
+ });
+ server2.invoke(() -> {
+ Region exportLogsRegion = ExportLogsFunction.createOrGetExistingExportLogsRegion(false);
+ assertThat(exportLogsRegion.size()).isEqualTo(0);
+ });
+ locator.invoke(() -> {
+ Region exportLogsRegion = ExportLogsFunction.createOrGetExistingExportLogsRegion(true);
+ assertThat(exportLogsRegion.size()).isEqualTo(0);
+ });
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart1DUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart1DUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart1DUnitTest.java
deleted file mode 100644
index 2fc8e84..0000000
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart1DUnitTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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 static org.apache.geode.test.dunit.Assert.*;
-import static org.apache.geode.test.dunit.LogWriterUtils.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.geode.cache.Cache;
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionFactory;
-import org.apache.geode.cache.RegionShortcut;
-import org.apache.geode.internal.FileUtil;
-import org.apache.geode.internal.logging.LogWriterImpl;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.SerializableRunnable;
-import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.junit.categories.DistributedTest;
-import org.apache.geode.test.junit.categories.FlakyTest;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-/**
- * Dunit class for testing gemfire function commands : export logs
- */
-@Category(DistributedTest.class)
-public class MiscellaneousCommandsExportLogsPart1DUnitTest extends CliCommandTestBase {
-
- private static final long serialVersionUID = 1L;
-
- void setupForExportLogs() {
- final VM vm1 = Host.getHost(0).getVM(1);
- setUpJmxManagerOnVm0ThenConnect(null);
-
- vm1.invoke(new SerializableRunnable() {
- public void run() {
- // no need to close cache as it will be closed as part of teardown2
- Cache cache = getCache();
-
- RegionFactory<Integer, Integer> dataRegionFactory =
- cache.createRegionFactory(RegionShortcut.PARTITION);
- Region region = dataRegionFactory.create("testRegion");
- for (int i = 0; i < 5; i++) {
- region.put("key" + (i + 200), "value" + (i + 200));
- }
- }
- });
- }
-
- String getCurrentTimeString() {
- SimpleDateFormat sf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS_z");
- Date startDate = new Date(System.currentTimeMillis());
- String formattedStartDate = sf.format(startDate);
- return ("_" + formattedStartDate);
- }
-
- @Test
- public void testExportLogs() throws IOException {
- Date startDate = new Date(System.currentTimeMillis() - 2 * 60 * 1000);
- SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
- String start = sf.format(startDate);
-
- Date enddate = new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000);
- String end = sf.format(enddate);
- String dir = getCurrentTimeString();
-
- setupForExportLogs();
- String logLevel = LogWriterImpl.levelToString(LogWriterImpl.INFO_LEVEL);
-
- MiscellaneousCommands misc = new MiscellaneousCommands();
- getCache();
-
- Result cmdResult = misc.exportLogsPreprocessing("./testExportLogs" + dir, null, null, logLevel,
- false, false, start, end, 1);
-
- getLogWriter().info("testExportLogs command result =" + cmdResult);
-
- if (cmdResult != null) {
- String cmdStringRsult = commandResultToString((CommandResult) cmdResult);
- getLogWriter().info("testExportLogs cmdStringRsult=" + cmdStringRsult);
- assertEquals(Result.Status.OK, cmdResult.getStatus());
- } else {
- fail("testExportLogs failed as did not get CommandResult");
- }
- FileUtil.delete(new File("./testExportLogs" + dir));
- }
-
- @Category(FlakyTest.class) // GEODE-1477 (http)
- @Test
- public void testExportLogsForMerge() throws IOException {
- setupForExportLogs();
- Date startDate = new Date(System.currentTimeMillis() - 2 * 60 * 1000);
- SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
- String start = sf.format(startDate);
-
- Date enddate = new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000);
- String end = sf.format(enddate);
- String dir = getCurrentTimeString();
-
- String logLevel = LogWriterImpl.levelToString(LogWriterImpl.INFO_LEVEL);
-
- MiscellaneousCommands misc = new MiscellaneousCommands();
- getCache();
-
- Result cmdResult = misc.exportLogsPreprocessing("./testExportLogsForMerge" + dir, null, null,
- logLevel, false, true, start, end, 1);
- getLogWriter().info("testExportLogsForMerge command=" + cmdResult);
-
- if (cmdResult != null) {
- String cmdStringRsult = commandResultToString((CommandResult) cmdResult);
- getLogWriter().info("testExportLogsForMerge cmdStringRsult=" + cmdStringRsult);
-
- assertEquals(Result.Status.OK, cmdResult.getStatus());
- } else {
- fail("testExportLogsForMerge failed as did not get CommandResult");
- }
- FileUtil.delete(new File("./testExportLogsForMerge" + dir));
- }
-}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart2DUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart2DUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart2DUnitTest.java
deleted file mode 100644
index d1f44d1..0000000
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart2DUnitTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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 static org.apache.geode.test.dunit.Assert.*;
-import static org.apache.geode.test.dunit.LogWriterUtils.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.geode.cache.Cache;
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionFactory;
-import org.apache.geode.cache.RegionShortcut;
-import org.apache.geode.internal.FileUtil;
-import org.apache.geode.internal.logging.LogWriterImpl;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.SerializableRunnable;
-import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.junit.categories.DistributedTest;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-/**
- * Dunit class for testing gemfire function commands : export logs
- */
-@Category(DistributedTest.class)
-public class MiscellaneousCommandsExportLogsPart2DUnitTest extends CliCommandTestBase {
-
- private static final long serialVersionUID = 1L;
-
- void setupForExportLogs() {
- final VM vm1 = Host.getHost(0).getVM(1);
- setUpJmxManagerOnVm0ThenConnect(null);
-
- vm1.invoke(new SerializableRunnable() {
- public void run() {
- // no need to close cache as it will be closed as part of teardown2
- Cache cache = getCache();
-
- RegionFactory<Integer, Integer> dataRegionFactory =
- cache.createRegionFactory(RegionShortcut.PARTITION);
- Region region = dataRegionFactory.create("testRegion");
- for (int i = 0; i < 5; i++) {
- region.put("key" + (i + 200), "value" + (i + 200));
- }
- }
- });
- }
-
- String getCurrentTimeString() {
- SimpleDateFormat sf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS_z");
- Date startDate = new Date(System.currentTimeMillis());
- String formattedStartDate = sf.format(startDate);
- return ("_" + formattedStartDate);
- }
-
- @Test
- public void testExportLogsForLogLevel() throws IOException {
- setupForExportLogs();
-
- Date startDate = new Date(System.currentTimeMillis() - 60 * 1000);
- SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
- String start = sf.format(startDate);
-
- Date enddate = new Date(System.currentTimeMillis() + 60 * 1000);
- String end = sf.format(enddate);
- String dir = getCurrentTimeString();
-
- String logLevel = LogWriterImpl.levelToString(LogWriterImpl.CONFIG_LEVEL);
-
- MiscellaneousCommands misc = new MiscellaneousCommands();
- getCache();
-
- Result cmdResult = misc.exportLogsPreprocessing("./testExportLogsForLogLevel" + dir, null, null,
- logLevel, false, false, start, end, 1);
-
- getLogWriter().info("testExportLogsForLogLevel command=" + cmdResult);
-
- if (cmdResult != null) {
- String cmdStringRsult = commandResultToString((CommandResult) cmdResult);
- getLogWriter().info("testExportLogsForLogLevel cmdStringRsult=" + cmdStringRsult);
- assertEquals(Result.Status.OK, cmdResult.getStatus());
- } else {
- fail("testExportLogsForLogLevel failed as did not get CommandResult");
- }
- FileUtil.delete(new File("testExportLogsForLogLevel" + dir));
- }
-
- @Test
- public void testExportLogsForLogLevelWithUPTOLOGLEVEL() throws IOException {
- setupForExportLogs();
-
- Date startDate = new Date(System.currentTimeMillis() - 2 * 60 * 1000);
- SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
- String start = sf.format(startDate);
-
- Date enddate = new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000);
- String end = sf.format(enddate);
- String dir = getCurrentTimeString();
-
- String logLevel = LogWriterImpl.levelToString(LogWriterImpl.SEVERE_LEVEL);
-
- MiscellaneousCommands misc = new MiscellaneousCommands();
- getCache();
-
- Result cmdResult =
- misc.exportLogsPreprocessing("./testExportLogsForLogLevelWithUPTOLOGLEVEL" + dir, null,
- null, logLevel, true, false, start, end, 1);
-
- getLogWriter().info("testExportLogsForLogLevelWithUPTOLOGLEVEL command=" + cmdResult);
-
- if (cmdResult != null) {
- String cmdStringRsult = commandResultToString((CommandResult) cmdResult);
- getLogWriter()
- .info("testExportLogsForLogLevelWithUPTOLOGLEVEL cmdStringRsult=" + cmdStringRsult);
-
- assertEquals(Result.Status.OK, cmdResult.getStatus());
- } else {
- fail("testExportLogsForLogLevelWithUPTOLOGLEVEL failed as did not get CommandResult");
- }
- FileUtil.delete(new File("testExportLogsForLogLevelWithUPTOLOGLEVEL" + dir));
- }
-}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart3DUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart3DUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart3DUnitTest.java
deleted file mode 100644
index b6a4a5b..0000000
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart3DUnitTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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 org.apache.geode.cache.Cache;
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionFactory;
-import org.apache.geode.cache.RegionShortcut;
-import org.apache.geode.internal.FileUtil;
-import org.apache.geode.internal.logging.LogWriterImpl;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.SerializableRunnable;
-import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.junit.categories.DistributedTest;
-import org.apache.geode.test.junit.categories.FlakyTest;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Properties;
-
-import static org.apache.geode.test.dunit.Assert.assertEquals;
-import static org.apache.geode.test.dunit.Assert.fail;
-import static org.apache.geode.test.dunit.LogWriterUtils.getLogWriter;
-import static org.apache.geode.distributed.ConfigurationProperties.*;
-
-/**
- * Dunit class for testing gemfire function commands : export logs
- */
-@Category(DistributedTest.class)
-public class MiscellaneousCommandsExportLogsPart3DUnitTest extends CliCommandTestBase {
-
- private static final long serialVersionUID = 1L;
-
- public String getMemberId() {
- Cache cache = getCache();
- return cache.getDistributedSystem().getDistributedMember().getId();
- }
-
- void setupForExportLogs() {
- final VM vm1 = Host.getHost(0).getVM(1);
- setUpJmxManagerOnVm0ThenConnect(null);
-
- vm1.invoke(new SerializableRunnable() {
- public void run() {
- // no need to close cache as it will be closed as part of teardown2
- Cache cache = getCache();
-
- RegionFactory<Integer, Integer> dataRegionFactory =
- cache.createRegionFactory(RegionShortcut.PARTITION);
- Region region = dataRegionFactory.create("testRegion");
- for (int i = 0; i < 5; i++) {
- region.put("key" + (i + 200), "value" + (i + 200));
- }
- }
- });
- }
-
- String getCurrentTimeString() {
- SimpleDateFormat sf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS_z");
- Date startDate = new Date(System.currentTimeMillis());
- String formattedStartDate = sf.format(startDate);
- return ("_" + formattedStartDate);
- }
-
- @Category(FlakyTest.class) // GEODE-672: random ports, java.rmi.server.ExportException: Port
- // already in use, HeadlessGfsh, disk IO
- @Test
- public void testExportLogsForGroup() throws IOException {
- Properties localProps = new Properties();
- localProps.setProperty(NAME, "Manager");
- localProps.setProperty(GROUPS, "Group1");
- setUpJmxManagerOnVm0ThenConnect(localProps);
- String dir = getCurrentTimeString();
-
- Date startDate = new Date(System.currentTimeMillis() - 2 * 60 * 1000);
- SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
- String start = sf.format(startDate);
-
- Date enddate = new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000);
- String end = sf.format(enddate);
-
- String logLevel = LogWriterImpl.levelToString(LogWriterImpl.INFO_LEVEL);
-
- MiscellaneousCommands misc = new MiscellaneousCommands();
- getCache();
- String[] groups = new String[1];
- groups[0] = "Group1";
-
- Result cmdResult = misc.exportLogsPreprocessing("./testExportLogsForGroup" + dir, groups, null,
- logLevel, false, false, start, end, 1);
-
- getLogWriter().info("testExportLogsForGroup command result =" + cmdResult);
- if (cmdResult != null) {
- String cmdStringRsult = commandResultToString((CommandResult) cmdResult);
- getLogWriter().info("testExportLogsForGroup cmdStringRsult=" + cmdStringRsult);
- assertEquals(Result.Status.OK, cmdResult.getStatus());
- } else {
- fail("testExportLogsForGroup failed as did not get CommandResult");
- }
- FileUtil.delete(new File("testExportLogsForGroup" + dir));
- }
-
- @Test
- public void testExportLogsForMember() throws IOException {
- setUpJmxManagerOnVm0ThenConnect(null);
-
- Date startDate = new Date(System.currentTimeMillis() - 2 * 60 * 1000);
- SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
- String start = sf.format(startDate);
-
- Date enddate = new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000);
- String end = sf.format(enddate);
-
- final VM vm1 = Host.getHost(0).getVM(1);
- final String vm1MemberId = (String) vm1.invoke(() -> getMemberId());
- String dir = getCurrentTimeString();
-
- String logLevel = LogWriterImpl.levelToString(LogWriterImpl.INFO_LEVEL);
-
- MiscellaneousCommands misc = new MiscellaneousCommands();
- getCache();
-
- Result cmdResult = misc.exportLogsPreprocessing("./testExportLogsForMember" + dir, null,
- vm1MemberId, logLevel, false, false, start, end, 1);
-
- getLogWriter().info("testExportLogsForMember command result =" + cmdResult);
-
- if (cmdResult != null) {
- String cmdStringRsult = commandResultToString((CommandResult) cmdResult);
- getLogWriter().info("testExportLogsForMember cmdStringRsult=" + cmdStringRsult);
- assertEquals(Result.Status.OK, cmdResult.getStatus());
- } else {
- fail("testExportLogsForMember failed as did not get CommandResult");
- }
- FileUtil.delete(new File("testExportLogsForMember" + dir));
- }
-}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart4DUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart4DUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart4DUnitTest.java
deleted file mode 100644
index b712785..0000000
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/MiscellaneousCommandsExportLogsPart4DUnitTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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 static org.apache.geode.test.dunit.Assert.*;
-import static org.apache.geode.test.dunit.LogWriterUtils.*;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.geode.cache.Cache;
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionFactory;
-import org.apache.geode.cache.RegionShortcut;
-import org.apache.geode.internal.FileUtil;
-import org.apache.geode.internal.logging.LogWriterImpl;
-import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.SerializableRunnable;
-import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.junit.categories.DistributedTest;
-import org.apache.geode.test.junit.categories.FlakyTest;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-/**
- * Dunit class for testing gemfire function commands : export logs
- */
-@Category(DistributedTest.class)
-public class MiscellaneousCommandsExportLogsPart4DUnitTest extends CliCommandTestBase {
-
- private static final long serialVersionUID = 1L;
-
- void setupForExportLogs() {
- final VM vm1 = Host.getHost(0).getVM(1);
- setUpJmxManagerOnVm0ThenConnect(null);
-
- vm1.invoke(new SerializableRunnable() {
- public void run() {
- // no need to close cache as it will be closed as part of teardown2
- Cache cache = getCache();
-
- RegionFactory<Integer, Integer> dataRegionFactory =
- cache.createRegionFactory(RegionShortcut.PARTITION);
- Region region = dataRegionFactory.create("testRegion");
- for (int i = 0; i < 5; i++) {
- region.put("key" + (i + 200), "value" + (i + 200));
- }
- }
- });
- }
-
- String getCurrentTimeString() {
- SimpleDateFormat sf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS_z");
- Date startDate = new Date(System.currentTimeMillis());
- String formattedStartDate = sf.format(startDate);
- return ("_" + formattedStartDate);
- }
-
- @Test
- public void testExportLogsForTimeRange1() throws IOException {
- setupForExportLogs();
- Date startDate = new Date(System.currentTimeMillis() - 1 * 60 * 1000);
- SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
- String start = sf.format(startDate);
-
- Date enddate = new Date(System.currentTimeMillis() + 1 * 60 * 60 * 1000);
- String end = sf.format(enddate);
- String dir = getCurrentTimeString();
-
- String logLevel = LogWriterImpl.levelToString(LogWriterImpl.INFO_LEVEL);
-
- MiscellaneousCommands misc = new MiscellaneousCommands();
- getCache();
-
- Result cmdResult = misc.exportLogsPreprocessing("./testExportLogsForTimeRange1" + dir, null,
- null, logLevel, false, false, start, end, 1);
-
- getLogWriter().info("testExportLogsForTimeRange1 command result =" + cmdResult);
-
- if (cmdResult != null) {
- String cmdStringRsult = commandResultToString((CommandResult) cmdResult);
- getLogWriter().info("testExportLogsForTimeRange1 cmdStringRsult=" + cmdStringRsult);
- assertEquals(Result.Status.OK, cmdResult.getStatus());
- } else {
- fail("testExportLogsForTimeRange1 failed as did not get CommandResult");
- }
- FileUtil.delete(new File("testExportLogsForTimeRange1" + dir));
- }
-
- @Category(FlakyTest.class) // GEODE-1500 (http)
- @Test
- public void testExportLogsForTimeRangeForOnlyStartTime() throws IOException {
- setupForExportLogs();
- Date date = new Date();
- date.setTime(System.currentTimeMillis() - 30 * 1000);
- SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd/HH:mm");
- String s = sf.format(date);
- String dir = getCurrentTimeString();
-
- String logLevel = LogWriterImpl.levelToString(LogWriterImpl.INFO_LEVEL);
-
- MiscellaneousCommands misc = new MiscellaneousCommands();
- getCache();
-
- Result cmdResult =
- misc.exportLogsPreprocessing("./testExportLogsForTimeRangeForOnlyStartTime" + dir, null,
- null, logLevel, false, false, s, null, 1);
-
- getLogWriter().info("testExportLogsForTimeRangeForOnlyStartTime command result =" + cmdResult);
-
- if (cmdResult != null) {
- String cmdStringRsult = commandResultToString((CommandResult) cmdResult);
- getLogWriter()
- .info("testExportLogsForTimeRangeForOnlyStartTime cmdStringRsult=" + cmdStringRsult);
- assertEquals(Result.Status.OK, cmdResult.getStatus());
- } else {
- fail("testExportLogsForTimeRangeForOnlyStartTime failed as did not get CommandResult");
- }
- FileUtil.delete(new File("testExportLogsForTimeRangeForOnlyStartTime" + dir));
- }
-}
http://git-wip-us.apache.org/repos/asf/geode/blob/d5d7e800/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunctionTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunctionTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunctionTest.java
new file mode 100644
index 0000000..023c0a2
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunctionTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.functions;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verify;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.execute.FunctionContextImpl;
+import org.apache.geode.test.dunit.rules.ServerStarterRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.util.Properties;
+
+public class ExportLogsFunctionTest {
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Rule
+ public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+
+ private ServerStarterRule serverStarterRule;
+ private File serverWorkingDir;
+
+ @Before
+ public void setup() throws Exception {
+ serverWorkingDir = temporaryFolder.newFolder("serverWorkingDir");
+ System.setProperty("user.dir", serverWorkingDir.getCanonicalPath());
+
+ serverStarterRule = new ServerStarterRule(new Properties());
+ serverStarterRule.startServer();
+ }
+
+ @After
+ public void teardown() {
+ serverStarterRule.after();
+ }
+
+ @Test
+ public void execute() throws Throwable {
+ File logFile1 = new File(serverWorkingDir, "server1.log");
+ FileUtils.writeStringToFile(logFile1, "some log for server1 \n some other log line");
+ File logFile2 = new File(serverWorkingDir, "server2.log");
+ FileUtils.writeStringToFile(logFile2, "some log for server2 \n some other log line");
+
+ File notALogFile = new File(serverWorkingDir, "foo.txt");
+ FileUtils.writeStringToFile(notALogFile, "some text");
+
+ ExportLogsFunction.Args args = new ExportLogsFunction.Args(null, null, "info", false);
+
+ CapturingResultSender resultSender = new CapturingResultSender();
+ FunctionContext context = new FunctionContextImpl("functionId", args, resultSender);
+
+ new ExportLogsFunction().execute(context);
+
+ if (resultSender.getThrowable() != null) {
+ throw resultSender.getThrowable();
+ }
+ }
+
+ @Test
+ public void createOrGetExistingExportLogsRegionDoesNotBlowUp() throws Exception {
+ ExportLogsFunction.createOrGetExistingExportLogsRegion(false);
+
+ Cache cache = GemFireCacheImpl.getInstance();
+ assertThat(cache.getRegion(ExportLogsFunction.EXPORT_LOGS_REGION)).isNotNull();
+ }
+
+ private static class CapturingResultSender implements ResultSender {
+ private Throwable t;
+
+ public Throwable getThrowable() {
+ return t;
+ }
+
+ @Override
+ public void sendResult(Object oneResult) {
+
+ }
+
+ @Override
+ public void lastResult(Object lastResult) {
+
+ }
+
+ @Override
+ public void sendException(Throwable t) {
+ this.t = t;
+ }
+ }
+}