github.com/fanux/shipyard@v0.0.0-20161009071005-6515ce223235/controller/static/app/containers/stats.controller.js (about) 1 (function(){ 2 'use strict'; 3 4 angular 5 .module('shipyard.containers') 6 .controller('ContainerStatsController', ContainerStatsController); 7 8 ContainerStatsController.$inject = ['$stateParams', '$scope']; 9 function ContainerStatsController($stateParams, $scope) { 10 var vm = this; 11 var graphCpuStats; 12 var graphMemoryStats; 13 var graphNetStats; 14 vm.refreshInterval = 2; 15 vm.id = $stateParams.id; 16 17 vm.cpuStats = [{ 18 key: "CPU", 19 values: [] 20 }]; 21 22 vm.memoryStats = [{ 23 key: "Memory", 24 color: '#ffa500', 25 values: [] 26 }]; 27 28 vm.netStats = [ 29 { 30 key: "Network (rx)", 31 values: [] 32 }, 33 { 34 key: "Network (tx)", 35 values: [] 36 } 37 ]; 38 39 vm.x = 0; 40 41 42 var previousCpuUsage = 0; 43 var previousSystemCpuUsage = 0; 44 function addCpuUsage(date, systemUsage, usage, cpuCores) { 45 if(previousCpuUsage == 0 || previousSystemCpuUsage == 0) { 46 previousCpuUsage = usage; 47 previousSystemCpuUsage = systemUsage; 48 return; 49 } 50 51 var usageSample = usage - previousCpuUsage 52 previousCpuUsage = usage; 53 54 var systemUsageSample = systemUsage - previousSystemCpuUsage; 55 previousSystemCpuUsage = systemUsage; 56 57 var cpuPercent = 0.0; 58 if(usageSample > 0.0 && systemUsageSample > 0.0) { 59 cpuPercent = (usageSample / systemUsageSample) * cpuCores * 100.0; 60 } 61 62 var stat = { x: date, y: cpuPercent }; 63 vm.cpuStats[0].values.push(stat); 64 if (vm.cpuStats[0].values.length > 20) { 65 vm.cpuStats[0].values.shift(); 66 } 67 68 } 69 70 function addMemoryUsage(date, usage) { 71 var stat = { x: date, y: usage }; 72 vm.memoryStats[0].values.push(stat); 73 if (vm.memoryStats[0].values.length > 20) { 74 vm.memoryStats[0].values.shift(); 75 } 76 } 77 78 function addNetworkUsage(date, rxUsage, txUsage) { 79 var rxStat = { x: date, y: rxUsage }; 80 vm.netStats[0].values.push(rxStat); 81 if (vm.netStats[0].values.length > 20) { 82 vm.netStats[0].values.shift(); 83 } 84 85 var txStat = { x: date, y: txUsage }; 86 vm.netStats[1].values.push(txStat); 87 if (vm.netStats[1].values.length > 20) { 88 vm.netStats[1].values.shift(); 89 } 90 } 91 92 nv.addGraph(function() { 93 graphCpuStats = nv.models.lineChart() 94 .options({ 95 transitionDuration: 300, 96 noData: "Loading...", 97 }) 98 ; 99 graphCpuStats 100 .x(function(d,i) { return d.x }); 101 graphCpuStats.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately 102 .tickFormat(function(d) { return d3.time.format('%H:%M:%S')(new Date(d)); }) 103 .axisLabel('') 104 ; 105 graphCpuStats 106 graphCpuStats.yAxis 107 .axisLabel('%') 108 .tickFormat(d3.format(',.2f')); 109 graphCpuStats.showXAxis(true).showYAxis(true).rightAlignYAxis(true).margin({right: 90}); 110 d3.select('#graphCpuStats svg') 111 .datum(vm.cpuStats) 112 .transition().duration(500) 113 .call(graphCpuStats); 114 nv.utils.windowResize(graphCpuStats.update); 115 return graphCpuStats; 116 }); 117 118 nv.addGraph(function() { 119 graphMemoryStats = nv.models.lineChart() 120 .options({ 121 transitionDuration: 300, 122 noData: "Loading...", 123 }) 124 .forceY([0,1]) 125 ; 126 graphMemoryStats 127 .x(function(d,i) { return d.x }); 128 graphMemoryStats.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately 129 .tickFormat(function(d) { return d3.time.format('%H:%M:%S')(new Date(d)); }) 130 .axisLabel('') 131 ; 132 graphMemoryStats 133 graphMemoryStats.yAxis 134 .axisLabel('MB') 135 .tickFormat(d3.format(',.2f')); 136 graphMemoryStats.showXAxis(true).showYAxis(true).rightAlignYAxis(true).margin({right: 90}); 137 d3.select('#graphMemoryStats svg') 138 .datum(vm.memoryStats) 139 .transition().duration(500) 140 .call(graphMemoryStats); 141 nv.utils.windowResize(graphMemoryStats.update); 142 return graphMemoryStats; 143 }); 144 145 nv.addGraph(function() { 146 graphNetStats = nv.models.lineChart() 147 .options({ 148 transitionDuration: 300, 149 noData: "Loading...", 150 }) 151 ; 152 graphNetStats 153 .x(function(d,i) { return d.x }); 154 graphNetStats.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately 155 .tickFormat(function(d) { return d3.time.format('%H:%M:%S')(new Date(d)); }) 156 .axisLabel('') 157 ; 158 graphNetStats 159 graphNetStats.yAxis 160 .axisLabel('MB') 161 .tickFormat(d3.format(',.2f')); 162 graphNetStats.showXAxis(true).showYAxis(true).rightAlignYAxis(true).margin({right: 90}); 163 d3.select('#graphNetStats svg') 164 .datum(vm.netStats) 165 .transition().duration(500) 166 .call(graphNetStats); 167 nv.utils.windowResize(graphNetStats.update); 168 return graphNetStats; 169 }); 170 171 var stream = oboe({ 172 url: '/containers/' + vm.id + '/stats', 173 withCredentials: true, 174 headers: { 175 'X-Access-Token': localStorage.getItem("X-Access-Token") 176 } 177 }) 178 .done(function(node) { 179 // stats come every 1 second; only update every 5 180 if (vm.x % vm.refreshInterval === 0) { 181 var timestamp = Date.parse(node.read); 182 addCpuUsage(timestamp, node.cpu_stats.system_cpu_usage, node.cpu_stats.cpu_usage.total_usage, node.cpu_stats.cpu_usage.percpu_usage.length); 183 // convert to MB 184 addMemoryUsage(timestamp, node.memory_stats.usage / 1048576); 185 // convert to MB 186 if(node.network) { 187 addNetworkUsage(timestamp, node.network.rx_bytes / 1048576, node.network.tx_bytes / 1048576); 188 } else if(node.networks) { 189 var ifs = Object.keys(node.networks); 190 var rxbytes = 0; 191 var txbytes = 0; 192 193 for (var i = ifs.length - 1; i >= 0; i--) { 194 txbytes+=node.networks[ifs[i]].tx_bytes; 195 rxbytes+=node.networks[ifs[i]].rx_bytes; 196 } 197 198 addNetworkUsage(timestamp, txbytes / 1048576, txbytes / 1048576); 199 } 200 201 refreshGraphs(); 202 } 203 vm.x++; 204 }) 205 .fail(function(err) { 206 vm.error = err; 207 }) 208 209 function refreshGraphs() { 210 graphCpuStats.update(); 211 graphMemoryStats.update(); 212 graphNetStats.update(); 213 } 214 215 $scope.$on("$destroy", function() { 216 stream.abort(); 217 }); 218 219 } 220 })();