@@ -20,15 +20,15 @@ package org.apache.spark.deploy.master.ui
2020import javax .servlet .http .HttpServletRequest
2121
2222import scala .concurrent .Await
23- import scala .xml .Node
23+ import scala .xml .{ Text , Node }
2424
2525import akka .pattern .ask
2626import org .json4s .JValue
2727
2828import org .apache .spark .deploy .JsonProtocol
2929import org .apache .spark .deploy .DeployMessages .{MasterStateResponse , RequestMasterState }
30- import org .apache .spark .deploy .master .{ApplicationInfo , DriverInfo , WorkerInfo }
31- import org .apache .spark .ui .{WebUIPage , UIUtils }
30+ import org .apache .spark .deploy .master .{WorkerInfo , ApplicationInfo , DriverInfo }
31+ import org .apache .spark .ui .{UITable , UITableBuilder , WebUIPage , UIUtils }
3232import org .apache .spark .util .Utils
3333
3434private [spark] class MasterPage (parent : MasterWebUI ) extends WebUIPage (" " ) {
@@ -41,32 +41,71 @@ private[spark] class MasterPage(parent: MasterWebUI) extends WebUIPage("") {
4141 JsonProtocol .writeMasterState(state)
4242 }
4343
44+ private val workerTable : UITable [WorkerInfo ] = {
45+ val builder = new UITableBuilder [WorkerInfo ]()
46+ import builder ._
47+ customCol(" ID" ) { worker =>
48+ <a href ={worker.webUiAddress}>{worker.id}</a >
49+ }
50+ col(" Address" ) { worker => s " ${worker.host}: ${worker.port}" }
51+ col(" State" ) { _.state.toString }
52+ intCol(" Cores" , formatter = c => s " $c Used " ) { _.coresUsed }
53+ customCol(" Memory" ,
54+ sortKey = Some ({worker : WorkerInfo => s " ${worker.memory}: ${worker.memoryUsed}" })) { worker =>
55+ Text (Utils .megabytesToString(worker.memory)) ++
56+ Text (Utils .megabytesToString(worker.memoryUsed))
57+ }
58+ build
59+ }
60+
61+ private val appTable : UITable [ApplicationInfo ] = {
62+ val builder = new UITableBuilder [ApplicationInfo ]()
63+ import builder ._
64+ customCol(" ID" ) { app =>
65+ <a href ={" app?appId=" + app.id}>{app.id}</a >
66+ }
67+ col(" Name" ) { _.id }
68+ intCol(" Cores" ) { _.coresGranted }
69+ memCol(" Memory per Node" ) { _.desc.memoryPerSlave }
70+ dateCol(" Submitted Time" ) { _.submitDate }
71+ col(" User" ) { _.desc.user }
72+ col(" State" ) { _.state.toString }
73+ durationCol(" Duration" ) { _.duration }
74+ build
75+ }
76+
77+ private val driverTable : UITable [DriverInfo ] = {
78+ val builder = new UITableBuilder [DriverInfo ]()
79+ import builder ._
80+ col(" ID" ) { _.id }
81+ dateCol(" Submitted Time" ) { _.submitDate }
82+ customCol(" Worker" ) { driver =>
83+ driver.worker.map(w => <a href ={w.webUiAddress}>{w.id.toString}</a >).getOrElse(Text (" None" ))
84+ }
85+ col(" State" ) { _.state.toString }
86+ intCol(" Cores" ) { _.desc.cores }
87+ memCol(" Memory" ) { _.desc.mem.toLong }
88+ col(" Main Class" ) { _.desc.command.arguments(1 ) }
89+ build
90+ }
91+
4492 /** Index view listing applications and executors */
4593 def render (request : HttpServletRequest ): Seq [Node ] = {
4694 val stateFuture = (master ? RequestMasterState )(timeout).mapTo[MasterStateResponse ]
4795 val state = Await .result(stateFuture, timeout)
4896
49- val workerHeaders = Seq (" Id" , " Address" , " State" , " Cores" , " Memory" )
50- val workers = state.workers.sortBy(_.id)
51- val workerTable = UIUtils .listingTable(workerHeaders, workerRow, workers)
97+ val allWorkersTable = workerTable.render(state.workers.sortBy(_.id))
5298
53- val appHeaders = Seq (" ID" , " Name" , " Cores" , " Memory per Node" , " Submitted Time" , " User" ,
54- " State" , " Duration" )
55- val activeApps = state.activeApps.sortBy(_.startTime).reverse
56- val activeAppsTable = UIUtils .listingTable(appHeaders, appRow, activeApps)
57- val completedApps = state.completedApps.sortBy(_.endTime).reverse
58- val completedAppsTable = UIUtils .listingTable(appHeaders, appRow, completedApps)
99+ val activeAppsTable = appTable.render(state.activeApps.sortBy(_.startTime).reverse)
100+ val completedAppsTable = appTable.render(state.completedApps.sortBy(_.endTime).reverse)
59101
60- val driverHeaders = Seq (" ID" , " Submitted Time" , " Worker" , " State" , " Cores" , " Memory" ,
61- " Main Class" )
62- val activeDrivers = state.activeDrivers.sortBy(_.startTime).reverse
63- val activeDriversTable = UIUtils .listingTable(driverHeaders, driverRow, activeDrivers)
64- val completedDrivers = state.completedDrivers.sortBy(_.startTime).reverse
65- val completedDriversTable = UIUtils .listingTable(driverHeaders, driverRow, completedDrivers)
102+ val activeDriversTable = driverTable.render(state.activeDrivers.sortBy(_.startTime).reverse)
103+ val completedDriversTable =
104+ driverTable.render(state.completedDrivers.sortBy(_.startTime).reverse)
66105
67106 // For now we only show driver information if the user has submitted drivers to the cluster.
68107 // This is until we integrate the notion of drivers and applications in the UI.
69- def hasDrivers = activeDrivers.length > 0 || completedDrivers.length > 0
108+ def hasDrivers = state. activeDrivers.length > 0 || state. completedDrivers.length > 0
70109
71110 val content =
72111 <div class =" row-fluid" >
@@ -93,7 +132,7 @@ private[spark] class MasterPage(parent: MasterWebUI) extends WebUIPage("") {
93132 <div class =" row-fluid" >
94133 <div class =" span12" >
95134 <h4 > Workers </h4 >
96- {workerTable }
135+ {allWorkersTable }
97136 </div >
98137 </div >
99138
@@ -138,57 +177,4 @@ private[spark] class MasterPage(parent: MasterWebUI) extends WebUIPage("") {
138177
139178 UIUtils .basicSparkPage(content, " Spark Master at " + state.uri)
140179 }
141-
142- private def workerRow (worker : WorkerInfo ): Seq [Node ] = {
143- <tr >
144- <td >
145- <a href ={worker.webUiAddress}>{worker.id}</a >
146- </td >
147- <td >{worker.host}: {worker.port}</td >
148- <td >{worker.state}</td >
149- <td >{worker.cores} ({worker.coresUsed} Used )</td >
150- <td sorttable_customkey ={" %s.%s" .format(worker.memory, worker.memoryUsed)}>
151- {Utils .megabytesToString(worker.memory)}
152- ({Utils .megabytesToString(worker.memoryUsed)} Used )
153- </td >
154- </tr >
155- }
156-
157- private def appRow (app : ApplicationInfo ): Seq [Node ] = {
158- <tr >
159- <td >
160- <a href ={" app?appId=" + app.id}>{app.id}</a >
161- </td >
162- <td >
163- <a href ={app.desc.appUiUrl}>{app.desc.name}</a >
164- </td >
165- <td >
166- {app.coresGranted}
167- </td >
168- <td sorttable_customkey ={app.desc.memoryPerSlave.toString}>
169- {Utils .megabytesToString(app.desc.memoryPerSlave)}
170- </td >
171- <td >{UIUtils .formatDate(app.submitDate)}</td >
172- <td >{app.desc.user}</td >
173- <td >{app.state.toString}</td >
174- <td >{UIUtils .formatDuration(app.duration)}</td >
175- </tr >
176- }
177-
178- private def driverRow (driver : DriverInfo ): Seq [Node ] = {
179- <tr >
180- <td >{driver.id} </td >
181- <td >{driver.submitDate}</td >
182- <td >{driver.worker.map(w => <a href ={w.webUiAddress}>{w.id.toString}</a >).getOrElse(" None" )}
183- </td >
184- <td >{driver.state}</td >
185- <td sorttable_customkey ={driver.desc.cores.toString}>
186- {driver.desc.cores}
187- </td >
188- <td sorttable_customkey ={driver.desc.mem.toString}>
189- {Utils .megabytesToString(driver.desc.mem.toLong)}
190- </td >
191- <td >{driver.desc.command.arguments(1 )}</td >
192- </tr >
193- }
194180}
0 commit comments