Skip to content
Snippets Groups Projects
Commit ddb97f0f authored by Patrick Wendell's avatar Patrick Wendell
Browse files

Add `Environment` tab to SparkUI.

This adds a tab which displays system property and classpath information. This
can be useful in debugging various types of issues such as:

1. Extra/incorrect Hadoop jars being included in the classpath
2. Spark launching with a different JRE version than intended
3. Spark system properties not being set to intended values
4. User added jars that conflict with Spark jars
parent 37abe842
No related branches found
No related tags found
No related merge requests found
package spark.ui
private[spark] object Page extends Enumeration { val Storage, Jobs = Value }
\ No newline at end of file
private[spark] object Page extends Enumeration { val Storage, Jobs, Environment = Value }
\ No newline at end of file
......@@ -5,15 +5,13 @@ import javax.servlet.http.HttpServletRequest
import org.eclipse.jetty.server.{Handler, Server}
import spark.{Logging, SparkContext, Utils}
import spark.ui.env.EnvironmentUI
import spark.ui.storage.BlockManagerUI
import spark.ui.jobs.JobProgressUI
import spark.ui.UIUtils._
import spark.ui.JettyUtils._
/** Top level user interface for Spark */
private[spark] class SparkUI(sc: SparkContext) extends Logging {
// TODO(pwendell): It would be nice to add a view that prints out environment information
val host = Utils.localHostName()
val port = Option(System.getProperty("spark.ui.port")).getOrElse(SparkUI.DEFAULT_PORT).toInt
var boundPort: Option[Int] = None
......@@ -25,7 +23,8 @@ private[spark] class SparkUI(sc: SparkContext) extends Logging {
)
val storage = new BlockManagerUI(sc)
val jobs = new JobProgressUI(sc)
val allHandlers = storage.getHandlers ++ jobs.getHandlers ++ handlers
val env = new EnvironmentUI(sc)
val allHandlers = storage.getHandlers ++ jobs.getHandlers ++ env.getHandlers ++ handlers
/** Bind the HTTP server which backs this web interface */
def bind() {
......
......@@ -19,6 +19,10 @@ private[spark] object UIUtils {
case Jobs => <li class="active"><a href="/stages">Jobs</a></li>
case _ => <li><a href="/stages">Jobs</a></li>
}
val environment = page match {
case Environment => <li class="active"><a href="/environment">Environment</a></li>
case _ => <li><a href="/environment">Environment</a></li>
}
<html>
<head>
......@@ -44,6 +48,7 @@ private[spark] object UIUtils {
<ul class="nav">
{storage}
{jobs}
{environment}
</ul>
<ul id="infolist">
<li>Application: <strong>{sc.appName}</strong></li>
......
package spark.ui.env
import javax.servlet.http.HttpServletRequest
import org.eclipse.jetty.server.Handler
import scala.collection.JavaConversions._
import spark.ui.JettyUtils._
import spark.ui.UIUtils.headerSparkPage
import spark.ui.Page.Environment
import spark.SparkContext
import spark.ui.UIUtils
import scala.xml.Node
private[spark] class EnvironmentUI(sc: SparkContext) {
def getHandlers = Seq[(String, Handler)](
("/environment", (request: HttpServletRequest) => envDetails(request))
)
def envDetails(request: HttpServletRequest): Seq[Node] = {
val properties = System.getProperties.iterator.toSeq
val classPathProperty = properties
.filter{case (k, v) => k.contains("java.class.path")}
.headOption
.getOrElse("", "")
val sparkProperties = properties.filter(_._1.contains("spark"))
val otherProperties = properties.diff(sparkProperties :+ classPathProperty)
val propertyHeaders = Seq("Name", "Value")
def propertyRow(kv: (String, String)) = <tr><td>{kv._1}</td><td>{kv._2}</td></tr>
val propertyTable = UIUtils.listingTable(
propertyHeaders, propertyRow, sparkProperties ++ otherProperties)
val classPathEntries = classPathProperty._2
.split(System.getProperty("path.separator", ":"))
.filterNot(e => e.isEmpty)
.map(e => (e, "System Classpath"))
val addedJars = sc.addedJars.iterator.toSeq.map{case (path, time) => (path, "Added By User")}
val addedFiles = sc.addedFiles.iterator.toSeq.map{case (path, time) => (path, "Added By User")}
val classPath = addedJars ++ addedFiles ++ classPathEntries
val classPathHeaders = Seq("Resource", "Source")
def classPathRow(data: (String, String)) = <tr><td>{data._1}</td><td>{data._2}</td></tr>
val classPathTable = UIUtils.listingTable(classPathHeaders, classPathRow, classPath)
val content =
<span>
<h2>System Properties</h2> {propertyTable}
<h2>Classpath Entries</h2> {classPathTable}
</span>
headerSparkPage(content, sc, "Environment", Environment)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment