YARN-1145. Fixed a potential file-handle leak in the web interface for displaying aggregated logs. Contributed by Rohith Sharma.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1551326 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Vinod Kumar Vavilapalli 2013-12-16 19:27:48 +00:00
parent d38fb71d00
commit 5a1b33507b
6 changed files with 109 additions and 102 deletions

View File

@ -249,6 +249,9 @@ Release 2.4.0 - UNRELEASED
YARN-1505. Fixed Webapplication proxy server to not hardcode its bind
address. (Xuan Gong via vinodkv)
YARN-1145. Fixed a potential file-handle leak in the web interface for
displaying aggregated logs. (Rohith Sharma via vinodkv)
Release 2.3.0 - UNRELEASED
INCOMPATIBLE CHANGES

View File

@ -53,6 +53,7 @@
import org.apache.hadoop.fs.Options;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.SecureIOUtils;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.file.tfile.TFile;
@ -294,7 +295,7 @@ public void append(LogKey logKey, LogValue logValue) throws IOException {
out.close();
}
public void closeWriter() {
public void close() {
try {
this.writer.close();
} catch (IOException e) {
@ -569,9 +570,8 @@ public static void readAContainerLogsForALogType(
out.println("");
}
public void close() throws IOException {
this.scanner.close();
this.fsDataIStream.close();
public void close() {
IOUtils.cleanup(LOG, scanner, reader, fsDataIStream);
}
}

View File

@ -59,6 +59,8 @@ public class AggregatedLogsBlock extends HtmlBlock {
@Override
protected void render(Block html) {
AggregatedLogFormat.LogReader reader = null;
try {
ContainerId containerId = verifyAndGetContainerId(html);
NodeId nodeId = verifyAndGetNodeId(html);
String appOwner = verifyAndGetAppOwner(html);
@ -68,8 +70,8 @@ protected void render(Block html) {
return;
}
ApplicationId applicationId =
containerId.getApplicationAttemptId().getApplicationId();
ApplicationId applicationId = containerId.getApplicationAttemptId()
.getApplicationId();
String logEntity = $(ENTITY_STRING);
if (logEntity == null || logEntity.isEmpty()) {
logEntity = containerId.toString();
@ -83,24 +85,21 @@ protected void render(Block html) {
return;
}
Path remoteRootLogDir =
new Path(conf.get(YarnConfiguration.NM_REMOTE_APP_LOG_DIR,
Path remoteRootLogDir = new Path(conf.get(
YarnConfiguration.NM_REMOTE_APP_LOG_DIR,
YarnConfiguration.DEFAULT_NM_REMOTE_APP_LOG_DIR));
AggregatedLogFormat.LogReader reader = null;
try {
reader =
new AggregatedLogFormat.LogReader(conf,
LogAggregationUtils.getRemoteNodeLogFileForApp(
remoteRootLogDir, applicationId, appOwner, nodeId,
reader = new AggregatedLogFormat.LogReader(conf,
LogAggregationUtils.getRemoteNodeLogFileForApp(remoteRootLogDir,
applicationId, appOwner, nodeId,
LogAggregationUtils.getRemoteNodeLogDirSuffix(conf)));
} catch (FileNotFoundException e) {
// ACLs not available till the log file is opened.
html.h1()
._("Logs not available for "
+ logEntity
._("Logs not available for " + logEntity
+ ". Aggregation may not be complete, "
+ "Check back later or try the nodemanager at "
+ nodeId)._();
+ "Check back later or try the nodemanager at " + nodeId)._();
return;
} catch (IOException e) {
html.h1()._("Error getting logs for " + logEntity)._();
@ -127,8 +126,8 @@ protected void render(Block html) {
callerUGI = UserGroupInformation.createRemoteUser(remoteUser);
}
if (callerUGI != null
&& !aclsManager.checkAccess(callerUGI, ApplicationAccessType.VIEW_APP,
owner, applicationId)) {
&& !aclsManager.checkAccess(callerUGI,
ApplicationAccessType.VIEW_APP, owner, applicationId)) {
html.h1()
._("User [" + remoteUser
+ "] is not authorized to view the logs for " + logEntity)._();
@ -137,11 +136,11 @@ protected void render(Block html) {
String desiredLogType = $(CONTAINER_LOG_TYPE);
try {
AggregatedLogFormat.ContainerLogsReader logReader =
reader.getContainerLogsReader(containerId);
AggregatedLogFormat.ContainerLogsReader logReader = reader
.getContainerLogsReader(containerId);
if (logReader == null) {
html.h1()._(
"Logs not available for " + logEntity
html.h1()
._("Logs not available for " + logEntity
+ ". Could be caused by the rentention policy")._();
return;
}
@ -163,6 +162,11 @@ protected void render(Block html) {
LOG.error("Error getting logs for " + logEntity, e);
return;
}
} finally {
if (reader != null) {
reader.close();
}
}
}
private boolean readContainerLogs(Block html,

View File

@ -114,7 +114,7 @@ public void testReadAcontainerLogs1() throws Exception {
testContainerId, ugi.getShortUserName());
logWriter.append(logKey, logValue);
logWriter.closeWriter();
logWriter.close();
// make sure permission are correct on the file
FileStatus fsStatus = fs.getFileStatus(remoteAppLogFile);
@ -194,7 +194,7 @@ public void testContainerLogsFileAccess() throws IOException {
ugi.getShortUserName());
logWriter.append(logKey, logValue);
logWriter.closeWriter();
logWriter.close();
BufferedReader in =
new BufferedReader(new FileReader(new File(remoteAppLogFile

View File

@ -229,7 +229,7 @@ private void writeLog(Configuration configuration, String user)
writer.append(new AggregatedLogFormat.LogKey("container_0_0001_01_000001"),
new AggregatedLogFormat.LogValue(rootLogDirs, containerId,UserGroupInformation.getCurrentUser().getShortUserName()));
writer.closeWriter();
writer.close();
}
private void writeLogs(String dirName) throws Exception {

View File

@ -178,7 +178,7 @@ private void doAppLogAggregation() {
localAppLogDirs);
if (this.writer != null) {
this.writer.closeWriter();
this.writer.close();
LOG.info("Finished aggregate log-file for app " + this.applicationId);
}