Skip to content

Commit

Permalink
YARN-3654. ContainerLogsPage web UI should not have meta-refresh. Con…
Browse files Browse the repository at this point in the history
…tributed by Xuan Gong
  • Loading branch information
jian-he committed May 21, 2015
1 parent 8966d42 commit 6329bd0
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 43 deletions.
3 changes: 3 additions & 0 deletions hadoop-yarn-project/CHANGES.txt
Expand Up @@ -426,6 +426,9 @@ Release 2.8.0 - UNRELEASED
YARN-2821. Fixed a problem that DistributedShell AM may hang if restarted.
(Varun Vasudev via jianhe)

YARN-3654. ContainerLogsPage web UI should not have meta-refresh. (Xuan Gong
via jianhe)

Release 2.7.1 - UNRELEASED

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

Expand Down
Expand Up @@ -20,29 +20,16 @@

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.YarnWebParams;

import com.google.inject.Inject;

public class NMController extends Controller implements YarnWebParams {

private Context nmContext;
private Configuration nmConf;

@Inject
public NMController(Configuration nmConf, RequestContext requestContext,
Context nmContext) {
public NMController(RequestContext requestContext) {
super(requestContext);
this.nmContext = nmContext;
this.nmConf = nmConf;
}

@Override
Expand Down Expand Up @@ -80,31 +67,6 @@ public void errorsAndWarnings() {
}

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);
}
}
@@ -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;
}
}
Expand Up @@ -22,7 +22,6 @@

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.http.HttpConfig;
import org.apache.hadoop.service.AbstractService;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
Expand All @@ -36,6 +35,8 @@
import org.apache.hadoop.yarn.webapp.YarnWebParams;
import org.apache.hadoop.yarn.webapp.util.WebAppUtils;

import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;

public class WebServer extends AbstractService {

private static final Log LOG = LogFactory.getLog(WebServer.class);
Expand Down Expand Up @@ -129,5 +130,9 @@ public void setup() {
route("/errors-and-warnings", NMController.class, "errorsAndWarnings");
}

@Override
protected Class<? extends GuiceContainer> getWebAppFilterClass() {
return NMWebAppFilter.class;
}
}
}

0 comments on commit 6329bd0

Please sign in to comment.