diff --git a/pages/containers_html.go b/pages/containers_html.go index 41af3f95..abc4ea28 100644 --- a/pages/containers_html.go +++ b/pages/containers_html.go @@ -192,6 +192,16 @@ const containersHtmlTemplate = `

Network

+
+ +

Throughput

diff --git a/pages/static/containers_js.go b/pages/static/containers_js.go index 9cba5ae9..a91fe56a 100644 --- a/pages/static/containers_js.go +++ b/pages/static/containers_js.go @@ -375,12 +375,32 @@ function drawMemoryUsage(elementId, machineInfo, containerInfo) { drawLineChart(titles, data, elementId, "Megabytes"); } +// Get the index of the interface with the specified name. +function getNetworkInterfaceIndex(interfaceName, interfaces) { + for (var i = 0; i < interfaces.length; i++) { + if (interfaces[i].name == interfaceName) { + return i; + } + } + return -1; +} + // Draw the graph for network tx/rx bytes. function drawNetworkBytes(elementId, machineInfo, stats) { if (stats.spec.has_network && !hasResource(stats, "network")) { return; } + // Get interface index. + var interfaceIndex = -1; + if (stats.stats.length > 0) { + interfaceIndex = getNetworkInterfaceIndex(window.cadvisor.network.interface, stats.stats[0].network.interfaces); + } + if (interfaceIndex < 0) { + console.log("Unable to find interface\"", interfaceName, "\" in ", stats.stats.network); + return; + } + var titles = ["Time", "Tx bytes", "Rx bytes"]; var data = []; for (var i = 1; i < stats.stats.length; i++) { @@ -390,8 +410,8 @@ function drawNetworkBytes(elementId, machineInfo, stats) { var elements = []; elements.push(cur.timestamp); - elements.push((cur.network.tx_bytes - prev.network.tx_bytes) / intervalInSec); - elements.push((cur.network.rx_bytes - prev.network.rx_bytes) / intervalInSec); + elements.push((cur.network.interfaces[interfaceIndex].tx_bytes - prev.network.interfaces[interfaceIndex].tx_bytes) / intervalInSec); + elements.push((cur.network.interfaces[interfaceIndex].rx_bytes - prev.network.interfaces[interfaceIndex].rx_bytes) / intervalInSec); data.push(elements); } drawLineChart(titles, data, elementId, "Bytes per second"); @@ -403,6 +423,16 @@ function drawNetworkErrors(elementId, machineInfo, stats) { return; } + // Get interface index. + var interfaceIndex = -1; + if (stats.stats.length > 0) { + interfaceIndex = getNetworkInterfaceIndex(window.cadvisor.network.interface, stats.stats[0].network.interfaces); + } + if (interfaceIndex < 0) { + console.log("Unable to find interface\"", interfaceName, "\" in ", stats.stats.network); + return; + } + var titles = ["Time", "Tx", "Rx"]; var data = []; for (var i = 1; i < stats.stats.length; i++) { @@ -412,8 +442,8 @@ function drawNetworkErrors(elementId, machineInfo, stats) { var elements = []; elements.push(cur.timestamp); - elements.push((cur.network.tx_errors - prev.network.tx_errors) / intervalInSec); - elements.push((cur.network.rx_errors - prev.network.rx_errors) / intervalInSec); + elements.push((cur.network.interfaces[interfaceIndex].tx_errors - prev.network.interfaces[interfaceIndex].tx_errors) / intervalInSec); + elements.push((cur.network.interfaces[interfaceIndex].rx_errors - prev.network.interfaces[interfaceIndex].rx_errors) / intervalInSec); data.push(elements); } drawLineChart(titles, data, elementId, "Errors per second"); @@ -618,6 +648,41 @@ function drawCharts(machineInfo, containerInfo) { stepExecute(steps); } +function setNetwork(interfaceName) { + $("#network-selection-text") + .empty() + .append($("").text("Interface: ")) + .append($("").text(interfaceName)); + window.cadvisor.network.interface = interfaceName; + // TODO(vmarmol): Draw network here. +} + +// Creates the network selection dropdown. +function startNetwork(selectionElement, containerInfo) { + if (!hasResource(containerInfo, "network") || containerInfo.stats.length == 0 + || !containerInfo.stats[0].network.interfaces || containerInfo.stats[0].network.interfaces.length == 0) { + return; + } + + window.cadvisor.network = {}; + window.cadvisor.network.interface = ""; + + // Add all interfaces to the dropdown. + var el = $("#" + selectionElement); + console.log(containerInfo.stats[0].network.interfaces); + for (var i = 0; i < containerInfo.stats[0].network.interfaces.length; i++) { + var interfaceName = containerInfo.stats[0].network.interfaces[i].name; + el.append($("
  • ") + .attr("role", "presentation") + .append($("") + .attr("role", "menuitem") + .attr("tabindex", -1) + .click(setNetwork.bind(null, interfaceName)) + .text(interfaceName))); + } + setNetwork(containerInfo.stats[0].network.interfaces[0].name); +} + // Executed when the page finishes loading. function startPage(containerName, hasCpu, hasMemory, rootDir, isRoot) { // Don't fetch data if we don't have any resource. @@ -643,9 +708,15 @@ function startPage(containerName, hasCpu, hasMemory, rootDir, isRoot) { getMachineInfo(rootDir, function(machineInfo) { setInterval(function() { getStats(rootDir, containerName, function(containerInfo){ - if (window.cadvisor.firstRun && containerInfo.spec.has_filesystem) { + if (window.cadvisor.firstRun) { window.cadvisor.firstRun = false; - startFileSystemUsage("filesystem-usage", machineInfo, containerInfo); + + if (containerInfo.spec.has_filesystem) { + startFileSystemUsage("filesystem-usage", machineInfo, containerInfo); + } + if (containerInfo.spec.has_network) { + startNetwork("network-selection", containerInfo); + } } drawCharts(machineInfo, containerInfo);