@@ -50,6 +50,8 @@ private[ui] class ExecutorsPage(
5050 threadDumpEnabled : Boolean )
5151 extends WebUIPage (" " ) {
5252 private val listener = parent.listener
53+ // When GCTimePercent is edited change ToolTips.TASK_TIME to match
54+ private val GCTimePercent = 0.1
5355
5456 def render (request : HttpServletRequest ): Seq [Node ] = {
5557 val (storageStatusList, execInfo) = listener.synchronized {
@@ -115,38 +117,10 @@ private[ui] class ExecutorsPage(
115117
116118 /** Render an HTML row representing an executor */
117119 private def execRow (info : ExecutorSummary , logsExist : Boolean ): Seq [Node ] = {
118- // When GCTimePercent is edited change ToolTips.TASK_TIME to match
119- val GCTimePercent = 0.1
120-
121120 val maximumMemory = info.maxMemory
122121 val memoryUsed = info.memoryUsed
123122 val diskUsed = info.diskUsed
124123
125- // Determine Color Opacity from 0.5-1
126- // activeTasks range from 0 to all cores
127- val activeTasksAlpha =
128- if (info.maxTasks > 0 ) {
129- (info.activeTasks.toDouble / info.maxTasks) * 0.5 + 0.5
130- } else {
131- 1
132- }
133- // failedTasks range max at 10% failure, alpha max = 1
134- // completedTasks range ignores 90% of tasks
135- val (failedTasksAlpha, completedTasksAlpha) =
136- if (info.totalTasks > 0 ) {
137- (math.min(10 * info.failedTasks.toDouble / info.totalTasks, 1 ) * 0.5 + 0.5 ,
138- math.max(((10 * info.completedTasks.toDouble / info.totalTasks) - 9 ) * 0.5 + 0.5 , 0.5 ))
139- } else {
140- (1 , 1 )
141- }
142- // totalDuration range from 0 to 50% GC time, alpha max = 1
143- val totalDurationAlpha =
144- if (info.totalDuration > 0 ) {
145- math.min(info.totalGCTime.toDouble / info.totalDuration + 0.5 , 1 )
146- } else {
147- 1
148- }
149-
150124 <tr >
151125 <td >{info.id}</td >
152126 <td >{info.hostPort}</td >
@@ -158,39 +132,8 @@ private[ui] class ExecutorsPage(
158132 <td sorttable_customkey ={diskUsed.toString}>
159133 {Utils .bytesToString(diskUsed)}
160134 </td >
161- < td style= {
162- if (info.activeTasks > 0 ) {
163- " background:hsla(240, 100%, 50%, " + activeTasksAlpha + " );color:white"
164- } else {
165- " "
166- }
167- }> {info.activeTasks}</td >
168- < td style= {
169- if (info.failedTasks > 0 ) {
170- " background:hsla(0, 100%, 50%, " + failedTasksAlpha + " );color:white"
171- } else {
172- " "
173- }
174- }> {info.failedTasks}</td >
175- < td style= {
176- if (info.completedTasks > 0 ) {
177- " background:hsla(120, 100%, 25%, " + completedTasksAlpha + " );color:white"
178- } else {
179- " "
180- }
181- }> {info.completedTasks}</td >
182- <td >{info.totalTasks}</td >
183- < td sorttable_customkey= {info.totalDuration.toString} style= {
184- // Red if GC time over GCTimePercent of total time
185- if (info.totalGCTime > GCTimePercent * info.totalDuration) {
186- " background:hsla(0, 100%, 50%, " + totalDurationAlpha + " );color:white"
187- } else {
188- " "
189- }
190- }>
191- {Utils .msDurationToString(info.totalDuration)}
192- ({Utils .msDurationToString(info.totalGCTime)})
193- </td >
135+ {coloredData(info.maxTasks, info.activeTasks, info.failedTasks, info.completedTasks,
136+ info.totalTasks, info.totalDuration, info.totalGCTime)}
194137 <td sorttable_customkey ={info.totalInputBytes.toString}>
195138 {Utils .bytesToString(info.totalInputBytes)}
196139 </td >
@@ -232,7 +175,6 @@ private[ui] class ExecutorsPage(
232175 val maximumMemory = execInfo.map(_.maxMemory).sum
233176 val memoryUsed = execInfo.map(_.memoryUsed).sum
234177 val diskUsed = execInfo.map(_.diskUsed).sum
235- val totalDuration = execInfo.map(_.totalDuration).sum
236178 val totalInputBytes = execInfo.map(_.totalInputBytes).sum
237179 val totalShuffleRead = execInfo.map(_.totalShuffleRead).sum
238180 val totalShuffleWrite = execInfo.map(_.totalShuffleWrite).sum
@@ -247,13 +189,13 @@ private[ui] class ExecutorsPage(
247189 <td sorttable_customkey ={diskUsed.toString}>
248190 {Utils .bytesToString(diskUsed)}
249191 </td >
250- < td >{ execInfo.map(_.activeTasks ).sum}</ td >
251- < td >{ execInfo.map(_.failedTasks ).sum}</ td >
252- < td >{ execInfo.map(_.completedTasks ).sum}</ td >
253- < td >{ execInfo.map(_.totalTasks ).sum}</ td >
254- < td sorttable_customkey ={totalDuration.toString}>
255- { Utils .msDurationToString( totalDuration)}
256- </ td >
192+ {coloredData( execInfo.map(_.maxTasks ).sum,
193+ execInfo.map(_.activeTasks ).sum,
194+ execInfo.map(_.failedTasks ).sum,
195+ execInfo.map(_.completedTasks ).sum,
196+ execInfo.map(_.totalTasks).sum,
197+ execInfo.map(_. totalDuration).sum,
198+ execInfo.map(_.totalGCTime).sum)}
257199 <td sorttable_customkey ={totalInputBytes.toString}>
258200 {Utils .bytesToString(totalInputBytes)}
259201 </td >
@@ -274,7 +216,7 @@ private[ui] class ExecutorsPage(
274216 <th >Failed Tasks </th >
275217 <th >Complete Tasks </th >
276218 <th >Total Tasks </th >
277- <th >Task Time </th >
219+ <th data-toggle = " tooltip " title ={ ToolTips . TASK_TIME } >Task Time ( GC Time ) </th >
278220 <th ><span data-toggle =" tooltip" title ={ToolTips .INPUT }>Input </span ></th >
279221 <th ><span data-toggle =" tooltip" title ={ToolTips .SHUFFLE_READ }>Shuffle Read </span ></th >
280222 <th >
@@ -288,6 +230,77 @@ private[ui] class ExecutorsPage(
288230 </tbody >
289231 </table >
290232 }
233+
234+ private def coloredData (maxTasks : Int ,
235+ activeTasks : Int ,
236+ failedTasks : Int ,
237+ completedTasks : Int ,
238+ totalTasks : Int ,
239+ totalDuration : Long ,
240+ totalGCTime : Long ):
241+ Seq [Node ] = {
242+ // Determine Color Opacity from 0.5-1
243+ // activeTasks range from 0 to all cores
244+ val activeTasksAlpha =
245+ if (maxTasks > 0 ) {
246+ (activeTasks.toDouble / maxTasks) * 0.5 + 0.5
247+ } else {
248+ 1
249+ }
250+ // failedTasks range max at 10% failure, alpha max = 1
251+ // completedTasks range ignores 90% of tasks
252+ val (failedTasksAlpha, completedTasksAlpha) =
253+ if (totalTasks > 0 ) {
254+ (math.min (10 * failedTasks.toDouble / totalTasks, 1 ) * 0.5 + 0.5 ,
255+ math.max (((10 * completedTasks.toDouble / totalTasks) - 9 ) * 0.5 + 0.5 , 0.5 ) )
256+ } else {
257+ (1 , 1 )
258+ }
259+ // totalDuration range from 0 to 50% GC time, alpha max = 1
260+ val totalDurationAlpha =
261+ if (totalDuration > 0 ) {
262+ math.min (totalGCTime.toDouble / totalDuration + 0.5 , 1 )
263+ } else {
264+ 1
265+ }
266+
267+ val tableData =
268+ < td style= {
269+ if (activeTasks > 0 ) {
270+ " background:hsla(240, 100%, 50%, " + activeTasksAlpha + " );color:white"
271+ } else {
272+ " "
273+ }
274+ }> {activeTasks}</td >
275+ < td style= {
276+ if (failedTasks > 0 ) {
277+ " background:hsla(0, 100%, 50%, " + failedTasksAlpha + " );color:white"
278+ } else {
279+ " "
280+ }
281+ }> {failedTasks}</td >
282+ < td style= {
283+ if (completedTasks > 0 ) {
284+ " background:hsla(120, 100%, 25%, " + completedTasksAlpha + " );color:white"
285+ } else {
286+ " "
287+ }
288+ }> {completedTasks}</td >
289+ <td >{totalTasks}</td >
290+ < td sorttable_customkey= {totalDuration.toString} style= {
291+ // Red if GC time over GCTimePercent of total time
292+ if (totalGCTime > GCTimePercent * totalDuration) {
293+ " background:hsla(0, 100%, 50%, " + totalDurationAlpha + " );color:white"
294+ } else {
295+ " "
296+ }
297+ }>
298+ {Utils .msDurationToString(totalDuration)}
299+ ({Utils .msDurationToString(totalGCTime)})
300+ </td >;
301+
302+ tableData
303+ }
291304}
292305
293306private [spark] object ExecutorsPage {
0 commit comments