diff --git a/plugins/inputs/docker/README.md b/plugins/inputs/docker/README.md index 9aea54c07..fa662ca80 100644 --- a/plugins/inputs/docker/README.md +++ b/plugins/inputs/docker/README.md @@ -22,16 +22,8 @@ for the stat structure can be found endpoint = "unix:///var/run/docker.sock" # Only collect metrics for these containers, collect all if empty container_names = [] - calculate_percentages = false ``` -### Calculate Percentages - -Optionally percentages can be calculated for cpu and memory usage. This uses -the same calculation as the 'docker stats' command line tool. Set this option -to 'true' to enable this feature. - - ### Measurements & Fields: Every effort was made to preserve the names based on the JSON response from the diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index 0812e340a..60abf71d1 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -14,9 +14,8 @@ import ( ) type Docker struct { - Endpoint string - ContainerNames []string - CalculatePercentages bool + Endpoint string + ContainerNames []string client *docker.Client } @@ -28,8 +27,6 @@ var sampleConfig = ` endpoint = "unix:///var/run/docker.sock" ### Only collect metrics for these containers, collect all if empty container_names = [] - # Add calculated percentages for mem and cpu, as per 'docker stats' command - calculate_percentages = false ` func (d *Docker) Description() string { @@ -135,7 +132,7 @@ func (d *Docker) gatherContainer( tags[k] = v } - gatherContainerStats(stat, acc, tags, d.CalculatePercentages) + gatherContainerStats(stat, acc, tags) return nil } @@ -144,7 +141,6 @@ func gatherContainerStats( stat *docker.Stats, acc telegraf.Accumulator, tags map[string]string, - calculate_percentages bool, ) { now := stat.Read @@ -182,9 +178,7 @@ func gatherContainerStats( "pgfault": stat.MemoryStats.Stats.Pgfault, "inactive_file": stat.MemoryStats.Stats.InactiveFile, "total_pgpgin": stat.MemoryStats.Stats.TotalPgpgin, - } - if calculate_percentages { - memfields["usage_percent"] = float64(stat.MemoryStats.Usage) / float64(stat.MemoryStats.Limit) * 100.0 + "usage_percent": calculateMemPercent(stat), } acc.AddFields("docker_mem", memfields, tags, now) @@ -196,9 +190,7 @@ func gatherContainerStats( "throttling_periods": stat.CPUStats.ThrottlingData.Periods, "throttling_throttled_periods": stat.CPUStats.ThrottlingData.ThrottledPeriods, "throttling_throttled_time": stat.CPUStats.ThrottlingData.ThrottledTime, - } - if calculate_percentages { - cpufields["usage_percent"] = calculateCPUPercent(stat) + "usage_percent": calculateCPUPercent(stat), } cputags := copyTags(tags) cputags["cpu"] = "cpu-total" @@ -230,14 +222,19 @@ func gatherContainerStats( gatherBlockIOMetrics(stat, acc, tags, now) } +func calculateMemPercent(stat *docker.Stats) float64 { + var memPercent = 0.0 + if stat.MemoryStats.Limit > 0 { + memPercent = float64(stat.MemoryStats.Usage) / float64(stat.MemoryStats.Limit) * 100.0 + } + return memPercent +} + func calculateCPUPercent(stat *docker.Stats) float64 { - var ( - cpuPercent = 0.0 - // calculate the change for the cpu usage of the container in between readings - cpuDelta = float64(stat.CPUStats.CPUUsage.TotalUsage) - float64(stat.PreCPUStats.CPUUsage.TotalUsage) - // calculate the change for the entire system between readings - systemDelta = float64(stat.CPUStats.SystemCPUUsage) - float64(stat.PreCPUStats.SystemCPUUsage) - ) + var cpuPercent = 0.0 + // calculate the change for the cpu and system usage of the container in between readings + cpuDelta := float64(stat.CPUStats.CPUUsage.TotalUsage) - float64(stat.PreCPUStats.CPUUsage.TotalUsage) + systemDelta := float64(stat.CPUStats.SystemCPUUsage) - float64(stat.PreCPUStats.SystemCPUUsage) if systemDelta > 0.0 && cpuDelta > 0.0 { cpuPercent = (cpuDelta / systemDelta) * float64(len(stat.CPUStats.CPUUsage.PercpuUsage)) * 100.0 diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index 3e27ea59b..aebe8102e 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -18,7 +18,7 @@ func TestDockerGatherContainerStats(t *testing.T) { "cont_name": "redis", "cont_image": "redis/image", } - gatherContainerStats(stats, &acc, tags, false) + gatherContainerStats(stats, &acc, tags) // test docker_net measurement netfields := map[string]interface{}{ @@ -45,13 +45,58 @@ func TestDockerGatherContainerStats(t *testing.T) { acc.AssertContainsTaggedFields(t, "docker_blkio", blkiofields, blkiotags) // test docker_mem measurement - memfields := sample_mem_fields() + memfields := map[string]interface{}{ + "max_usage": uint64(1001), + "usage": uint64(1111), + "fail_count": uint64(1), + "limit": uint64(2000), + "total_pgmafault": uint64(0), + "cache": uint64(0), + "mapped_file": uint64(0), + "total_inactive_file": uint64(0), + "pgpgout": uint64(0), + "rss": uint64(0), + "total_mapped_file": uint64(0), + "writeback": uint64(0), + "unevictable": uint64(0), + "pgpgin": uint64(0), + "total_unevictable": uint64(0), + "pgmajfault": uint64(0), + "total_rss": uint64(44), + "total_rss_huge": uint64(444), + "total_writeback": uint64(55), + "total_inactive_anon": uint64(0), + "rss_huge": uint64(0), + "hierarchical_memory_limit": uint64(0), + "total_pgfault": uint64(0), + "total_active_file": uint64(0), + "active_anon": uint64(0), + "total_active_anon": uint64(0), + "total_pgpgout": uint64(0), + "total_cache": uint64(0), + "inactive_anon": uint64(0), + "active_file": uint64(1), + "pgfault": uint64(2), + "inactive_file": uint64(3), + "total_pgpgin": uint64(4), + "usage_percent": float64(55.55), + } + acc.AssertContainsTaggedFields(t, "docker_mem", memfields, tags) // test docker_cpu measurement cputags := copyTags(tags) cputags["cpu"] = "cpu-total" - cpufields := sample_cpu_fields() + cpufields := map[string]interface{}{ + "usage_total": uint64(500), + "usage_in_usermode": uint64(100), + "usage_in_kernelmode": uint64(200), + "usage_system": uint64(100), + "throttling_periods": uint64(1), + "throttling_throttled_periods": uint64(0), + "throttling_throttled_time": uint64(0), + "usage_percent": float64(400.0), + } acc.AssertContainsTaggedFields(t, "docker_cpu", cpufields, cputags) cputags["cpu"] = "cpu0" @@ -67,30 +112,6 @@ func TestDockerGatherContainerStats(t *testing.T) { acc.AssertContainsTaggedFields(t, "docker_cpu", cpu1fields, cputags) } -func TestDockerGatherContainerPercentages(t *testing.T) { - var acc testutil.Accumulator - stats := testStats() - - tags := map[string]string{ - "cont_id": "foobarbaz", - "cont_name": "redis", - "cont_image": "redis/image", - } - gatherContainerStats(stats, &acc, tags, true) - - // test docker_mem measurement - memfields := sample_mem_fields() - memfields["usage_percent"] = 55.55 - acc.AssertContainsTaggedFields(t, "docker_mem", memfields, tags) - - // test docker_cpu measurement - cputags := copyTags(tags) - cputags["cpu"] = "cpu-total" - cpufields := sample_cpu_fields() - cpufields["usage_percent"] = 400.0 - acc.AssertContainsTaggedFields(t, "docker_cpu", cpufields, cputags) -} - func testStats() *docker.Stats { stats := &docker.Stats{ Read: time.Now(), @@ -173,58 +194,3 @@ func testStats() *docker.Stats { return stats } - -func sample_mem_fields() map[string]interface{} { - - memfields := map[string]interface{}{ - "max_usage": uint64(1001), - "usage": uint64(1111), - "fail_count": uint64(1), - "limit": uint64(2000), - "total_pgmafault": uint64(0), - "cache": uint64(0), - "mapped_file": uint64(0), - "total_inactive_file": uint64(0), - "pgpgout": uint64(0), - "rss": uint64(0), - "total_mapped_file": uint64(0), - "writeback": uint64(0), - "unevictable": uint64(0), - "pgpgin": uint64(0), - "total_unevictable": uint64(0), - "pgmajfault": uint64(0), - "total_rss": uint64(44), - "total_rss_huge": uint64(444), - "total_writeback": uint64(55), - "total_inactive_anon": uint64(0), - "rss_huge": uint64(0), - "hierarchical_memory_limit": uint64(0), - "total_pgfault": uint64(0), - "total_active_file": uint64(0), - "active_anon": uint64(0), - "total_active_anon": uint64(0), - "total_pgpgout": uint64(0), - "total_cache": uint64(0), - "inactive_anon": uint64(0), - "active_file": uint64(1), - "pgfault": uint64(2), - "inactive_file": uint64(3), - "total_pgpgin": uint64(4), - } - - return memfields -} - -func sample_cpu_fields() map[string]interface{} { - - cpufields := map[string]interface{}{ - "usage_total": uint64(500), - "usage_in_usermode": uint64(100), - "usage_in_kernelmode": uint64(200), - "usage_system": uint64(100), - "throttling_periods": uint64(1), - "throttling_throttled_periods": uint64(0), - "throttling_throttled_time": uint64(0), - } - return cpufields -}