Windows: stats support

Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
John Howard
2016-09-07 16:08:51 -07:00
parent a7c25f9540
commit 340e5233b2
22 changed files with 585 additions and 323 deletions

View File

@@ -3,8 +3,8 @@ package daemon
import (
"encoding/json"
"errors"
"fmt"
"runtime"
"time"
"golang.org/x/net/context"
@@ -19,9 +19,6 @@ import (
// ContainerStats writes information about the container to the stream
// given in the config object.
func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *backend.ContainerStatsConfig) error {
if runtime.GOOS == "windows" {
return errors.New("Windows does not support stats")
}
// Remote API version (used for backwards compatibility)
apiVersion := config.Version
@@ -44,10 +41,13 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
}
var preCPUStats types.CPUStats
var preRead time.Time
getStatJSON := func(v interface{}) *types.StatsJSON {
ss := v.(types.StatsJSON)
ss.PreCPUStats = preCPUStats
ss.PreRead = preRead
preCPUStats = ss.CPUStats
preRead = ss.Read
return &ss
}
@@ -67,6 +67,9 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
var statsJSON interface{}
statsJSONPost120 := getStatJSON(v)
if versions.LessThan(apiVersion, "1.21") {
if runtime.GOOS == "windows" {
return errors.New("API versions pre v1.21 do not support stats on Windows")
}
var (
rxBytes uint64
rxPackets uint64
@@ -138,7 +141,8 @@ func (daemon *Daemon) GetContainerStats(container *container.Container) (*types.
return nil, err
}
if !container.Config.NetworkDisabled {
// We already have the network stats on Windows directly from HCS.
if !container.Config.NetworkDisabled && runtime.GOOS != "windows" {
if stats.Networks, err = daemon.getNetworkStats(container); err != nil {
return nil, err
}
@@ -146,51 +150,3 @@ func (daemon *Daemon) GetContainerStats(container *container.Container) (*types.
return stats, nil
}
// Resolve Network SandboxID in case the container reuse another container's network stack
func (daemon *Daemon) getNetworkSandboxID(c *container.Container) (string, error) {
curr := c
for curr.HostConfig.NetworkMode.IsContainer() {
containerID := curr.HostConfig.NetworkMode.ConnectedContainer()
connected, err := daemon.GetContainer(containerID)
if err != nil {
return "", fmt.Errorf("Could not get container for %s", containerID)
}
curr = connected
}
return curr.NetworkSettings.SandboxID, nil
}
func (daemon *Daemon) getNetworkStats(c *container.Container) (map[string]types.NetworkStats, error) {
sandboxID, err := daemon.getNetworkSandboxID(c)
if err != nil {
return nil, err
}
sb, err := daemon.netController.SandboxByID(sandboxID)
if err != nil {
return nil, err
}
lnstats, err := sb.Statistics()
if err != nil {
return nil, err
}
stats := make(map[string]types.NetworkStats)
// Convert libnetwork nw stats into engine-api stats
for ifName, ifStats := range lnstats {
stats[ifName] = types.NetworkStats{
RxBytes: ifStats.RxBytes,
RxPackets: ifStats.RxPackets,
RxErrors: ifStats.RxErrors,
RxDropped: ifStats.RxDropped,
TxBytes: ifStats.TxBytes,
TxPackets: ifStats.TxPackets,
TxErrors: ifStats.TxErrors,
TxDropped: ifStats.TxDropped,
}
}
return stats, nil
}