YARN-5470. Differentiate exactly match with regex in yarn log CLI. Contributed by Xuan Gong.

(cherry picked from commit e605d47df0)
This commit is contained in:
Junping Du 2016-08-05 10:54:36 -07:00
parent a73e118437
commit adcecd417b
4 changed files with 137 additions and 75 deletions

View File

@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -90,6 +91,7 @@ public class LogsCLI extends Configured implements Tool {
= "show_container_log_info"; = "show_container_log_info";
private static final String OUT_OPTION = "out"; private static final String OUT_OPTION = "out";
private static final String SIZE_OPTION = "size"; private static final String SIZE_OPTION = "size";
private static final String REGEX_OPTION = "regex";
public static final String HELP_CMD = "help"; public static final String HELP_CMD = "help";
private PrintStream outStream = System.out; private PrintStream outStream = System.out;
private YarnClient yarnClient = null; private YarnClient yarnClient = null;
@ -126,6 +128,7 @@ public class LogsCLI extends Configured implements Tool {
boolean nodesList = false; boolean nodesList = false;
boolean showApplicationLogInfo = false; boolean showApplicationLogInfo = false;
boolean showContainerLogInfo = false; boolean showContainerLogInfo = false;
boolean useRegex = false;
String[] logFiles = null; String[] logFiles = null;
List<String> amContainersList = new ArrayList<String>(); List<String> amContainersList = new ArrayList<String>();
String localDir = null; String localDir = null;
@ -142,6 +145,7 @@ public class LogsCLI extends Configured implements Tool {
showApplicationLogInfo = commandLine.hasOption( showApplicationLogInfo = commandLine.hasOption(
SHOW_APPLICATION_LOG_INFO); SHOW_APPLICATION_LOG_INFO);
showContainerLogInfo = commandLine.hasOption(SHOW_CONTAINER_LOG_INFO); showContainerLogInfo = commandLine.hasOption(SHOW_CONTAINER_LOG_INFO);
useRegex = commandLine.hasOption(REGEX_OPTION);
if (getAMContainerLogs) { if (getAMContainerLogs) {
try { try {
amContainersList = parseAMContainer(commandLine, printOpts); amContainersList = parseAMContainer(commandLine, printOpts);
@ -243,11 +247,11 @@ public class LogsCLI extends Configured implements Tool {
} }
} }
List<String> logs = new ArrayList<String>(); Set<String> logs = new HashSet<String>();
if (fetchAllLogFiles(logFiles)) { if (fetchAllLogFiles(logFiles, useRegex)) {
logs.add(".*"); logs.add("ALL");
} else if (logFiles != null && logFiles.length > 0) { } else if (logFiles != null && logFiles.length > 0) {
logs = Arrays.asList(logFiles); logs.addAll(Arrays.asList(logFiles));
} }
ContainerLogsRequest request = new ContainerLogsRequest(appId, ContainerLogsRequest request = new ContainerLogsRequest(appId,
@ -268,15 +272,15 @@ public class LogsCLI extends Configured implements Tool {
// To get am logs // To get am logs
if (getAMContainerLogs) { if (getAMContainerLogs) {
return fetchAMContainerLogs(request, amContainersList, return fetchAMContainerLogs(request, amContainersList,
logCliHelper); logCliHelper, useRegex);
} }
int resultCode = 0; int resultCode = 0;
if (containerIdStr != null) { if (containerIdStr != null) {
return fetchContainerLogs(request, logCliHelper); return fetchContainerLogs(request, logCliHelper, useRegex);
} else { } else {
if (nodeAddress == null) { if (nodeAddress == null) {
resultCode = fetchApplicationLogs(request, logCliHelper); resultCode = fetchApplicationLogs(request, logCliHelper, useRegex);
} else { } else {
System.err.println("Should at least provide ContainerId!"); System.err.println("Should at least provide ContainerId!");
printHelpMessage(printOpts); printHelpMessage(printOpts);
@ -362,7 +366,7 @@ public class LogsCLI extends Configured implements Tool {
return amContainersList; return amContainersList;
} }
private boolean fetchAllLogFiles(String[] logFiles) { private boolean fetchAllLogFiles(String[] logFiles, boolean useRegex) {
// If no value is specified for the PER_CONTAINER_LOG_FILES_OPTION option, // If no value is specified for the PER_CONTAINER_LOG_FILES_OPTION option,
// we will assume all logs. // we will assume all logs.
@ -371,7 +375,8 @@ public class LogsCLI extends Configured implements Tool {
} }
List<String> logs = Arrays.asList(logFiles); List<String> logs = Arrays.asList(logFiles);
if (logs.contains("ALL") || logs.contains(".*")) { if (logs.contains("ALL") || logs.contains("*")||
(logs.contains(".*") && useRegex)) {
return true; return true;
} }
@ -418,8 +423,8 @@ public class LogsCLI extends Configured implements Tool {
@Private @Private
@VisibleForTesting @VisibleForTesting
public int printContainerLogsFromRunningApplication(Configuration conf, public int printContainerLogsFromRunningApplication(Configuration conf,
ContainerLogsRequest request, LogCLIHelpers logCliHelper) ContainerLogsRequest request, LogCLIHelpers logCliHelper,
throws IOException { boolean useRegex) throws IOException {
String containerIdStr = request.getContainerId().toString(); String containerIdStr = request.getContainerId().toString();
String localDir = request.getOutputLocalDir(); String localDir = request.getOutputLocalDir();
String nodeHttpAddress = request.getNodeHttpAddress(); String nodeHttpAddress = request.getNodeHttpAddress();
@ -442,7 +447,8 @@ public class LogsCLI extends Configured implements Tool {
for (PerLogFileInfo fileInfo : allLogFileInfos) { for (PerLogFileInfo fileInfo : allLogFileInfos) {
fileNames.add(fileInfo.getFileName()); fileNames.add(fileInfo.getFileName());
} }
List<String> matchedFiles = getMatchedLogFiles(request, fileNames); Set<String> matchedFiles = getMatchedLogFiles(request, fileNames,
useRegex);
if (matchedFiles.isEmpty()) { if (matchedFiles.isEmpty()) {
System.err.println("Can not find any log file matching the pattern: " System.err.println("Can not find any log file matching the pattern: "
+ request.getLogTypes() + " for the container: " + containerIdStr + request.getLogTypes() + " for the container: " + containerIdStr
@ -504,10 +510,10 @@ public class LogsCLI extends Configured implements Tool {
} }
private int printContainerLogsForFinishedApplication( private int printContainerLogsForFinishedApplication(
ContainerLogsRequest request, LogCLIHelpers logCliHelper) ContainerLogsRequest request, LogCLIHelpers logCliHelper,
throws IOException { boolean useRegex) throws IOException {
ContainerLogsRequest newOptions = getMatchedLogOptions( ContainerLogsRequest newOptions = getMatchedLogOptions(
request, logCliHelper); request, logCliHelper, useRegex);
if (newOptions == null) { if (newOptions == null) {
System.err.println("Can not find any log file matching the pattern: " System.err.println("Can not find any log file matching the pattern: "
+ request.getLogTypes() + " for the container: " + request.getLogTypes() + " for the container: "
@ -519,10 +525,10 @@ public class LogsCLI extends Configured implements Tool {
} }
private int printContainerLogsForFinishedApplicationWithoutNodeId( private int printContainerLogsForFinishedApplicationWithoutNodeId(
ContainerLogsRequest request, LogCLIHelpers logCliHelper) ContainerLogsRequest request, LogCLIHelpers logCliHelper,
throws IOException { boolean useRegex) throws IOException {
ContainerLogsRequest newOptions = getMatchedLogOptions( ContainerLogsRequest newOptions = getMatchedLogOptions(
request, logCliHelper); request, logCliHelper, useRegex);
if (newOptions == null) { if (newOptions == null) {
System.err.println("Can not find any log file matching the pattern: " System.err.println("Can not find any log file matching the pattern: "
+ request.getLogTypes() + " for the container: " + request.getLogTypes() + " for the container: "
@ -550,7 +556,7 @@ public class LogsCLI extends Configured implements Tool {
private int printAMContainerLogs(Configuration conf, private int printAMContainerLogs(Configuration conf,
ContainerLogsRequest request, List<String> amContainers, ContainerLogsRequest request, List<String> amContainers,
LogCLIHelpers logCliHelper) throws Exception { LogCLIHelpers logCliHelper, boolean useRegex) throws Exception {
List<JSONObject> amContainersList = null; List<JSONObject> amContainersList = null;
List<ContainerLogsRequest> requests = List<ContainerLogsRequest> requests =
new ArrayList<ContainerLogsRequest>(); new ArrayList<ContainerLogsRequest>();
@ -614,7 +620,7 @@ public class LogsCLI extends Configured implements Tool {
if (amContainers.contains("ALL")) { if (amContainers.contains("ALL")) {
for (ContainerLogsRequest amRequest : requests) { for (ContainerLogsRequest amRequest : requests) {
outputAMContainerLogs(amRequest, conf, logCliHelper); outputAMContainerLogs(amRequest, conf, logCliHelper, useRegex);
} }
outStream.println(); outStream.println();
outStream.println("Specified ALL for -am option. " outStream.println("Specified ALL for -am option. "
@ -624,11 +630,11 @@ public class LogsCLI extends Configured implements Tool {
int amContainerId = Integer.parseInt(amContainer.trim()); int amContainerId = Integer.parseInt(amContainer.trim());
if (amContainerId == -1) { if (amContainerId == -1) {
outputAMContainerLogs(requests.get(requests.size() - 1), conf, outputAMContainerLogs(requests.get(requests.size() - 1), conf,
logCliHelper); logCliHelper, useRegex);
} else { } else {
if (amContainerId <= requests.size()) { if (amContainerId <= requests.size()) {
outputAMContainerLogs(requests.get(amContainerId - 1), conf, outputAMContainerLogs(requests.get(amContainerId - 1), conf,
logCliHelper); logCliHelper, useRegex);
} else { } else {
System.err.println(String.format("ERROR: Specified AM containerId" System.err.println(String.format("ERROR: Specified AM containerId"
+ " (%s) exceeds the number of AM containers (%s).", + " (%s) exceeds the number of AM containers (%s).",
@ -642,7 +648,8 @@ public class LogsCLI extends Configured implements Tool {
} }
private void outputAMContainerLogs(ContainerLogsRequest request, private void outputAMContainerLogs(ContainerLogsRequest request,
Configuration conf, LogCLIHelpers logCliHelper) throws Exception { Configuration conf, LogCLIHelpers logCliHelper, boolean useRegex)
throws Exception {
String nodeHttpAddress = request.getNodeHttpAddress(); String nodeHttpAddress = request.getNodeHttpAddress();
String containerId = request.getContainerId(); String containerId = request.getContainerId();
String nodeId = request.getNodeId(); String nodeId = request.getNodeId();
@ -651,10 +658,10 @@ public class LogsCLI extends Configured implements Tool {
if (containerId != null && !containerId.isEmpty()) { if (containerId != null && !containerId.isEmpty()) {
if (nodeId != null && !nodeId.isEmpty()) { if (nodeId != null && !nodeId.isEmpty()) {
printContainerLogsForFinishedApplication(request, printContainerLogsForFinishedApplication(request,
logCliHelper); logCliHelper, useRegex);
} else { } else {
printContainerLogsForFinishedApplicationWithoutNodeId( printContainerLogsForFinishedApplicationWithoutNodeId(
request, logCliHelper); request, logCliHelper, useRegex);
} }
} }
} else { } else {
@ -664,7 +671,7 @@ public class LogsCLI extends Configured implements Tool {
.getContainerState(); .getContainerState();
request.setContainerState(containerState); request.setContainerState(containerState);
printContainerLogsFromRunningApplication(conf, printContainerLogsFromRunningApplication(conf,
request, logCliHelper); request, logCliHelper, useRegex);
} }
} }
} }
@ -747,12 +754,15 @@ public class LogsCLI extends Configured implements Tool {
opts.addOption(amOption); opts.addOption(amOption);
Option logFileOpt = new Option(PER_CONTAINER_LOG_FILES_OPTION, true, Option logFileOpt = new Option(PER_CONTAINER_LOG_FILES_OPTION, true,
"Specify comma-separated value " "Specify comma-separated value "
+ "to get specified container log files. Use \"ALL\" to fetch all the " + "to get exact matched log files. Use \"ALL\" or \"*\"to "
+ "log files for the container. It also supports Java Regex."); + "fetch all the log files for the container. Specific -regex "
+ "for using java regex to find matched log files.");
logFileOpt.setValueSeparator(','); logFileOpt.setValueSeparator(',');
logFileOpt.setArgs(Option.UNLIMITED_VALUES); logFileOpt.setArgs(Option.UNLIMITED_VALUES);
logFileOpt.setArgName("Log File Name"); logFileOpt.setArgName("Log File Name");
opts.addOption(logFileOpt); opts.addOption(logFileOpt);
opts.addOption(REGEX_OPTION, false, "Work with -log_files to find "
+ "matched files by using java regex.");
opts.addOption(SHOW_CONTAINER_LOG_INFO, false, opts.addOption(SHOW_CONTAINER_LOG_INFO, false,
"Show the container log metadata, " "Show the container log metadata, "
+ "including log-file names, the size of the log files. " + "including log-file names, the size of the log files. "
@ -795,6 +805,7 @@ public class LogsCLI extends Configured implements Tool {
printOpts.addOption(commandOpts.getOption(SHOW_CONTAINER_LOG_INFO)); printOpts.addOption(commandOpts.getOption(SHOW_CONTAINER_LOG_INFO));
printOpts.addOption(commandOpts.getOption(OUT_OPTION)); printOpts.addOption(commandOpts.getOption(OUT_OPTION));
printOpts.addOption(commandOpts.getOption(SIZE_OPTION)); printOpts.addOption(commandOpts.getOption(SIZE_OPTION));
printOpts.addOption(commandOpts.getOption(REGEX_OPTION));
return printOpts; return printOpts;
} }
@ -830,14 +841,14 @@ public class LogsCLI extends Configured implements Tool {
} }
private int fetchAMContainerLogs(ContainerLogsRequest request, private int fetchAMContainerLogs(ContainerLogsRequest request,
List<String> amContainersList, LogCLIHelpers logCliHelper) List<String> amContainersList, LogCLIHelpers logCliHelper,
throws Exception { boolean useRegex) throws Exception {
return printAMContainerLogs(getConf(), request, amContainersList, return printAMContainerLogs(getConf(), request, amContainersList,
logCliHelper); logCliHelper, useRegex);
} }
private int fetchContainerLogs(ContainerLogsRequest request, private int fetchContainerLogs(ContainerLogsRequest request,
LogCLIHelpers logCliHelper) throws IOException { LogCLIHelpers logCliHelper, boolean useRegex) throws IOException {
int resultCode = 0; int resultCode = 0;
String appIdStr = request.getAppId().toString(); String appIdStr = request.getAppId().toString();
String containerIdStr = request.getContainerId(); String containerIdStr = request.getContainerId();
@ -851,10 +862,10 @@ public class LogsCLI extends Configured implements Tool {
// to logCliHelper so that it fetches all the logs // to logCliHelper so that it fetches all the logs
if (nodeAddress != null && !nodeAddress.isEmpty()) { if (nodeAddress != null && !nodeAddress.isEmpty()) {
return printContainerLogsForFinishedApplication( return printContainerLogsForFinishedApplication(
request, logCliHelper); request, logCliHelper, useRegex);
} else { } else {
return printContainerLogsForFinishedApplicationWithoutNodeId( return printContainerLogsForFinishedApplicationWithoutNodeId(
request, logCliHelper); request, logCliHelper, useRegex);
} }
} }
String nodeHttpAddress = null; String nodeHttpAddress = null;
@ -876,7 +887,7 @@ public class LogsCLI extends Configured implements Tool {
} catch (IOException | YarnException ex) { } catch (IOException | YarnException ex) {
if (isAppFinished) { if (isAppFinished) {
return printContainerLogsForFinishedApplicationWithoutNodeId( return printContainerLogsForFinishedApplicationWithoutNodeId(
request, logCliHelper); request, logCliHelper, useRegex);
} else { } else {
System.err.println("Unable to get logs for this container:" System.err.println("Unable to get logs for this container:"
+ containerIdStr + "for the application:" + appIdStr + containerIdStr + "for the application:" + appIdStr
@ -893,18 +904,19 @@ public class LogsCLI extends Configured implements Tool {
// by calling NodeManager webservice. // by calling NodeManager webservice.
if (!isAppFinished) { if (!isAppFinished) {
resultCode = printContainerLogsFromRunningApplication(getConf(), request, resultCode = printContainerLogsFromRunningApplication(getConf(), request,
logCliHelper); logCliHelper, useRegex);
} else { } else {
// If the application is in the final state, we will directly // If the application is in the final state, we will directly
// get the container logs from HDFS. // get the container logs from HDFS.
resultCode = printContainerLogsForFinishedApplication( resultCode = printContainerLogsForFinishedApplication(
request, logCliHelper); request, logCliHelper, useRegex);
} }
return resultCode; return resultCode;
} }
private int fetchApplicationLogs(ContainerLogsRequest options, private int fetchApplicationLogs(ContainerLogsRequest options,
LogCLIHelpers logCliHelper) throws IOException, YarnException { LogCLIHelpers logCliHelper, boolean useRegex) throws IOException,
YarnException {
// If the application has finished, we would fetch the logs // If the application has finished, we would fetch the logs
// from HDFS. // from HDFS.
// If the application is still running, we would get the full // If the application is still running, we would get the full
@ -913,7 +925,7 @@ public class LogsCLI extends Configured implements Tool {
int resultCode = -1; int resultCode = -1;
if (options.isAppFinished()) { if (options.isAppFinished()) {
ContainerLogsRequest newOptions = getMatchedLogOptions( ContainerLogsRequest newOptions = getMatchedLogOptions(
options, logCliHelper); options, logCliHelper, useRegex);
if (newOptions == null) { if (newOptions == null) {
System.err.println("Can not find any log file matching the pattern: " System.err.println("Can not find any log file matching the pattern: "
+ options.getLogTypes() + " for the application: " + options.getLogTypes() + " for the application: "
@ -927,7 +939,7 @@ public class LogsCLI extends Configured implements Tool {
getContainersLogRequestForRunningApplication(options); getContainersLogRequestForRunningApplication(options);
for (ContainerLogsRequest container : containerLogRequests) { for (ContainerLogsRequest container : containerLogRequests) {
int result = printContainerLogsFromRunningApplication(getConf(), int result = printContainerLogsFromRunningApplication(getConf(),
container, logCliHelper); container, logCliHelper, useRegex);
if (result == 0) { if (result == 0) {
resultCode = 0; resultCode = 0;
} }
@ -956,14 +968,14 @@ public class LogsCLI extends Configured implements Tool {
} }
private ContainerLogsRequest getMatchedLogOptions( private ContainerLogsRequest getMatchedLogOptions(
ContainerLogsRequest request, LogCLIHelpers logCliHelper) ContainerLogsRequest request, LogCLIHelpers logCliHelper,
throws IOException { boolean useRegex) throws IOException {
ContainerLogsRequest newOptions = new ContainerLogsRequest(request); ContainerLogsRequest newOptions = new ContainerLogsRequest(request);
if (request.getLogTypes() != null && !request.getLogTypes().isEmpty()) { if (request.getLogTypes() != null && !request.getLogTypes().isEmpty()) {
List<String> matchedFiles = new ArrayList<String>(); Set<String> matchedFiles = new HashSet<String>();
if (!request.getLogTypes().contains(".*")) { if (!request.getLogTypes().contains("ALL")) {
Set<String> files = logCliHelper.listContainerLogs(request); Set<String> files = logCliHelper.listContainerLogs(request);
matchedFiles = getMatchedLogFiles(request, files); matchedFiles = getMatchedLogFiles(request, files, useRegex);
if (matchedFiles.isEmpty()) { if (matchedFiles.isEmpty()) {
return null; return null;
} }
@ -973,20 +985,29 @@ public class LogsCLI extends Configured implements Tool {
return newOptions; return newOptions;
} }
private List<String> getMatchedLogFiles(ContainerLogsRequest options, private Set<String> getMatchedLogFiles(ContainerLogsRequest options,
Collection<String> candidate) throws IOException { Collection<String> candidate, boolean useRegex) throws IOException {
List<String> matchedFiles = new ArrayList<String>(); Set<String> matchedFiles = new HashSet<String>();
List<String> filePattern = options.getLogTypes(); Set<String> filePattern = options.getLogTypes();
if (options.getLogTypes().contains("ALL")) {
return new HashSet<String>(candidate);
}
for (String file : candidate) { for (String file : candidate) {
if (isFileMatching(file, filePattern)) { if (useRegex) {
matchedFiles.add(file); if (isFileMatching(file, filePattern)) {
matchedFiles.add(file);
}
} else {
if (filePattern.contains(file)) {
matchedFiles.add(file);
}
} }
} }
return matchedFiles; return matchedFiles;
} }
private boolean isFileMatching(String fileType, private boolean isFileMatching(String fileType,
List<String> logTypes) { Set<String> logTypes) {
for (String logType : logTypes) { for (String logType : logTypes) {
Pattern filterPattern = Pattern.compile(logType); Pattern filterPattern = Pattern.compile(logType);
boolean match = filterPattern.matcher(fileType).find(); boolean match = filterPattern.matcher(fileType).find();

View File

@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -46,7 +47,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileStatus;
@ -211,14 +212,17 @@ public class TestLogsCLI {
pw.println(" aggregated logs. This option can only be"); pw.println(" aggregated logs. This option can only be");
pw.println(" used with finished applications."); pw.println(" used with finished applications.");
pw.println(" -log_files <Log File Name> Specify comma-separated value to get"); pw.println(" -log_files <Log File Name> Specify comma-separated value to get");
pw.println(" specified container log files. Use \"ALL\""); pw.println(" exact matched log files. Use \"ALL\" or");
pw.println(" to fetch all the log files for the"); pw.println(" \"*\"to fetch all the log files for the");
pw.println(" container. It also supports Java Regex."); pw.println(" container. Specific -regex for using java");
pw.println(" regex to find matched log files.");
pw.println(" -nodeAddress <Node Address> NodeAddress in the format nodename:port"); pw.println(" -nodeAddress <Node Address> NodeAddress in the format nodename:port");
pw.println(" -out <Local Directory> Local directory for storing individual"); pw.println(" -out <Local Directory> Local directory for storing individual");
pw.println(" container logs. The container logs will"); pw.println(" container logs. The container logs will");
pw.println(" be stored based on the node the container"); pw.println(" be stored based on the node the container");
pw.println(" ran on."); pw.println(" ran on.");
pw.println(" -regex Work with -log_files to find matched");
pw.println(" files by using java regex.");
pw.println(" -show_application_log_info Show the containerIds which belong to the"); pw.println(" -show_application_log_info Show the containerIds which belong to the");
pw.println(" specific Application. You can combine"); pw.println(" specific Application. You can combine");
pw.println(" this with --nodeAddress to get"); pw.println(" this with --nodeAddress to get");
@ -286,6 +290,7 @@ public class TestLogsCLI {
// create two logs for container3 in localLogDir // create two logs for container3 in localLogDir
logTypes.add("stdout"); logTypes.add("stdout");
logTypes.add("stdout1234");
createContainerLogInLocalDir(appLogsDir, containerId3, fs, logTypes); createContainerLogInLocalDir(appLogsDir, containerId3, fs, logTypes);
Path path = Path path =
@ -336,10 +341,12 @@ public class TestLogsCLI {
logMessage(containerId3, "syslog"))); logMessage(containerId3, "syslog")));
assertTrue(sysOutStream.toString().contains( assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout"))); logMessage(containerId3, "stdout")));
assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout1234")));
sysOutStream.reset(); sysOutStream.reset();
exitCode = cli.run(new String[] {"-applicationId", appId.toString(), exitCode = cli.run(new String[] {"-applicationId", appId.toString(),
"-log_files", ".*"}); "-log_files", ".*", "-regex"});
assertTrue(exitCode == 0); assertTrue(exitCode == 0);
assertTrue(sysOutStream.toString().contains( assertTrue(sysOutStream.toString().contains(
logMessage(containerId1, "syslog"))); logMessage(containerId1, "syslog")));
@ -349,11 +356,28 @@ public class TestLogsCLI {
logMessage(containerId3, "syslog"))); logMessage(containerId3, "syslog")));
assertTrue(sysOutStream.toString().contains( assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout"))); logMessage(containerId3, "stdout")));
assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout1234")));
sysOutStream.reset();
exitCode = cli.run(new String[] {"-applicationId", appId.toString(),
"-log_files", "*"});
assertTrue(exitCode == 0);
assertTrue(sysOutStream.toString().contains(
logMessage(containerId1, "syslog")));
assertTrue(sysOutStream.toString().contains(
logMessage(containerId2, "syslog")));
assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "syslog")));
assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout")));
assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout1234")));
int fullSize = sysOutStream.toByteArray().length; int fullSize = sysOutStream.toByteArray().length;
sysOutStream.reset(); sysOutStream.reset();
exitCode = cli.run(new String[] {"-applicationId", appId.toString(), exitCode = cli.run(new String[] {"-applicationId", appId.toString(),
"-log_files", "std*"}); "-log_files", "stdout"});
assertTrue(exitCode == 0); assertTrue(exitCode == 0);
assertFalse(sysOutStream.toString().contains( assertFalse(sysOutStream.toString().contains(
logMessage(containerId1, "syslog"))); logMessage(containerId1, "syslog")));
@ -363,6 +387,23 @@ public class TestLogsCLI {
logMessage(containerId3, "syslog"))); logMessage(containerId3, "syslog")));
assertTrue(sysOutStream.toString().contains( assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout"))); logMessage(containerId3, "stdout")));
assertFalse(sysOutStream.toString().contains(
logMessage(containerId3, "stdout1234")));
sysOutStream.reset();
exitCode = cli.run(new String[] {"-applicationId", appId.toString(),
"-log_files", "std*", "-regex"});
assertTrue(exitCode == 0);
assertFalse(sysOutStream.toString().contains(
logMessage(containerId1, "syslog")));
assertFalse(sysOutStream.toString().contains(
logMessage(containerId2, "syslog")));
assertFalse(sysOutStream.toString().contains(
logMessage(containerId3, "syslog")));
assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout")));
assertTrue(sysOutStream.toString().contains(
logMessage(containerId3, "stdout1234")));
sysOutStream.reset(); sysOutStream.reset();
exitCode = cli.run(new String[] {"-applicationId", appId.toString(), exitCode = cli.run(new String[] {"-applicationId", appId.toString(),
@ -376,7 +417,7 @@ public class TestLogsCLI {
// specify the bytes which is larger than the actual file size, // specify the bytes which is larger than the actual file size,
// we would get the full logs // we would get the full logs
exitCode = cli.run(new String[] {"-applicationId", appId.toString(), exitCode = cli.run(new String[] {"-applicationId", appId.toString(),
"-log_files", ".*", "-size", "10000" }); "-log_files", "*", "-size", "10000" });
assertTrue(exitCode == 0); assertTrue(exitCode == 0);
assertTrue(sysOutStream.toByteArray().length == fullSize); assertTrue(sysOutStream.toByteArray().length == fullSize);
sysOutStream.reset(); sysOutStream.reset();
@ -568,7 +609,7 @@ public class TestLogsCLI {
LogsCLI cli = spy(new LogsCLIForTest(mockYarnClient)); LogsCLI cli = spy(new LogsCLIForTest(mockYarnClient));
doReturn(0).when(cli).printContainerLogsFromRunningApplication( doReturn(0).when(cli).printContainerLogsFromRunningApplication(
any(Configuration.class), any(ContainerLogsRequest.class), any(Configuration.class), any(ContainerLogsRequest.class),
any(LogCLIHelpers.class)); any(LogCLIHelpers.class), anyBoolean());
cli.setConf(new YarnConfiguration()); cli.setConf(new YarnConfiguration());
int exitCode = cli.run(new String[] {"-applicationId", appId.toString()}); int exitCode = cli.run(new String[] {"-applicationId", appId.toString()});
@ -581,16 +622,16 @@ public class TestLogsCLI {
// printContainerLogsFromRunningApplication twice // printContainerLogsFromRunningApplication twice
verify(cli, times(2)).printContainerLogsFromRunningApplication( verify(cli, times(2)).printContainerLogsFromRunningApplication(
any(Configuration.class), logsRequestCaptor.capture(), any(Configuration.class), logsRequestCaptor.capture(),
any(LogCLIHelpers.class)); any(LogCLIHelpers.class), anyBoolean());
// Verify that the log-type is * // Verify that the log-type is "ALL"
List<ContainerLogsRequest> capturedRequests = List<ContainerLogsRequest> capturedRequests =
logsRequestCaptor.getAllValues(); logsRequestCaptor.getAllValues();
Assert.assertEquals(2, capturedRequests.size()); Assert.assertEquals(2, capturedRequests.size());
List<String> logTypes0 = capturedRequests.get(0).getLogTypes(); Set<String> logTypes0 = capturedRequests.get(0).getLogTypes();
List<String> logTypes1 = capturedRequests.get(1).getLogTypes(); Set<String> logTypes1 = capturedRequests.get(1).getLogTypes();
Assert.assertEquals(".*", logTypes0.get(0)); Assert.assertTrue(logTypes0.contains("ALL") && (logTypes0.size() == 1));
Assert.assertEquals(".*", logTypes1.get(0)); Assert.assertTrue(logTypes1.contains("ALL") && (logTypes1.size() == 1));
} }
@Test (timeout = 15000) @Test (timeout = 15000)

View File

@ -18,7 +18,7 @@
package org.apache.hadoop.yarn.logaggregation; package org.apache.hadoop.yarn.logaggregation;
import java.util.List; import java.util.Set;
import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ContainerState; import org.apache.hadoop.yarn.api.records.ContainerState;
@ -30,7 +30,7 @@ public class ContainerLogsRequest {
private String appOwner; private String appOwner;
private boolean appFinished; private boolean appFinished;
private String outputLocalDir; private String outputLocalDir;
private List<String> logTypes; private Set<String> logTypes;
private long bytes; private long bytes;
private ContainerState containerState; private ContainerState containerState;
@ -52,7 +52,7 @@ public class ContainerLogsRequest {
public ContainerLogsRequest(ApplicationId applicationId, public ContainerLogsRequest(ApplicationId applicationId,
boolean isAppFinished, String owner, boolean isAppFinished, String owner,
String address, String httpAddress, String container, String localDir, String address, String httpAddress, String container, String localDir,
List<String> logs, long bytes, ContainerState containerState) { Set<String> logs, long bytes, ContainerState containerState) {
this.setAppId(applicationId); this.setAppId(applicationId);
this.setAppFinished(isAppFinished); this.setAppFinished(isAppFinished);
this.setAppOwner(owner); this.setAppOwner(owner);
@ -121,11 +121,11 @@ public class ContainerLogsRequest {
this.outputLocalDir = outputLocalDir; this.outputLocalDir = outputLocalDir;
} }
public List<String> getLogTypes() { public Set<String> getLogTypes() {
return logTypes; return logTypes;
} }
public void setLogTypes(List<String> logTypes) { public void setLogTypes(Set<String> logTypes) {
this.logTypes = logTypes; this.logTypes = logTypes;
} }

View File

@ -67,7 +67,7 @@ public class LogCLIHelpers implements Configurable {
options.setContainerId(containerId); options.setContainerId(containerId);
options.setNodeId(nodeId); options.setNodeId(nodeId);
options.setAppOwner(jobOwner); options.setAppOwner(jobOwner);
List<String> logs = new ArrayList<String>(); Set<String> logs = new HashSet<String>();
options.setLogTypes(logs); options.setLogTypes(logs);
options.setBytes(Long.MAX_VALUE); options.setBytes(Long.MAX_VALUE);
return dumpAContainerLogsForLogType(options, false); return dumpAContainerLogsForLogType(options, false);
@ -136,7 +136,7 @@ public class LogCLIHelpers implements Configurable {
String nodeId = options.getNodeId(); String nodeId = options.getNodeId();
String containerId = options.getContainerId(); String containerId = options.getContainerId();
String localDir = options.getOutputLocalDir(); String localDir = options.getOutputLocalDir();
List<String> logType = options.getLogTypes(); List<String> logType = new ArrayList<String>(options.getLogTypes());
RemoteIterator<FileStatus> nodeFiles = getRemoteNodeFileDir( RemoteIterator<FileStatus> nodeFiles = getRemoteNodeFileDir(
applicationId, jobOwner); applicationId, jobOwner);
if (nodeFiles == null) { if (nodeFiles == null) {
@ -208,7 +208,7 @@ public class LogCLIHelpers implements Configurable {
String jobOwner = options.getAppOwner(); String jobOwner = options.getAppOwner();
String containerId = options.getContainerId(); String containerId = options.getContainerId();
String localDir = options.getOutputLocalDir(); String localDir = options.getOutputLocalDir();
List<String> logType = options.getLogTypes(); List<String> logType = new ArrayList<String>(options.getLogTypes());
RemoteIterator<FileStatus> nodeFiles = getRemoteNodeFileDir( RemoteIterator<FileStatus> nodeFiles = getRemoteNodeFileDir(
applicationId, jobOwner); applicationId, jobOwner);
if (nodeFiles == null) { if (nodeFiles == null) {
@ -344,7 +344,7 @@ public class LogCLIHelpers implements Configurable {
ApplicationId appId = options.getAppId(); ApplicationId appId = options.getAppId();
String appOwner = options.getAppOwner(); String appOwner = options.getAppOwner();
String localDir = options.getOutputLocalDir(); String localDir = options.getOutputLocalDir();
List<String> logTypes = options.getLogTypes(); List<String> logTypes = new ArrayList<String>(options.getLogTypes());
RemoteIterator<FileStatus> nodeFiles = getRemoteNodeFileDir( RemoteIterator<FileStatus> nodeFiles = getRemoteNodeFileDir(
appId, appOwner); appId, appOwner);
if (nodeFiles == null) { if (nodeFiles == null) {