Skip to content

Commit

Permalink
Basic fix for the issue influxdata#2457 - influxdata#2457
Browse files Browse the repository at this point in the history
  • Loading branch information
georgyturevich committed Feb 24, 2017
1 parent 94de9dc commit 80cf1cb
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 22 deletions.
1 change: 1 addition & 0 deletions Godeps
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ github.com/couchbase/gomemcached a5ea6356f648fec6ab89add00edd09151455b4b2
github.com/couchbase/goutils 5823a0cbaaa9008406021dc5daf80125ea30bba6
github.com/dancannon/gorethink e7cac92ea2bc52638791a021f212145acfedb1fc
github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
github.com/docker/docker 092cba3727bb9b4a2f0e922cd6c0f93ea270e363
github.com/docker/engine-api 8924d6900370b4c7e7984be5adc61f50a80d7537
github.com/docker/go-connections f549a9393d05688dff0992ef3efd8bbe6c628aeb
github.com/docker/go-units 5d2041e26a699eaca682e2ea41c8f891e1060444
Expand Down
83 changes: 61 additions & 22 deletions plugins/inputs/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import (

"golang.org/x/net/context"

"github.com/docker/engine-api/client"
"github.com/docker/engine-api/types"
"github.com/docker/docker/client"
"github.com/docker/docker/api/types"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/inputs"
"runtime"
)

// Docker object
Expand All @@ -36,7 +37,7 @@ type Docker struct {
type DockerClient interface {
Info(ctx context.Context) (types.Info, error)
ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error)
ContainerStats(ctx context.Context, containerID string, stream bool) (io.ReadCloser, error)
ContainerStats(ctx context.Context, containerID string, stream bool) (types.ContainerStats, error)
}

// KB, MB, GB, TB, PB...human friendly
Expand Down Expand Up @@ -210,8 +211,8 @@ func (d *Docker) gatherInfo(acc telegraf.Accumulator) error {
}

func (d *Docker) gatherContainer(
container types.Container,
acc telegraf.Accumulator,
container types.Container,
acc telegraf.Accumulator,
) error {
var v *types.StatsJSON
// Parse container name
Expand Down Expand Up @@ -243,12 +244,12 @@ func (d *Docker) gatherContainer(

ctx, cancel := context.WithTimeout(context.Background(), d.Timeout.Duration)
defer cancel()
r, err := d.client.ContainerStats(ctx, container.ID, false)
cStats, err := d.client.ContainerStats(ctx, container.ID, false)
if err != nil {
return fmt.Errorf("Error getting docker stats: %s", err.Error())
}
defer r.Close()
dec := json.NewDecoder(r)
defer cStats.Body.Close()
dec := json.NewDecoder(cStats.Body)
if err = dec.Decode(&v); err != nil {
if err == io.EOF {
return nil
Expand All @@ -267,12 +268,12 @@ func (d *Docker) gatherContainer(
}

func gatherContainerStats(
stat *types.StatsJSON,
acc telegraf.Accumulator,
tags map[string]string,
id string,
perDevice bool,
total bool,
stat *types.StatsJSON,
acc telegraf.Accumulator,
tags map[string]string,
id string,
perDevice bool,
total bool,
) {
now := stat.Read

Expand Down Expand Up @@ -313,8 +314,29 @@ func gatherContainerStats(
"usage_percent": calculateMemPercent(stat),
"container_id": id,
}

if runtime.GOOS == "windows" {
memfieldsWin := map[string]interface{}{
"usage": stat.MemoryStats.PrivateWorkingSet,
"commitbytes": stat.MemoryStats.Commit,
"commitpeakbytes": stat.MemoryStats.CommitPeak,
"privateworkingset": stat.MemoryStats.PrivateWorkingSet,
// "usage_percent": calculateMemPercent(stat),
"container_id": id,
}
memfields = memfieldsWin
}

acc.AddFields("docker_container_mem", memfields, tags, now)

var cpuPercent = 0.0
if runtime.GOOS == "windows" {
cpuPercent = calculateCPUPercentWindows(stat)
} else {
cpuPercent = calculateCPUPercent(stat)
}


cpufields := map[string]interface{}{
"usage_total": stat.CPUStats.CPUUsage.TotalUsage,
"usage_in_usermode": stat.CPUStats.CPUUsage.UsageInUsermode,
Expand All @@ -323,7 +345,7 @@ func gatherContainerStats(
"throttling_periods": stat.CPUStats.ThrottlingData.Periods,
"throttling_throttled_periods": stat.CPUStats.ThrottlingData.ThrottledPeriods,
"throttling_throttled_time": stat.CPUStats.ThrottlingData.ThrottledTime,
"usage_percent": calculateCPUPercent(stat),
"usage_percent": cpuPercent,
"container_id": id,
}
cputags := copyTags(tags)
Expand Down Expand Up @@ -405,14 +427,31 @@ func calculateCPUPercent(stat *types.StatsJSON) float64 {
return cpuPercent
}

// Copied from docker repo https://github.com/docker/docker/blob/master/cli/command/container/stats_helpers.go#L189
func calculateCPUPercentWindows(v *types.StatsJSON) float64 {
// Max number of 100ns intervals between the previous time read and now
possIntervals := uint64(v.Read.Sub(v.PreRead).Nanoseconds()) // Start with number of ns intervals
possIntervals /= 100 // Convert to number of 100ns intervals
possIntervals *= uint64(v.NumProcs) // Multiple by the number of processors

// Intervals used
intervalsUsed := v.CPUStats.CPUUsage.TotalUsage - v.PreCPUStats.CPUUsage.TotalUsage

// Percentage avoiding divide-by-zero
if possIntervals > 0 {
return float64(intervalsUsed) / float64(possIntervals) * 100.0
}
return 0.00
}

func gatherBlockIOMetrics(
stat *types.StatsJSON,
acc telegraf.Accumulator,
tags map[string]string,
now time.Time,
id string,
perDevice bool,
total bool,
stat *types.StatsJSON,
acc telegraf.Accumulator,
tags map[string]string,
now time.Time,
id string,
perDevice bool,
total bool,
) {
blkioStats := stat.BlkioStats
// Make a map of devices to their block io stats
Expand Down

0 comments on commit 80cf1cb

Please sign in to comment.