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

This commit is contained in:
Junping Du 2016-08-05 10:54:36 -07:00
parent 3f100d76ff
commit e605d47df0
4 changed files with 137 additions and 75 deletions

View File

@ -25,6 +25,7 @@
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 @@ private int runCommand(String[] args) throws Exception {
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 @@ private int runCommand(String[] args) throws Exception {
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 @@ private int runCommand(String[] args) throws Exception {
} }
} }
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 @@ private int runCommand(String[] args) throws Exception {
// 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 @@ private List<JSONObject> getAMContainerInfoForAHSWebService(
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 @@ private boolean fetchAllLogFiles(String[] logFiles) {
} }
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;
} }
@ -417,8 +422,8 @@ private List<PerLogFileInfo> getContainerLogFiles(Configuration conf,
@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();
@ -441,7 +446,8 @@ public int printContainerLogsFromRunningApplication(Configuration conf,
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
@ -503,10 +509,10 @@ public int printContainerLogsFromRunningApplication(Configuration conf,
} }
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: "
@ -518,10 +524,10 @@ private int printContainerLogsForFinishedApplication(
} }
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: "
@ -549,7 +555,7 @@ private boolean isApplicationFinished(YarnApplicationState appState) {
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>();
@ -613,7 +619,7 @@ private int printAMContainerLogs(Configuration conf,
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. "
@ -623,11 +629,11 @@ private int printAMContainerLogs(Configuration conf,
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).",
@ -641,7 +647,8 @@ private int printAMContainerLogs(Configuration conf,
} }
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();
@ -650,10 +657,10 @@ private void outputAMContainerLogs(ContainerLogsRequest request,
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 {
@ -663,7 +670,7 @@ private void outputAMContainerLogs(ContainerLogsRequest request,
.getContainerState(); .getContainerState();
request.setContainerState(containerState); request.setContainerState(containerState);
printContainerLogsFromRunningApplication(conf, printContainerLogsFromRunningApplication(conf,
request, logCliHelper); request, logCliHelper, useRegex);
} }
} }
} }
@ -746,12 +753,15 @@ private Options createCommandOpts() {
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. "
@ -794,6 +804,7 @@ private Options createPrintOpts(Options commandOpts) {
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;
} }
@ -829,14 +840,14 @@ private List<String> parseAMContainer(CommandLine commandLine,
} }
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();
@ -850,10 +861,10 @@ private int fetchContainerLogs(ContainerLogsRequest request,
// 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;
@ -875,7 +886,7 @@ private int fetchContainerLogs(ContainerLogsRequest request,
} 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
@ -892,18 +903,19 @@ private int fetchContainerLogs(ContainerLogsRequest request,
// 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
@ -912,7 +924,7 @@ private int fetchApplicationLogs(ContainerLogsRequest options,
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: "
@ -926,7 +938,7 @@ private int fetchApplicationLogs(ContainerLogsRequest options,
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;
} }
@ -955,14 +967,14 @@ private String guessAppOwner(ApplicationReport appReport,
} }
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;
} }
@ -972,20 +984,29 @@ private ContainerLogsRequest getMatchedLogOptions(
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.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.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 void testHelpMessage() throws Exception {
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 void testFetchFinishedApplictionLogs() throws Exception {
// 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 ContainerReport getContainerReport(String containerIdStr)
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 ContainerReport getContainerReport(String containerIdStr)
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 ContainerReport getContainerReport(String containerIdStr)
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 ContainerReport getContainerReport(String containerIdStr)
// 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 void testFetchRunningApplicationLogs() throws Exception {
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 void testFetchRunningApplicationLogs() throws Exception {
// 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 ContainerLogsRequest(ContainerLogsRequest request) {
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 void setOutputLocalDir(String outputLocalDir) {
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 int dumpAContainersLogs(String appId, String containerId,
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 int dumpAContainerLogsForLogType(ContainerLogsRequest options,
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 int dumpAContainerLogsForLogTypeWithoutNodeId(
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 int dumpAllContainersLogs(ContainerLogsRequest options)
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) {