org.apache.spark.sql.execution.ui.ExecutionPage.scala Maven / Gradle / Ivy
/*
* 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.spark.sql.execution.ui
import javax.servlet.http.HttpServletRequest
import scala.xml.Node
import org.apache.spark.JobExecutionStatus
import org.apache.spark.internal.Logging
import org.apache.spark.ui.{UIUtils, WebUIPage}
class ExecutionPage(parent: SQLTab) extends WebUIPage("execution") with Logging {
private val sqlStore = parent.sqlStore
override def render(request: HttpServletRequest): Seq[Node] = {
// stripXSS is called first to remove suspicious characters used in XSS attacks
val parameterExecutionId = UIUtils.stripXSS(request.getParameter("id"))
require(parameterExecutionId != null && parameterExecutionId.nonEmpty,
"Missing execution id parameter")
val executionId = parameterExecutionId.toLong
val content = sqlStore.execution(executionId).map { executionUIData =>
val currentTime = System.currentTimeMillis()
val duration = executionUIData.completionTime.map(_.getTime()).getOrElse(currentTime) -
executionUIData.submissionTime
def jobLinks(status: JobExecutionStatus, label: String): Seq[Node] = {
val jobs = executionUIData.jobs.flatMap { case (jobId, jobStatus) =>
if (jobStatus == status) Some(jobId) else None
}
if (jobs.nonEmpty) {
{label}
{jobs.toSeq.sorted.map { jobId =>
{jobId.toString}
}}
} else {
Nil
}
}
val summary =
-
Submitted Time: {UIUtils.formatDate(executionUIData.submissionTime)}
-
Duration: {UIUtils.formatDuration(duration)}
{jobLinks(JobExecutionStatus.RUNNING, "Running Jobs:")}
{jobLinks(JobExecutionStatus.SUCCEEDED, "Succeeded Jobs:")}
{jobLinks(JobExecutionStatus.FAILED, "Failed Jobs:")}
val metrics = sqlStore.executionMetrics(executionId)
val graph = sqlStore.planGraph(executionId)
summary ++
planVisualization(metrics, graph) ++
physicalPlanDescription(executionUIData.physicalPlanDescription)
}.getOrElse {
No information to display for query {executionId}
}
UIUtils.headerSparkPage(s"Details for Query $executionId", content, parent, Some(5000))
}
private def planVisualizationResources: Seq[Node] = {
// scalastyle:off
// scalastyle:on
}
private def planVisualization(metrics: Map[Long, String], graph: SparkPlanGraph): Seq[Node] = {
val metadata = graph.allNodes.flatMap { node =>
val nodeId = s"plan-meta-data-${node.id}"
{node.desc}
}
}
private def jobURL(jobId: Long): String =
"%s/jobs/job?id=%s".format(UIUtils.prependBaseUri(parent.basePath), jobId)
private def physicalPlanDescription(physicalPlanDescription: String): Seq[Node] = {
{planVisualizationResources}
}
}