|
@@ -76,6 +76,7 @@ public class HadoopArchiveLogs implements Tool {
|
|
private static final String MAX_TOTAL_LOGS_SIZE_OPTION = "maxTotalLogsSize";
|
|
private static final String MAX_TOTAL_LOGS_SIZE_OPTION = "maxTotalLogsSize";
|
|
private static final String MEMORY_OPTION = "memory";
|
|
private static final String MEMORY_OPTION = "memory";
|
|
private static final String VERBOSE_OPTION = "verbose";
|
|
private static final String VERBOSE_OPTION = "verbose";
|
|
|
|
+ private static final String FORCE_OPTION = "force";
|
|
|
|
|
|
private static final int DEFAULT_MAX_ELIGIBLE = -1;
|
|
private static final int DEFAULT_MAX_ELIGIBLE = -1;
|
|
private static final int DEFAULT_MIN_NUM_LOG_FILES = 20;
|
|
private static final int DEFAULT_MIN_NUM_LOG_FILES = 20;
|
|
@@ -91,6 +92,8 @@ public class HadoopArchiveLogs implements Tool {
|
|
@VisibleForTesting
|
|
@VisibleForTesting
|
|
long memory = DEFAULT_MEMORY;
|
|
long memory = DEFAULT_MEMORY;
|
|
private boolean verbose = false;
|
|
private boolean verbose = false;
|
|
|
|
+ @VisibleForTesting
|
|
|
|
+ boolean force = false;
|
|
|
|
|
|
@VisibleForTesting
|
|
@VisibleForTesting
|
|
Set<AppInfo> eligibleApplications;
|
|
Set<AppInfo> eligibleApplications;
|
|
@@ -126,6 +129,8 @@ public class HadoopArchiveLogs implements Tool {
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public int run(String[] args) throws Exception {
|
|
public int run(String[] args) throws Exception {
|
|
|
|
+ int exitCode = 1;
|
|
|
|
+
|
|
handleOpts(args);
|
|
handleOpts(args);
|
|
|
|
|
|
FileSystem fs = null;
|
|
FileSystem fs = null;
|
|
@@ -141,44 +146,41 @@ public class HadoopArchiveLogs implements Tool {
|
|
}
|
|
}
|
|
try {
|
|
try {
|
|
fs = FileSystem.get(conf);
|
|
fs = FileSystem.get(conf);
|
|
- checkFilesAndSeedApps(fs, remoteRootLogDir, suffix);
|
|
|
|
|
|
+ if (prepareWorkingDir(fs, workingDir)) {
|
|
|
|
|
|
- // Prepare working directory
|
|
|
|
- if (fs.exists(workingDir)) {
|
|
|
|
- fs.delete(workingDir, true);
|
|
|
|
- }
|
|
|
|
- fs.mkdirs(workingDir);
|
|
|
|
- fs.setPermission(workingDir,
|
|
|
|
- new FsPermission(FsAction.ALL, FsAction.NONE, FsAction.NONE));
|
|
|
|
- } finally {
|
|
|
|
- if (fs != null) {
|
|
|
|
- fs.close();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- filterAppsByAggregatedStatus();
|
|
|
|
|
|
+ checkFilesAndSeedApps(fs, remoteRootLogDir, suffix);
|
|
|
|
|
|
- checkMaxEligible();
|
|
|
|
|
|
+ filterAppsByAggregatedStatus();
|
|
|
|
|
|
- if (eligibleApplications.isEmpty()) {
|
|
|
|
- LOG.info("No eligible applications to process");
|
|
|
|
- System.exit(0);
|
|
|
|
- }
|
|
|
|
|
|
+ checkMaxEligible();
|
|
|
|
|
|
- StringBuilder sb =
|
|
|
|
- new StringBuilder("Will process the following applications:");
|
|
|
|
- for (AppInfo app : eligibleApplications) {
|
|
|
|
- sb.append("\n\t").append(app.getAppId());
|
|
|
|
- }
|
|
|
|
- LOG.info(sb.toString());
|
|
|
|
|
|
+ if (eligibleApplications.isEmpty()) {
|
|
|
|
+ LOG.info("No eligible applications to process");
|
|
|
|
+ exitCode = 0;
|
|
|
|
+ } else {
|
|
|
|
+ StringBuilder sb =
|
|
|
|
+ new StringBuilder("Will process the following applications:");
|
|
|
|
+ for (AppInfo app : eligibleApplications) {
|
|
|
|
+ sb.append("\n\t").append(app.getAppId());
|
|
|
|
+ }
|
|
|
|
+ LOG.info(sb.toString());
|
|
|
|
|
|
- File localScript = File.createTempFile("hadoop-archive-logs-", ".sh");
|
|
|
|
- generateScript(localScript, workingDir, remoteRootLogDir, suffix);
|
|
|
|
|
|
+ File localScript = File.createTempFile("hadoop-archive-logs-", ".sh");
|
|
|
|
+ generateScript(localScript, workingDir, remoteRootLogDir, suffix);
|
|
|
|
|
|
- if (runDistributedShell(localScript)) {
|
|
|
|
- return 0;
|
|
|
|
|
|
+ exitCode = runDistributedShell(localScript) ? 0 : 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } finally {
|
|
|
|
+ if (fs != null) {
|
|
|
|
+ // Cleanup working directory
|
|
|
|
+ if (fs.exists(workingDir)) {
|
|
|
|
+ fs.delete(workingDir, true);
|
|
|
|
+ }
|
|
|
|
+ fs.close();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- return -1;
|
|
|
|
|
|
+ return exitCode;
|
|
}
|
|
}
|
|
|
|
|
|
private void handleOpts(String[] args) throws ParseException {
|
|
private void handleOpts(String[] args) throws ParseException {
|
|
@@ -202,12 +204,17 @@ public class HadoopArchiveLogs implements Tool {
|
|
memoryOpt.setArgName("megabytes");
|
|
memoryOpt.setArgName("megabytes");
|
|
Option verboseOpt = new Option(VERBOSE_OPTION, false,
|
|
Option verboseOpt = new Option(VERBOSE_OPTION, false,
|
|
"Print more details.");
|
|
"Print more details.");
|
|
|
|
+ Option forceOpt = new Option(FORCE_OPTION, false,
|
|
|
|
+ "Force recreating the working directory if an existing one is found. " +
|
|
|
|
+ "This should only be used if you know that another instance is " +
|
|
|
|
+ "not currently running");
|
|
opts.addOption(helpOpt);
|
|
opts.addOption(helpOpt);
|
|
opts.addOption(maxEligibleOpt);
|
|
opts.addOption(maxEligibleOpt);
|
|
opts.addOption(minNumLogFilesOpt);
|
|
opts.addOption(minNumLogFilesOpt);
|
|
opts.addOption(maxTotalLogsSizeOpt);
|
|
opts.addOption(maxTotalLogsSizeOpt);
|
|
opts.addOption(memoryOpt);
|
|
opts.addOption(memoryOpt);
|
|
opts.addOption(verboseOpt);
|
|
opts.addOption(verboseOpt);
|
|
|
|
+ opts.addOption(forceOpt);
|
|
|
|
|
|
try {
|
|
try {
|
|
CommandLineParser parser = new GnuParser();
|
|
CommandLineParser parser = new GnuParser();
|
|
@@ -242,6 +249,9 @@ public class HadoopArchiveLogs implements Tool {
|
|
if (commandLine.hasOption(VERBOSE_OPTION)) {
|
|
if (commandLine.hasOption(VERBOSE_OPTION)) {
|
|
verbose = true;
|
|
verbose = true;
|
|
}
|
|
}
|
|
|
|
+ if (commandLine.hasOption(FORCE_OPTION)) {
|
|
|
|
+ force = true;
|
|
|
|
+ }
|
|
} catch (ParseException pe) {
|
|
} catch (ParseException pe) {
|
|
HelpFormatter formatter = new HelpFormatter();
|
|
HelpFormatter formatter = new HelpFormatter();
|
|
formatter.printHelp("yarn archive-logs", opts);
|
|
formatter.printHelp("yarn archive-logs", opts);
|
|
@@ -249,6 +259,25 @@ public class HadoopArchiveLogs implements Tool {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @VisibleForTesting
|
|
|
|
+ boolean prepareWorkingDir(FileSystem fs, Path workingDir) throws IOException {
|
|
|
|
+ if (fs.exists(workingDir)) {
|
|
|
|
+ if (force) {
|
|
|
|
+ LOG.info("Existing Working Dir detected: -" + FORCE_OPTION +
|
|
|
|
+ " specified -> recreating Working Dir");
|
|
|
|
+ fs.delete(workingDir, true);
|
|
|
|
+ } else {
|
|
|
|
+ LOG.info("Existing Working Dir detected: -" + FORCE_OPTION +
|
|
|
|
+ " not specified -> exiting");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ fs.mkdirs(workingDir);
|
|
|
|
+ fs.setPermission(workingDir,
|
|
|
|
+ new FsPermission(FsAction.ALL, FsAction.ALL, FsAction.NONE));
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
@VisibleForTesting
|
|
@VisibleForTesting
|
|
void filterAppsByAggregatedStatus() throws IOException, YarnException {
|
|
void filterAppsByAggregatedStatus() throws IOException, YarnException {
|
|
YarnClient client = YarnClient.createYarnClient();
|
|
YarnClient client = YarnClient.createYarnClient();
|