diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/LogsCLI.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/LogsCLI.java index d28c77c..2dea704 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/LogsCLI.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/LogsCLI.java @@ -370,7 +370,7 @@ private boolean fetchAllLogFiles(String[] logFiles) { @Private @VisibleForTesting - public void printContainerLogsFromRunningApplication(Configuration conf, + public int printContainerLogsFromRunningApplication(Configuration conf, ContainerLogsRequest request, LogCLIHelpers logCliHelper) throws IOException { String containerIdStr = request.getContainerId().toString(); @@ -384,10 +384,12 @@ public void printContainerLogsFromRunningApplication(Configuration conf, // filter the log files based on the given --logFiles pattern List allLogs= getContainerLogFiles(getConf(), containerIdStr, nodeHttpAddress); - List matchedFiles = getMatchedLogFiles( - request, allLogs, true); + List matchedFiles = getMatchedLogFiles(request, allLogs); if (matchedFiles.isEmpty()) { - return; + System.err.println("Can not find any log file matching the pattern: " + + request.getLogTypes() + " for the container: " + containerIdStr + + " within the application: " + request.getAppId()); + return -1; } ContainerLogsRequest newOptions = new ContainerLogsRequest(request); newOptions.setLogTypes(matchedFiles); @@ -397,7 +399,7 @@ public void printContainerLogsFromRunningApplication(Configuration conf, + nodeId; out.println(containerString); out.println(StringUtils.repeat("=", containerString.length())); - + boolean foundAnyLogs = false; for (String logFile : newOptions.getLogTypes()) { out.println("LogType:" + logFile); out.println("Log Upload Time:" @@ -417,6 +419,7 @@ public void printContainerLogsFromRunningApplication(Configuration conf, + " to a running container (" + containerIdStr + ") and so may" + " not be complete."); out.flush(); + foundAnyLogs = true; } catch (ClientHandlerException | UniformInterfaceException ex) { System.err.println("Can not find the log file:" + logFile + " for the container:" + containerIdStr + " in NodeManager:" @@ -424,7 +427,13 @@ public void printContainerLogsFromRunningApplication(Configuration conf, } } // for the case, we have already uploaded partial logs in HDFS - logCliHelper.dumpAContainersLogsForALogType(newOptions, false); + int result = logCliHelper.dumpAContainersLogsForALogType( + newOptions, false); + if (result == 0 || foundAnyLogs) { + return 0; + } else { + return -1; + } } finally { logCliHelper.closePrintStream(out); } @@ -436,6 +445,10 @@ private int printContainerLogsForFinishedApplication( ContainerLogsRequest newOptions = getMatchedLogOptions( request, logCliHelper); if (newOptions == null) { + System.err.println("Can not find any log file matching the pattern: " + + request.getLogTypes() + " for the container: " + + request.getContainerId() + " within the application: " + + request.getAppId()); return -1; } return logCliHelper.dumpAContainersLogsForALogType(newOptions); @@ -447,6 +460,10 @@ private int printContainerLogsForFinishedApplicationWithoutNodeId( ContainerLogsRequest newOptions = getMatchedLogOptions( request, logCliHelper); if (newOptions == null) { + System.err.println("Can not find any log file matching the pattern: " + + request.getLogTypes() + " for the container: " + + request.getContainerId() + " within the application: " + + request.getAppId()); return -1; } return logCliHelper.dumpAContainersLogsForALogTypeWithoutNodeId( @@ -634,7 +651,7 @@ private Options createCommandOpts() { amOption.setArgName("AM Containers"); opts.addOption(amOption); Option logFileOpt = new Option(CONTAINER_LOG_FILES, true, - "Work with -am/-containerId and specify comma-separated value " + "Specify comma-separated value " + "to get specified container log files. Use \"ALL\" to fetch all the " + "log files for the container. It also supports Java Regex."); logFileOpt.setValueSeparator(','); @@ -812,7 +829,7 @@ private int fetchContainerLogs(ContainerLogsRequest request, logFiles = Arrays.asList("syslog"); } request.setLogTypes(logFiles); - printContainerLogsFromRunningApplication(getConf(), request, + resultCode = printContainerLogsFromRunningApplication(getConf(), request, logCliHelper); } else { // If the application is in the final state, we will directly @@ -830,12 +847,14 @@ private int fetchApplicationLogs(ContainerLogsRequest options, // If the application is still running, we would get the full // list of the containers first, then fetch the logs for each // container from NM. - int resultCode = 0; + int resultCode = -1; if (options.isAppFinished()) { ContainerLogsRequest newOptions = getMatchedLogOptions( options, logCliHelper); if (newOptions == null) { - resultCode = -1; + System.err.println("Can not find any log file matching the pattern: " + + options.getLogTypes() + " for the application: " + + options.getAppId()); } else { resultCode = logCliHelper.dumpAllContainersLogs(newOptions); @@ -844,8 +863,11 @@ private int fetchApplicationLogs(ContainerLogsRequest options, List containerLogRequests = getContainersLogRequestForRunningApplication(options); for (ContainerLogsRequest container : containerLogRequests) { - printContainerLogsFromRunningApplication(getConf(), container, - logCliHelper); + int result = printContainerLogsFromRunningApplication(getConf(), + container, logCliHelper); + if (result == 0) { + resultCode = 0; + } } } if (resultCode == -1) { @@ -878,8 +900,7 @@ private ContainerLogsRequest getMatchedLogOptions( List matchedFiles = new ArrayList(); if (!request.getLogTypes().contains(".*")) { Set files = logCliHelper.listContainerLogs(request); - matchedFiles = getMatchedLogFiles( - request, files, true); + matchedFiles = getMatchedLogFiles(request, files); if (matchedFiles.isEmpty()) { return null; } @@ -890,7 +911,7 @@ private ContainerLogsRequest getMatchedLogOptions( } private List getMatchedLogFiles(ContainerLogsRequest options, - Collection candidate, boolean printError) throws IOException { + Collection candidate) throws IOException { List matchedFiles = new ArrayList(); List filePattern = options.getLogTypes(); for (String file : candidate) { @@ -898,13 +919,6 @@ private ContainerLogsRequest getMatchedLogOptions( matchedFiles.add(file); } } - if (matchedFiles.isEmpty()) { - if (printError) { - System.err.println("Can not find any log file matching the pattern: " - + options.getLogTypes() + " for the application: " - + options.getAppId()); - } - } return matchedFiles; } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestLogsCLI.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestLogsCLI.java index df1c6b7..5f4febf 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestLogsCLI.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestLogsCLI.java @@ -208,11 +208,10 @@ public void testHelpMessage() throws Exception { pw.println(" -list_nodes Show the list of nodes that successfully"); pw.println(" aggregated logs. This option can only be"); pw.println(" used with finished applications."); - pw.println(" -logFiles Work with -am/-containerId and specify"); - pw.println(" comma-separated value to get specified"); - pw.println(" container log files. Use \"ALL\" to fetch"); - pw.println(" all the log files for the container. It"); - pw.println(" also supports Java Regex."); + pw.println(" -logFiles Specify comma-separated value to get"); + pw.println(" specified container log files. Use \"ALL\""); + pw.println(" to fetch all the log files for the"); + pw.println(" container. It also supports Java Regex."); pw.println(" -nodeAddress NodeAddress in the format nodename:port"); pw.println(" -out Local directory for storing individual"); pw.println(" container logs. The container logs will"); @@ -364,7 +363,8 @@ public ContainerReport getContainerReport(String containerIdStr) "-logFiles", "123"}); assertTrue(exitCode == -1); assertTrue(sysErrStream.toString().contains( - "Can not find any log file matching the pattern: [123]")); + "Can not find any log file matching the pattern: [123] " + + "for the application: " + appId.toString())); sysErrStream.reset(); // specify the bytes which is larger than the actual file size, @@ -392,6 +392,15 @@ public ContainerReport getContainerReport(String containerIdStr) sysOutStream.reset(); exitCode = cli.run(new String[] {"-applicationId", appId.toString(), + "-containerId", containerId3.toString(), "-logFiles", "123" }); + assertTrue(exitCode == -1); + assertTrue(sysErrStream.toString().contains( + "Can not find any log file matching the pattern: [123] " + + "for the container: " + containerId3 + + " within the application: " + appId.toString())); + sysErrStream.reset(); + + exitCode = cli.run(new String[] {"-applicationId", appId.toString(), "-containerId", containerId3.toString(), "-logFiles", "stdout" }); assertTrue(exitCode == 0); int fullContextSize = sysOutStream.toByteArray().length; @@ -530,7 +539,7 @@ public void testFetchRunningApplicationLogs() throws Exception { YarnApplicationState.RUNNING, ugi.getShortUserName(), true, attemptReports, containerReports); LogsCLI cli = spy(new LogsCLIForTest(mockYarnClient)); - doNothing().when(cli).printContainerLogsFromRunningApplication( + doReturn(0).when(cli).printContainerLogsFromRunningApplication( any(Configuration.class), any(ContainerLogsRequest.class), any(LogCLIHelpers.class));