YARN-3511. Add errors and warnings page to ATS. Contributed by Varun Vasudev

This commit is contained in:
Xuan 2015-04-24 09:41:59 -07:00
parent 91b97c21c9
commit eee9facbba
7 changed files with 114 additions and 5 deletions
hadoop-yarn-project
CHANGES.txt
hadoop-yarn/hadoop-yarn-server
hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp
hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp
hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp

View File

@ -166,6 +166,8 @@ Release 2.8.0 - UNRELEASED
YARN-3503. Expose disk utilization percentage and bad local and log dir YARN-3503. Expose disk utilization percentage and bad local and log dir
counts in NM metrics. (Varun Vasudev via jianhe) counts in NM metrics. (Varun Vasudev via jianhe)
YARN-3511. Add errors and warnings page to ATS. (Varun Vasudev via xgong)
OPTIMIZATIONS OPTIMIZATIONS
YARN-3339. TestDockerContainerExecutor should pull a single image and not YARN-3339. TestDockerContainerExecutor should pull a single image and not

View File

@ -52,4 +52,8 @@ public class AHSController extends Controller {
public void logs() { public void logs() {
render(AHSLogsPage.class); render(AHSLogsPage.class);
} }
public void errorsAndWarnings() {
render(AHSErrorsAndWarningsPage.class);
}
} }

View File

@ -0,0 +1,57 @@
/**
* 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.applicationhistoryservice.webapp;
import org.apache.hadoop.yarn.server.webapp.ErrorsAndWarningsBlock;
import org.apache.hadoop.yarn.webapp.SubView;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
/**
* Class to display the Errors and Warnings page for the AHS.
*/
public class AHSErrorsAndWarningsPage extends AHSView {
@Override
protected Class<? extends SubView> content() {
return ErrorsAndWarningsBlock.class;
}
@Override
protected void preHead(Page.HTML<_> html) {
commonPreHead(html);
String title = "Errors and Warnings in the Application History Server";
setTitle(title);
String tableId = "messages";
set(DATATABLES_ID, tableId);
set(initID(DATATABLES, tableId), tablesInit());
setTableStyles(html, tableId, ".message {width:50em}",
".count {width:8em}", ".lasttime {width:16em}");
}
private String tablesInit() {
StringBuilder b = tableInit().append(", aoColumnDefs: [");
b.append("{'sType': 'string', 'aTargets': [ 0 ]}");
b.append(", {'sType': 'string', 'bSearchable': true, 'aTargets': [ 1 ]}");
b.append(", {'sType': 'numeric', 'bSearchable': false, 'aTargets': [ 2 ]}");
b.append(", {'sType': 'date', 'aTargets': [ 3 ] }]");
b.append(", aaSorting: [[3, 'desc']]}");
return b.toString();
}
}

View File

@ -64,5 +64,6 @@ public class AHSWebApp extends WebApp implements YarnWebParams {
route( route(
pajoin("/logs", NM_NODENAME, CONTAINER_ID, ENTITY_STRING, APP_OWNER, pajoin("/logs", NM_NODENAME, CONTAINER_ID, ENTITY_STRING, APP_OWNER,
CONTAINER_LOG_TYPE), AHSController.class, "logs"); CONTAINER_LOG_TYPE), AHSController.class, "logs");
route("/errors-and-warnings", AHSController.class, "errorsAndWarnings");
} }
} }

View File

@ -18,14 +18,28 @@
package org.apache.hadoop.yarn.server.applicationhistoryservice.webapp; package org.apache.hadoop.yarn.server.applicationhistoryservice.webapp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.hadoop.yarn.api.records.YarnApplicationState; import org.apache.hadoop.yarn.api.records.YarnApplicationState;
import org.apache.hadoop.yarn.util.Log4jWarningErrorMetricsAppender;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
import org.apache.hadoop.yarn.webapp.view.HtmlBlock; import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
public class NavBlock extends HtmlBlock { public class NavBlock extends HtmlBlock {
@Override @Override
public void render(Block html) { public void render(Block html) {
html. boolean addErrorsAndWarningsLink = false;
Log log = LogFactory.getLog(NavBlock.class);
if (log instanceof Log4JLogger) {
Log4jWarningErrorMetricsAppender appender =
Log4jWarningErrorMetricsAppender.findAppender();
if (appender != null) {
addErrorsAndWarningsLink = true;
}
}
Hamlet.DIV<Hamlet> nav = html.
div("#nav"). div("#nav").
h3("Application History"). h3("Application History").
ul(). ul().
@ -45,7 +59,17 @@ public class NavBlock extends HtmlBlock {
_(). _().
_(). _().
_(). _().
_(). _();
_();
Hamlet.UL<Hamlet.DIV<Hamlet>> tools = nav.h3("Tools").ul();
tools.li().a("/conf", "Configuration")._()
.li().a("/logs", "Local logs")._()
.li().a("/stacks", "Server stacks")._()
.li().a("/jmx?qry=Hadoop:*", "Server metrics")._();
if (addErrorsAndWarningsLink) {
tools.li().a(url("errors-and-warnings"), "Errors/Warnings")._();
}
tools._()._();
} }
} }

View File

@ -22,7 +22,10 @@ import com.google.inject.Inject;
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.commons.logging.impl.Log4JLogger; import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.Time; import org.apache.hadoop.util.Time;
import org.apache.hadoop.yarn.security.AdminACLsManager;
import org.apache.hadoop.yarn.util.Log4jWarningErrorMetricsAppender; import org.apache.hadoop.yarn.util.Log4jWarningErrorMetricsAppender;
import org.apache.hadoop.yarn.util.Times; import org.apache.hadoop.yarn.util.Times;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
@ -36,9 +39,10 @@ import java.util.Map;
public class ErrorsAndWarningsBlock extends HtmlBlock { public class ErrorsAndWarningsBlock extends HtmlBlock {
long cutoffPeriodSeconds; long cutoffPeriodSeconds;
final private AdminACLsManager adminAclsManager;
@Inject @Inject
ErrorsAndWarningsBlock(ViewContext ctx) { ErrorsAndWarningsBlock(ViewContext ctx, Configuration conf) {
super(ctx); super(ctx);
// default is to show all errors and warnings // default is to show all errors and warnings
cutoffPeriodSeconds = Time.now() / 1000; cutoffPeriodSeconds = Time.now() / 1000;
@ -51,12 +55,29 @@ public class ErrorsAndWarningsBlock extends HtmlBlock {
} catch (NumberFormatException ne) { } catch (NumberFormatException ne) {
cutoffPeriodSeconds = Time.now() / 1000; cutoffPeriodSeconds = Time.now() / 1000;
} }
adminAclsManager = new AdminACLsManager(conf);
} }
@Override @Override
protected void render(Block html) { protected void render(Block html) {
Log log = LogFactory.getLog(ErrorsAndWarningsBlock.class); Log log = LogFactory.getLog(ErrorsAndWarningsBlock.class);
boolean isAdmin = false;
UserGroupInformation callerUGI = this.getCallerUGI();
if (adminAclsManager.areACLsEnabled()) {
if (callerUGI != null && adminAclsManager.isAdmin(callerUGI)) {
isAdmin = true;
}
} else {
isAdmin = true;
}
if (!isAdmin) {
html.div().p()._("This page is for admins only.")._()._();
return;
}
if (log instanceof Log4JLogger) { if (log instanceof Log4JLogger) {
html._(ErrorMetrics.class); html._(ErrorMetrics.class);
html._(WarningMetrics.class); html._(WarningMetrics.class);

View File

@ -33,7 +33,7 @@ public class NavBlock extends HtmlBlock {
@Override public void render(Block html) { @Override public void render(Block html) {
boolean addErrorsAndWarningsLink = false; boolean addErrorsAndWarningsLink = false;
Log log = LogFactory.getLog(RMErrorsAndWarningsPage.class); Log log = LogFactory.getLog(NavBlock.class);
if (log instanceof Log4JLogger) { if (log instanceof Log4JLogger) {
Log4jWarningErrorMetricsAppender appender = Log4jWarningErrorMetricsAppender appender =
Log4jWarningErrorMetricsAppender.findAppender(); Log4jWarningErrorMetricsAppender.findAppender();