diff --git hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java index b3d6d4a..303f119 100644 --- hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java +++ hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java @@ -343,23 +343,6 @@ public static Connector createDefaultChannelConnector() { */ protected void addDefaultApps(ContextHandlerCollection parent, final String appDir, Configuration conf) throws IOException { - // set up the context for "/logs/" if "hadoop.log.dir" property is defined. - String logDir = System.getProperty("hadoop.log.dir"); - if (logDir != null) { - Context logContext = new Context(parent, "/logs"); - logContext.setResourceBase(logDir); - logContext.addServlet(AdminAuthorizedServlet.class, "/*"); - if (conf.getBoolean( - CommonConfigurationKeys.HADOOP_JETTY_LOGS_SERVE_ALIASES, - CommonConfigurationKeys.DEFAULT_HADOOP_JETTY_LOGS_SERVE_ALIASES)) { - logContext.getInitParams().put( - "org.mortbay.jetty.servlet.Default.aliases", "true"); - } - logContext.setDisplayName("logs"); - setContextAttributes(logContext, conf); - addNoCacheFilter(webAppContext); - defaultContexts.put(logContext, true); - } // set up the context for "/static/*" Context staticContext = new Context(parent, "/static"); staticContext.setResourceBase(appDir + "/static"); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/utils/LocalLogsBlock.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/utils/LocalLogsBlock.java new file mode 100644 index 0000000..76b2d43 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/utils/LocalLogsBlock.java @@ -0,0 +1,68 @@ +package org.apache.hadoop.yarn.server.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.apache.hadoop.io.SecureIOUtils; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.PRE; +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; +import com.google.inject.Inject; + + +public class LocalLogsBlock extends HtmlBlock{ + + @Inject + LocalLogsBlock(ViewContext ctx) { + super(ctx); + } + + @Override + protected void render(Block html) { + String logDir = System.getProperty("hadoop.log.dir"); + String logName = System.getProperty("yarn.log.file"); + String user = System.getProperty("user.name"); + File logFile = new File(logDir, logName); + FileInputStream logByteStream = null; + + try { + logByteStream = + SecureIOUtils.openForRead(logFile, user, null); + } catch (IOException e) { + LOG.error( + "Exception reading log file " + logFile.getAbsolutePath(), e); + return; + } + + try { + InputStreamReader reader = new InputStreamReader(logByteStream); + int bufferSize = 65536; + char[] cbuf = new char[bufferSize]; + + int len = 0; + PRE pre = html.pre(); + + while ((len = reader.read(cbuf, 0, bufferSize)) > 0) { + pre._(new String(cbuf, 0, len)); + } + + pre._(); + reader.close(); + + } catch (IOException e) { + LOG.error( + "Exception reading log file " + logFile.getAbsolutePath(), e); + html.h1("Exception reading log file." + logFile.getName()); + } finally { + if (logByteStream != null) { + try { + logByteStream.close(); + } catch (IOException e) { + // Ignore + } + } + } + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/LocalLogsPage.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/LocalLogsPage.java new file mode 100644 index 0000000..a73690b --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/LocalLogsPage.java @@ -0,0 +1,17 @@ +package org.apache.hadoop.yarn.server.nodemanager.webapp; + +import org.apache.hadoop.yarn.server.utils.LocalLogsBlock; +import org.apache.hadoop.yarn.webapp.SubView; + +public class LocalLogsPage extends NMView { + + @Override + protected void preHead(Page.HTML<_> html) { + commonPreHead(html); + } + + @Override + protected Class content() { + return LocalLogsBlock.class; + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/MetricsOverviewTable.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/MetricsOverviewTable.java new file mode 100644 index 0000000..19e1606 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/MetricsOverviewTable.java @@ -0,0 +1,154 @@ +package org.apache.hadoop.yarn.server.nodemanager.webapp; + +import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.yarn.server.nodemanager.Context; +import org.apache.hadoop.yarn.server.nodemanager.ResourceView; +import org.apache.hadoop.yarn.server.nodemanager.webapp.dao.NodeInfo; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV; +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; + +import com.google.inject.Inject; + +public class MetricsOverviewTable extends HtmlBlock { + + private static final long BYTES_IN_MB = 1024 * 1024; + + private final Context nmContext; + private final ResourceView resourceView; + + @Inject + MetricsOverviewTable(Context context, ResourceView resourceView) { + this.nmContext = context; + this.resourceView = resourceView; + } + + @Override + protected void render(Block html) { + // Yes this is a hack, but there is no other way to insert + // CSS in the correct spot + html.style(".metrics {margin-bottom:5px}"); + + NodeInfo nodeInfo = + new NodeInfo(this.nmContext, this.resourceView); + + DIV div = html.div().$class("metrics"); + + div.h3("Cluster Metrics") + . + table("#metricsoverview") + . + thead() + .$class("ui-widget-header") + . + tr() + . + th() + .$class("ui-state-default") + ._("Node ID") + ._() + . + th() + .$class("ui-state-default") + ._("Node Host Name") + ._() + . + th() + .$class("ui-state-default") + ._("Total Virtual Memory Used") + ._() + . + th() + .$class("ui-state-default") + ._("Virtual Memory Checked") + ._() + . + th() + .$class("ui-state-default") + ._("Total Physical Memory Used") + ._() + . + th() + .$class("ui-state-default") + ._("Physical Memory Checked") + ._() + . + th() + .$class("ui-state-default") + ._("Node Healthy") + ._() + . + th() + .$class("ui-state-default") + ._("Last Node UpdateTime") + ._() + . + th() + .$class("ui-state-default") + ._("Health Report") + ._() + . + th() + .$class("ui-state-default") + ._("NodeManager Version") + ._() + . + th() + .$class("ui-state-default") + ._("NodeManager Build Version") + ._() + . + th() + .$class("ui-state-default") + ._("NodeManager Version BuiltOn") + ._() + . + th() + .$class("ui-state-default") + ._("Hadoop Version") + ._() + . + th() + .$class("ui-state-default") + ._("Hadoop Build Version") + ._() + . + th() + .$class("ui-state-default") + ._("Hadoop Version BuiltOn") + ._() + . + _() + . + _() + . + tbody() + .$class("ui-widget-content") + . + tr() + . + td(String.valueOf(nodeInfo.getNodeId())) + . + td(String.valueOf(nodeInfo.getNodeHostName())) + . + td(StringUtils.byteDesc(nodeInfo.getTotalVmemAllocated() * BYTES_IN_MB)) + . + td(String.valueOf(nodeInfo.isVmemCheckEnabled())) + . + td(StringUtils.byteDesc(nodeInfo.getTotalPmemAllocated() * BYTES_IN_MB)) + . + td(String.valueOf(nodeInfo.isPmemCheckEnabled())). + td(String.valueOf(nodeInfo.getHealthStatus())). + td(String.valueOf(nodeInfo.getLastNodeUpdateTime())). + td(String.valueOf(nodeInfo.getHealthReport())). + td(String.valueOf(nodeInfo.getNMVersion())). + td(String.valueOf(nodeInfo.getNMBuildVersion())). + td(String.valueOf(nodeInfo.getNMVersionBuiltOn())). + td(String.valueOf(nodeInfo.getHadoopVersion())). + td(String.valueOf(nodeInfo.getHadoopBuildVersion())). + td(String.valueOf(nodeInfo.getHadoopVersionBuiltOn())). + _(). + _()._(); + div._(); + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMController.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMController.java index 86e2505..5203c90 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMController.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMController.java @@ -103,4 +103,14 @@ public void logs() { } render(ContainerLogsPage.class); } + + public void localLogs() { + setTitle("NM Local Logs"); + render(LocalLogsPage.class); + } + + public void metricsOverviewTable() { + setTitle("NM Metrics Overview"); + render(MetricsOverviewTable.class); + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NavBlock.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NavBlock.java index 73511c4..53bcd62 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NavBlock.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NavBlock.java @@ -56,9 +56,9 @@ protected void render(Block html) { .h3("Tools") .ul() .li().a("/conf", "Configuration")._() - .li().a("/logs", "Local logs")._() + .li().a(url("/logs"), "Local logs")._() .li().a("/stacks", "Server stacks")._() - .li().a("/metrics", "Server metrics")._()._()._(); + .li().a(url("/metrics"), "Server metrics")._()._()._(); } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/WebServer.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/WebServer.java index 25dfaf6..62f1123 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/WebServer.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/WebServer.java @@ -116,6 +116,8 @@ public void setup() { route( pajoin("/containerlogs", CONTAINER_ID, APP_OWNER, CONTAINER_LOG_TYPE), NMController.class, "logs"); + route("/logs", NMController.class, "localLogs"); + route("/metrics", NMController.class, "metricsOverviewTable"); } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/LocalLogsPage.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/LocalLogsPage.java new file mode 100644 index 0000000..97fa07e --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/LocalLogsPage.java @@ -0,0 +1,17 @@ +package org.apache.hadoop.yarn.server.resourcemanager.webapp; + +import org.apache.hadoop.yarn.server.utils.LocalLogsBlock; +import org.apache.hadoop.yarn.webapp.SubView; + +public class LocalLogsPage extends RmView { + + @Override + protected void preHead(Page.HTML<_> html) { + commonPreHead(html); + } + + @Override + protected Class content() { + return LocalLogsBlock.class; + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NavBlock.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NavBlock.java index f31e06b..11c70c7 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NavBlock.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NavBlock.java @@ -48,8 +48,8 @@ h3("Tools"). ul(). li().a("/conf", "Configuration")._(). - li().a("/logs", "Local logs")._(). + li().a(url("logs"), "Local logs")._(). li().a("/stacks", "Server stacks")._(). - li().a("/metrics", "Server metrics")._()._()._(); + li().a(url("/metrics"), "Server metrics")._()._()._(); } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java index 90b0824..e6bf2e8 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java @@ -56,5 +56,7 @@ public void setup() { route(pajoin("/app", APPLICATION_ID), RmController.class, "app"); route("/scheduler", RmController.class, "scheduler"); route(pajoin("/queue", QUEUE_NAME), RmController.class, "queue"); + route("/logs", RmController.class, "localLogs"); + route("/metrics", RmController.class, "metricsOverviewTable"); } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java index cec16f3..05f869f 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java @@ -28,7 +28,6 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler; import org.apache.hadoop.yarn.util.StringHelper; import org.apache.hadoop.yarn.webapp.Controller; -import org.apache.hadoop.yarn.webapp.WebAppException; import org.apache.hadoop.yarn.webapp.YarnWebParams; import com.google.inject.Inject; @@ -94,4 +93,14 @@ public void queue() { public void submit() { setTitle("Application Submission Not Allowed"); } + + public void localLogs() { + setTitle("RM Local Logs"); + render(LocalLogsPage.class); + } + + public void metricsOverviewTable() { + setTitle("RM Metrics Overview"); + render(MetricsOverviewTable.class); + } }