|
@@ -30,7 +30,10 @@ import java.util.Map;
|
|
|
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
+import org.apache.hadoop.fs.FileContext;
|
|
|
+import org.apache.hadoop.fs.FileStatus;
|
|
|
import org.apache.hadoop.fs.Path;
|
|
|
+import org.apache.hadoop.fs.RemoteIterator;
|
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
|
import org.apache.hadoop.yarn.api.records.ApplicationAccessType;
|
|
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
|
@@ -59,113 +62,127 @@ 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);
|
|
|
- LogLimits logLimits = verifyAndGetLogLimits(html);
|
|
|
- if (containerId == null || nodeId == null || appOwner == null
|
|
|
- || appOwner.isEmpty() || logLimits == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- ApplicationId applicationId = containerId.getApplicationAttemptId()
|
|
|
- .getApplicationId();
|
|
|
- String logEntity = $(ENTITY_STRING);
|
|
|
- if (logEntity == null || logEntity.isEmpty()) {
|
|
|
- logEntity = containerId.toString();
|
|
|
- }
|
|
|
+ ContainerId containerId = verifyAndGetContainerId(html);
|
|
|
+ NodeId nodeId = verifyAndGetNodeId(html);
|
|
|
+ String appOwner = verifyAndGetAppOwner(html);
|
|
|
+ LogLimits logLimits = verifyAndGetLogLimits(html);
|
|
|
+ if (containerId == null || nodeId == null || appOwner == null
|
|
|
+ || appOwner.isEmpty() || logLimits == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- if (!conf.getBoolean(YarnConfiguration.LOG_AGGREGATION_ENABLED,
|
|
|
- YarnConfiguration.DEFAULT_LOG_AGGREGATION_ENABLED)) {
|
|
|
- html.h1()
|
|
|
- ._("Aggregation is not enabled. Try the nodemanager at " + nodeId)
|
|
|
- ._();
|
|
|
- return;
|
|
|
- }
|
|
|
+ ApplicationId applicationId = containerId.getApplicationAttemptId()
|
|
|
+ .getApplicationId();
|
|
|
+ String logEntity = $(ENTITY_STRING);
|
|
|
+ if (logEntity == null || logEntity.isEmpty()) {
|
|
|
+ logEntity = containerId.toString();
|
|
|
+ }
|
|
|
|
|
|
- Path remoteRootLogDir = new Path(conf.get(
|
|
|
- YarnConfiguration.NM_REMOTE_APP_LOG_DIR,
|
|
|
- YarnConfiguration.DEFAULT_NM_REMOTE_APP_LOG_DIR));
|
|
|
+ if (!conf.getBoolean(YarnConfiguration.LOG_AGGREGATION_ENABLED,
|
|
|
+ YarnConfiguration.DEFAULT_LOG_AGGREGATION_ENABLED)) {
|
|
|
+ html.h1()
|
|
|
+ ._("Aggregation is not enabled. Try the nodemanager at " + nodeId)
|
|
|
+ ._();
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- try {
|
|
|
- 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
|
|
|
- + ". Aggregation may not be complete, "
|
|
|
- + "Check back later or try the nodemanager at " + nodeId)._();
|
|
|
- return;
|
|
|
- } catch (IOException e) {
|
|
|
- html.h1()._("Error getting logs for " + logEntity)._();
|
|
|
- LOG.error("Error getting logs for " + logEntity, e);
|
|
|
- return;
|
|
|
- }
|
|
|
+ Path remoteRootLogDir = new Path(conf.get(
|
|
|
+ YarnConfiguration.NM_REMOTE_APP_LOG_DIR,
|
|
|
+ YarnConfiguration.DEFAULT_NM_REMOTE_APP_LOG_DIR));
|
|
|
+ Path remoteAppDir = LogAggregationUtils.getRemoteAppLogDir(
|
|
|
+ remoteRootLogDir, applicationId, appOwner,
|
|
|
+ LogAggregationUtils.getRemoteNodeLogDirSuffix(conf));
|
|
|
+ RemoteIterator<FileStatus> nodeFiles;
|
|
|
+ try {
|
|
|
+ Path qualifiedLogDir =
|
|
|
+ FileContext.getFileContext(conf).makeQualified(
|
|
|
+ remoteAppDir);
|
|
|
+ nodeFiles =
|
|
|
+ FileContext.getFileContext(qualifiedLogDir.toUri(), conf)
|
|
|
+ .listStatus(remoteAppDir);
|
|
|
+ } catch (FileNotFoundException fnf) {
|
|
|
+ html.h1()
|
|
|
+ ._("Logs not available for " + logEntity
|
|
|
+ + ". Aggregation may not be complete, "
|
|
|
+ + "Check back later or try the nodemanager at " + nodeId)._();
|
|
|
+ return;
|
|
|
+ } catch (Exception ex) {
|
|
|
+ html.h1()
|
|
|
+ ._("Error getting logs at " + nodeId)._();
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- String owner = null;
|
|
|
- Map<ApplicationAccessType, String> appAcls = null;
|
|
|
- try {
|
|
|
- owner = reader.getApplicationOwner();
|
|
|
- appAcls = reader.getApplicationAcls();
|
|
|
- } catch (IOException e) {
|
|
|
- html.h1()._("Error getting logs for " + logEntity)._();
|
|
|
- LOG.error("Error getting logs for " + logEntity, e);
|
|
|
- return;
|
|
|
- }
|
|
|
- ApplicationACLsManager aclsManager = new ApplicationACLsManager(conf);
|
|
|
- aclsManager.addApplication(applicationId, appAcls);
|
|
|
+ boolean foundLog = false;
|
|
|
+ String desiredLogType = $(CONTAINER_LOG_TYPE);
|
|
|
+ try {
|
|
|
+ while (nodeFiles.hasNext()) {
|
|
|
+ AggregatedLogFormat.LogReader reader = null;
|
|
|
+ try {
|
|
|
+ FileStatus thisNodeFile = nodeFiles.next();
|
|
|
+ if (!thisNodeFile.getPath().getName()
|
|
|
+ .contains(LogAggregationUtils.getNodeString(nodeId))
|
|
|
+ || thisNodeFile.getPath().getName()
|
|
|
+ .endsWith(LogAggregationUtils.TMP_FILE_SUFFIX)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ reader =
|
|
|
+ new AggregatedLogFormat.LogReader(conf, thisNodeFile.getPath());
|
|
|
+
|
|
|
+ String owner = null;
|
|
|
+ Map<ApplicationAccessType, String> appAcls = null;
|
|
|
+ try {
|
|
|
+ owner = reader.getApplicationOwner();
|
|
|
+ appAcls = reader.getApplicationAcls();
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("Error getting logs for " + logEntity, e);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ ApplicationACLsManager aclsManager = new ApplicationACLsManager(conf);
|
|
|
+ aclsManager.addApplication(applicationId, appAcls);
|
|
|
|
|
|
- String remoteUser = request().getRemoteUser();
|
|
|
- UserGroupInformation callerUGI = null;
|
|
|
- if (remoteUser != null) {
|
|
|
- callerUGI = UserGroupInformation.createRemoteUser(remoteUser);
|
|
|
- }
|
|
|
- if (callerUGI != null
|
|
|
- && !aclsManager.checkAccess(callerUGI,
|
|
|
+ String remoteUser = request().getRemoteUser();
|
|
|
+ UserGroupInformation callerUGI = null;
|
|
|
+ if (remoteUser != null) {
|
|
|
+ callerUGI = UserGroupInformation.createRemoteUser(remoteUser);
|
|
|
+ }
|
|
|
+ if (callerUGI != null && !aclsManager.checkAccess(callerUGI,
|
|
|
ApplicationAccessType.VIEW_APP, owner, applicationId)) {
|
|
|
- html.h1()
|
|
|
- ._("User [" + remoteUser
|
|
|
- + "] is not authorized to view the logs for " + logEntity)._();
|
|
|
- return;
|
|
|
- }
|
|
|
+ html.h1()
|
|
|
+ ._("User [" + remoteUser
|
|
|
+ + "] is not authorized to view the logs for " + logEntity
|
|
|
+ + " in log file [" + thisNodeFile.getPath().getName() + "]")._();
|
|
|
+ LOG.error("User [" + remoteUser
|
|
|
+ + "] is not authorized to view the logs for " + logEntity);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- String desiredLogType = $(CONTAINER_LOG_TYPE);
|
|
|
- try {
|
|
|
- AggregatedLogFormat.ContainerLogsReader logReader = reader
|
|
|
+ AggregatedLogFormat.ContainerLogsReader logReader = reader
|
|
|
.getContainerLogsReader(containerId);
|
|
|
- if (logReader == null) {
|
|
|
- html.h1()
|
|
|
- ._("Logs not available for " + logEntity
|
|
|
- + ". Could be caused by the rentention policy")._();
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- boolean foundLog = readContainerLogs(html, logReader, logLimits,
|
|
|
- desiredLogType);
|
|
|
-
|
|
|
- if (!foundLog) {
|
|
|
- if (desiredLogType.isEmpty()) {
|
|
|
- html.h1("No logs available for container " + containerId.toString());
|
|
|
- } else {
|
|
|
- html.h1("Unable to locate '" + desiredLogType
|
|
|
- + "' log for container " + containerId.toString());
|
|
|
+ if (logReader == null) {
|
|
|
+ continue;
|
|
|
}
|
|
|
- return;
|
|
|
+
|
|
|
+ foundLog = readContainerLogs(html, logReader, logLimits,
|
|
|
+ desiredLogType);
|
|
|
+ } catch (IOException ex) {
|
|
|
+ LOG.error("Error getting logs for " + logEntity, ex);
|
|
|
+ continue;
|
|
|
+ } finally {
|
|
|
+ if (reader != null)
|
|
|
+ reader.close();
|
|
|
}
|
|
|
- } catch (IOException e) {
|
|
|
- html.h1()._("Error getting logs for " + logEntity)._();
|
|
|
- LOG.error("Error getting logs for " + logEntity, e);
|
|
|
- return;
|
|
|
}
|
|
|
- } finally {
|
|
|
- if (reader != null) {
|
|
|
- reader.close();
|
|
|
+ if (!foundLog) {
|
|
|
+ if (desiredLogType.isEmpty()) {
|
|
|
+ html.h1("No logs available for container " + containerId.toString());
|
|
|
+ } else {
|
|
|
+ html.h1("Unable to locate '" + desiredLogType
|
|
|
+ + "' log for container " + containerId.toString());
|
|
|
+ }
|
|
|
}
|
|
|
+ } catch (IOException e) {
|
|
|
+ html.h1()._("Error getting logs for " + logEntity)._();
|
|
|
+ LOG.error("Error getting logs for " + logEntity, e);
|
|
|
}
|
|
|
}
|
|
|
|