mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Windows: stats support
Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user