YARN-3654. ContainerLogsPage web UI should not have meta-refresh. Contributed by Xuan Gong
(cherry picked from commit 6329bd00fa
)
This commit is contained in:
parent
521378ffa3
commit
7c3895c8f6
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,29 +20,16 @@ package org.apache.hadoop.yarn.server.nodemanager.webapp;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
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 class NMController extends Controller implements YarnWebParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ import static org.apache.hadoop.yarn.util.StringHelper.pajoin;
|
||||||
|
|
||||||
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.WebApps;
|
||||||
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 class WebServer extends AbstractService {
|
||||||
route("/errors-and-warnings", NMController.class, "errorsAndWarnings");
|
route("/errors-and-warnings", NMController.class, "errorsAndWarnings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<? extends GuiceContainer> getWebAppFilterClass() {
|
||||||
|
return NMWebAppFilter.class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue