YARN-3654. ContainerLogsPage web UI should not have meta-refresh. Contributed by Xuan Gong

(cherry picked from commit 6329bd00fa)
This commit is contained in:
Jian He 2015-05-20 17:20:21 -07:00
parent 521378ffa3
commit 7c3895c8f6
5 changed files with 128 additions and 43 deletions

View File

@ -381,6 +381,9 @@ Release 2.8.0 - UNRELEASED
YARN-2821. Fixed a problem that DistributedShell AM may hang if restarted. YARN-2821. Fixed a problem that DistributedShell AM may hang if restarted.
(Varun Vasudev via jianhe) (Varun Vasudev via jianhe)
YARN-3654. ContainerLogsPage web UI should not have meta-refresh. (Xuan Gong
via jianhe)
Release 2.7.1 - UNRELEASED Release 2.7.1 - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -59,9 +59,6 @@ public class ContainerLogsPage extends NMView {
if (redirectUrl.equals("false")) { if (redirectUrl.equals("false")) {
set(TITLE, join("Failed redirect for ", $(CONTAINER_ID))); set(TITLE, join("Failed redirect for ", $(CONTAINER_ID)));
//Error getting redirect url. Fall through. //Error getting redirect url. Fall through.
} else {
set(TITLE, join("Redirecting to log server for ", $(CONTAINER_ID)));
html.meta_http("refresh", "1; url=" + redirectUrl);
} }
} }

View File

@ -20,13 +20,6 @@
import static org.apache.hadoop.yarn.util.StringHelper.join; import static org.apache.hadoop.yarn.util.StringHelper.join;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.nodemanager.Context;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
import org.apache.hadoop.yarn.util.ConverterUtils;
import org.apache.hadoop.yarn.webapp.Controller; import org.apache.hadoop.yarn.webapp.Controller;
import org.apache.hadoop.yarn.webapp.YarnWebParams; import org.apache.hadoop.yarn.webapp.YarnWebParams;
@ -34,15 +27,9 @@
public class NMController extends Controller implements YarnWebParams { public class NMController extends Controller implements YarnWebParams {
private Context nmContext;
private Configuration nmConf;
@Inject @Inject
public NMController(Configuration nmConf, RequestContext requestContext, public NMController(RequestContext requestContext) {
Context nmContext) {
super(requestContext); super(requestContext);
this.nmContext = nmContext;
this.nmConf = nmConf;
} }
@Override @Override
@ -80,31 +67,6 @@ public void errorsAndWarnings() {
} }
public void logs() { public void logs() {
String containerIdStr = $(CONTAINER_ID);
ContainerId containerId = null;
try {
containerId = ConverterUtils.toContainerId(containerIdStr);
} catch (IllegalArgumentException e) {
render(ContainerLogsPage.class);
return;
}
ApplicationId appId =
containerId.getApplicationAttemptId().getApplicationId();
Application app = nmContext.getApplications().get(appId);
if (app == null
&& nmConf.getBoolean(YarnConfiguration.LOG_AGGREGATION_ENABLED,
YarnConfiguration.DEFAULT_LOG_AGGREGATION_ENABLED)) {
String logServerUrl = nmConf.get(YarnConfiguration.YARN_LOG_SERVER_URL);
String redirectUrl = null;
if (logServerUrl == null || logServerUrl.isEmpty()) {
redirectUrl = "false";
} else {
redirectUrl =
url(logServerUrl, nmContext.getNodeId().toString(), containerIdStr,
containerIdStr, $(APP_OWNER));
}
set(ContainerLogsPage.REDIRECT_URL, redirectUrl);
}
render(ContainerLogsPage.class); render(ContainerLogsPage.class);
} }
} }

View File

@ -0,0 +1,118 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.server.nodemanager.webapp;
import java.io.IOException;
import java.io.PrintWriter;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.http.HtmlQuoting;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.nodemanager.Context;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
import org.apache.hadoop.yarn.webapp.Controller.RequestContext;
import com.google.inject.Injector;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
@Singleton
public class NMWebAppFilter extends GuiceContainer{
private Injector injector;
private Context nmContext;
private static final long serialVersionUID = 1L;
@Inject
public NMWebAppFilter(Injector injector, Context nmContext) {
super(injector);
this.injector = injector;
this.nmContext = nmContext;
}
@Override
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) throws IOException,
ServletException {
String uri = HtmlQuoting.quoteHtmlChars(request.getRequestURI());
String redirectPath = containerLogPageRedirectPath(uri);
if (redirectPath != null) {
String redirectMsg =
"Redirecting to log server" + " : " + redirectPath;
PrintWriter out = response.getWriter();
out.println(redirectMsg);
response.setHeader("Location", redirectPath);
response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
return;
}
super.doFilter(request, response, chain);
}
private String containerLogPageRedirectPath(String uri) {
String redirectPath = null;
if (!uri.contains("/ws/v1/node") && uri.contains("/containerlogs")) {
String[] parts = uri.split("/");
String containerIdStr = parts[3];
String appOwner = parts[4];
if (containerIdStr != null && !containerIdStr.isEmpty()) {
ContainerId containerId = null;
try {
containerId = ContainerId.fromString(containerIdStr);
} catch (IllegalArgumentException ex) {
return redirectPath;
}
ApplicationId appId =
containerId.getApplicationAttemptId().getApplicationId();
Application app = nmContext.getApplications().get(appId);
Configuration nmConf = nmContext.getLocalDirsHandler().getConfig();
if (app == null
&& nmConf.getBoolean(YarnConfiguration.LOG_AGGREGATION_ENABLED,
YarnConfiguration.DEFAULT_LOG_AGGREGATION_ENABLED)) {
String logServerUrl =
nmConf.get(YarnConfiguration.YARN_LOG_SERVER_URL);
if (logServerUrl != null && !logServerUrl.isEmpty()) {
StringBuilder sb = new StringBuilder();
sb.append(logServerUrl);
sb.append("/");
sb.append(nmContext.getNodeId().toString());
sb.append("/");
sb.append(containerIdStr);
sb.append("/");
sb.append(containerIdStr);
sb.append("/");
sb.append(appOwner);
redirectPath = sb.toString();
} else {
injector.getInstance(RequestContext.class).set(
ContainerLogsPage.REDIRECT_URL, "false");
}
}
}
}
return redirectPath;
}
}

View File

@ -22,7 +22,6 @@
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.http.HttpConfig;
import org.apache.hadoop.service.AbstractService; import org.apache.hadoop.service.AbstractService;
import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
@ -36,6 +35,8 @@
import org.apache.hadoop.yarn.webapp.YarnWebParams; import org.apache.hadoop.yarn.webapp.YarnWebParams;
import org.apache.hadoop.yarn.webapp.util.WebAppUtils; import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
public class WebServer extends AbstractService { public class WebServer extends AbstractService {
private static final Log LOG = LogFactory.getLog(WebServer.class); private static final Log LOG = LogFactory.getLog(WebServer.class);
@ -129,5 +130,9 @@ public void setup() {
route("/errors-and-warnings", NMController.class, "errorsAndWarnings"); route("/errors-and-warnings", NMController.class, "errorsAndWarnings");
} }
@Override
protected Class<? extends GuiceContainer> getWebAppFilterClass() {
return NMWebAppFilter.class;
}
} }
} }