| OLD | NEW |
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 {{template "header.html" .}} | 4 {{template "header.html" .}} |
| 5 <title>Skia Buildbot Dashboard</title> | 5 <title>Skia Buildbot Dashboard</title> |
| 6 | 6 |
| 7 <style> | 7 <style> |
| 8 core-header-panel { | 8 core-header-panel { |
| 9 background: white; | 9 background: white; |
| 10 font-family: sans-serif; | 10 font-family: sans-serif; |
| 11 } | 11 } |
| 12 core-toolbar { | 12 core-toolbar { |
| 13 background-color: #006C7C; | 13 background-color: #006C7C; |
| 14 color: #FFFFFF; | 14 color: #FFFFFF; |
| 15 text-align: center; | 15 text-align: center; |
| 16 font-size: 15px; | 16 font-size: 15px; |
| 17 } | 17 } |
| 18 h1 { | |
| 19 font-size: 1.7em; | |
| 20 margin-bottom: 2px; | |
| 21 margin-top: 5px; | |
| 22 } | |
| 23 #maincontent { | |
| 24 padding: 10px; | |
| 25 } | |
| 26 #spacer-left { | 18 #spacer-left { |
| 27 width: 160px; | 19 width: 160px; |
| 28 } | 20 } |
| 29 #spacer-right { | 21 #spacer-right { |
| 30 width: 0px; | 22 width: 0px; |
| 31 } | 23 } |
| 32 login-sk { | 24 login-sk { |
| 33 width: 200px; | 25 width: 200px; |
| 34 } | 26 } |
| 35 tree-status-sk { | 27 tree-status-sk { |
| 36 font-size: 1em; | 28 font-size: 1em; |
| 37 } | 29 } |
| 38 </style> | 30 </style> |
| 39 <script type="text/javascript" src="https://www.google.com/jsapi"></script> | |
| 40 <script type="text/javascript"> | |
| 41 (function() { | |
| 42 var chartsReady = false; | |
| 43 var ChartsReady = new Promise(function(resolve, reject) { | |
| 44 if (chartsReady) { | |
| 45 resolve(); | |
| 46 } else { | |
| 47 google.setOnLoadCallback(resolve); | |
| 48 } | |
| 49 }) | |
| 50 | |
| 51 google.load("visualization", "1.0", {"packages": ["corechart"]}); | |
| 52 google.setOnLoadCallback(function() { chartsReady = true; }); | |
| 53 | |
| 54 var builds = []; | |
| 55 var buildTimes = {}; | |
| 56 var stepTimes = {}; | |
| 57 var buildResults = {}; | |
| 58 var stepResults = {}; | |
| 59 | |
| 60 var blacklist = []; | |
| 61 var match = []; | |
| 62 | |
| 63 var palette = [ | |
| 64 "#03DCFB", "#00C2DD", "#008699", "#006C7C", "#00535E", // Blue | |
| 65 "#FFAE00", "#FFAE00", "#FAAB00", "#CA8A00", "#9A6900", // Yellow | |
| 66 "#FF1300", "#FF1300", "#FA1200", "#CA0F00", "#9A0B00", // Red | |
| 67 ]; | |
| 68 var paletteRowLen = 5; | |
| 69 var colors = [ | |
| 70 palette[2*paletteRowLen+3], | |
| 71 palette[1*paletteRowLen+3], | |
| 72 palette[0*paletteRowLen+3], | |
| 73 ]; | |
| 74 | |
| 75 function reloadBuilds(start, end) { | |
| 76 console.time("loadData"); | |
| 77 url = "/json/builds"; | |
| 78 if (!!start) { | |
| 79 url += "?start=" + start; | |
| 80 if (!!end) { | |
| 81 url += "&end=" + end; | |
| 82 } | |
| 83 } | |
| 84 document.getElementById("spinner").style.display = "flex"; | |
| 85 document.getElementById("chart_container").style.display = "none"; | |
| 86 sk.get(url).then(JSON.parse).then(function(json) { | |
| 87 console.timeEnd("loadData"); | |
| 88 builds = json; | |
| 89 processBuilds(); | |
| 90 document.getElementById("spinner").style.display = "none"; | |
| 91 document.getElementById("chart_container").style.display = "flex"; | |
| 92 }); | |
| 93 } | |
| 94 | |
| 95 function includeBuilder(builder) { | |
| 96 for (var i = 0; i < blacklist.length; i++) { | |
| 97 if (builder.match(blacklist[i])) { | |
| 98 return false; | |
| 99 } | |
| 100 } | |
| 101 for (var i = 0; i < match.length; i++) { | |
| 102 if (!builder.match(match[i])) { | |
| 103 return false; | |
| 104 } | |
| 105 } | |
| 106 return true; | |
| 107 } | |
| 108 | |
| 109 function mean(data) { | |
| 110 // TODO(borenet): Use a more stable algorithm. | |
| 111 var sum = 0; | |
| 112 for (var i = 0; i < data.length; i++) { | |
| 113 sum += data[i]; | |
| 114 } | |
| 115 return sum / data.length; | |
| 116 } | |
| 117 | |
| 118 function processBuilds() { | |
| 119 console.time("processBuilds"); | |
| 120 buildTimes = {}; | |
| 121 stepTimes = {}; | |
| 122 buildResults = {}; | |
| 123 stepResults = {}; | |
| 124 | |
| 125 for (var i = 0; i < builds.length; i++) { | |
| 126 var build = builds[i]; | |
| 127 if (!includeBuilder(build.Builder)) { | |
| 128 continue; | |
| 129 } | |
| 130 | |
| 131 var duration = build.Finished - build.Started; | |
| 132 if (!buildTimes[build.Builder]) { | |
| 133 buildTimes[build.Builder] = []; | |
| 134 } | |
| 135 buildTimes[build.Builder].push(duration); | |
| 136 | |
| 137 if (!buildResults[build.Builder]) { | |
| 138 buildResults[build.Builder] = []; | |
| 139 } | |
| 140 buildResults[build.Builder].push(build.Results == 0 ? 0 : 1); | |
| 141 | |
| 142 for (var j = 0; j < build.Steps.length; j++) { | |
| 143 var step = build.Steps[j]; | |
| 144 // Always exclude these steps. | |
| 145 if (step.Name == "steps" || step.Name == "Uncaught Exception") { | |
| 146 continue; | |
| 147 } | |
| 148 var stepDuration = step.Finished - step.Started; | |
| 149 if (!stepTimes[step.Name]) { | |
| 150 stepTimes[step.Name] = []; | |
| 151 } | |
| 152 stepTimes[step.Name].push(stepDuration); | |
| 153 | |
| 154 if (!stepResults[step.Name]) { | |
| 155 stepResults[step.Name] = []; | |
| 156 } | |
| 157 stepResults[step.Name].push(step.Results == 0 ? 0 : 1); | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 console.timeEnd("processBuilds"); | |
| 162 drawCharts(); | |
| 163 } | |
| 164 | |
| 165 function drawCharts() { | |
| 166 console.time("drawCharts"); | |
| 167 // Draw charts. | |
| 168 ChartsReady.then(function() { | |
| 169 var chart = null; | |
| 170 | |
| 171 // Build times. | |
| 172 chart = document.getElementById("build_times_chart"); | |
| 173 chart.colors = colors; | |
| 174 chart.draw( | |
| 175 [["string", "Builder"], | |
| 176 ["number", "Time (s)"]], | |
| 177 generateStats(buildTimes, mean)); | |
| 178 | |
| 179 // Step times. | |
| 180 chart = document.getElementById("step_times_chart"); | |
| 181 chart.colors = colors; | |
| 182 chart.draw( | |
| 183 [["string", "Step"], | |
| 184 ["number", "Time (s)"]], | |
| 185 generateStats(stepTimes, mean)); | |
| 186 | |
| 187 // Build failure rate. | |
| 188 chart = document.getElementById("build_failure_rate_chart"); | |
| 189 chart.colors = colors; | |
| 190 chart.draw( | |
| 191 [["string", "Builder"], | |
| 192 ["number", "Failure Rate"]], | |
| 193 generateStats(buildResults, mean)); | |
| 194 | |
| 195 // Step failure rate. | |
| 196 chart = document.getElementById("step_failure_rate_chart"); | |
| 197 chart.colors = colors; | |
| 198 chart.draw( | |
| 199 [["string", "Step"], | |
| 200 ["number", "Failure Rate"]], | |
| 201 generateStats(stepResults, mean)); | |
| 202 | |
| 203 console.timeEnd("drawCharts"); | |
| 204 }); | |
| 205 } | |
| 206 | |
| 207 function generateStats(data, aggregator) { | |
| 208 var stats = []; | |
| 209 for (var series in data) { | |
| 210 stats.push([series, aggregator(data[series])]); | |
| 211 } | |
| 212 stats.sort(function(a, b) { | |
| 213 return b[1] - a[1]; | |
| 214 }); | |
| 215 return stats; | |
| 216 } | |
| 217 | |
| 218 sk.WebComponentsReady.then(function() { reloadBuilds(); }); | |
| 219 })(); | |
| 220 </script> | |
| 221 </head> | 31 </head> |
| 222 <body fullbleed vertical layout unresolved> | 32 <body fullbleed vertical layout unresolved> |
| 223 <core-header-panel flex> | 33 <core-header-panel flex> |
| 224 <core-toolbar class="short"> | 34 <core-toolbar class="short"> |
| 225 <div id="toolbar" class="top" horizontal layout center fit> | 35 <div id="toolbar" class="top" horizontal layout center fit> |
| 226 <menu-sk></menu-sk> | 36 <menu-sk></menu-sk> |
| 227 <div id="spacer-left"></div> | 37 <div id="spacer-left"></div> |
| 228 <div id="title" vertical layout flex> | 38 <div id="title" vertical layout flex> |
| 229 <h1>Skia Buildbot Dashboard</h1> | 39 <h1>Skia Buildbot Dashboard</h1> |
| 230 </div> | 40 </div> |
| 231 <div id="spacer-right"></div> | 41 <div id="spacer-right"></div> |
| 232 <login-sk></login-sk> | 42 <login-sk></login-sk> |
| 233 </div> | 43 </div> |
| 234 </core-toolbar> | 44 </core-toolbar> |
| 235 <div id="maincontent" vertical layout> | 45 <buildbot-dash-sk></buildbot-dash-sk> |
| 236 <div id="spinner" horizontal layout center fit> | |
| 237 <div vertical layout center flex> | |
| 238 <paper-spinner active></paper-spinner> | |
| 239 </div> | |
| 240 </div> | |
| 241 <div id="chart_container" vertical layout> | |
| 242 <bar-chart-sk heading="Build Times" id="build_times_chart"></bar-chart
-sk> | |
| 243 <bar-chart-sk heading="Step Times" id="step_times_chart"></bar-chart-s
k> | |
| 244 <bar-chart-sk heading="Build Failure Rate" id="build_failure_rate_char
t"></bar-chart-sk> | |
| 245 <bar-chart-sk heading="Step Failure Rate" id="step_failure_rate_chart"
></bar-chart-sk> | |
| 246 </div> | |
| 247 </div> | |
| 248 </core-header-panel> | 46 </core-header-panel> |
| 249 <div horizontal layout> | 47 <div horizontal layout> |
| 250 <div flex></div> | 48 <div flex></div> |
| 251 <version-sk></version-sk> | 49 <version-sk></version-sk> |
| 252 </div> | 50 </div> |
| 253 </body> | 51 </body> |
| 254 </html> | 52 </html> |
| OLD | NEW |