diff --git a/cmd/cadvisor.go b/cmd/cadvisor.go index ade2d22829..56f5128bf2 100644 --- a/cmd/cadvisor.go +++ b/cmd/cadvisor.go @@ -88,7 +88,7 @@ var ( container.ProcessSchedulerMetrics: struct{}{}, container.ProcessMetrics: struct{}{}, container.HugetlbUsageMetrics: struct{}{}, - container.ReferencedMemoryMetrics: struct{}{}, + container.SmapsMemoryMetrics: struct{}{}, container.CPUTopologyMetrics: struct{}{}, container.ResctrlMetrics: struct{}{}, }} @@ -107,7 +107,7 @@ var ( container.ProcessSchedulerMetrics: struct{}{}, container.ProcessMetrics: struct{}{}, container.HugetlbUsageMetrics: struct{}{}, - container.ReferencedMemoryMetrics: struct{}{}, + container.SmapsMemoryMetrics: struct{}{}, container.CPUTopologyMetrics: struct{}{}, container.ResctrlMetrics: struct{}{}, } @@ -141,7 +141,7 @@ func (ml *metricSetValue) Set(value string) error { } func init() { - flag.Var(&ignoreMetrics, "disable_metrics", "comma-separated list of `metrics` to be disabled. Options are 'accelerator', 'cpu_topology','disk', 'diskIO', 'memory_numa', 'network', 'tcp', 'udp', 'percpu', 'sched', 'process', 'hugetlb', 'referenced_memory', 'resctrl'.") + flag.Var(&ignoreMetrics, "disable_metrics", "comma-separated list of `metrics` to be disabled. Options are 'accelerator', 'cpu_topology','disk', 'diskIO', 'memory_numa', 'network', 'tcp', 'udp', 'percpu', 'sched', 'process', 'hugetlb', 'resctrl', 'smaps_memory'.") // Default logging verbosity to V(2) flag.Set("v", "2") diff --git a/cmd/cadvisor_test.go b/cmd/cadvisor_test.go index 093a348118..111ba2393e 100644 --- a/cmd/cadvisor_test.go +++ b/cmd/cadvisor_test.go @@ -40,10 +40,10 @@ func TestUdpMetricsAreDisabledByDefault(t *testing.T) { assert.True(t, ignoreMetrics.Has(container.NetworkUdpUsageMetrics)) } -func TestReferencedMemoryMetricsIsDisabledByDefault(t *testing.T) { - assert.True(t, ignoreMetrics.Has(container.ReferencedMemoryMetrics)) +func TestSmapsMemoryMetricsIsDisabledByDefault(t *testing.T) { + assert.True(t, ignoreMetrics.Has(container.SmapsMemoryMetrics)) flag.Parse() - assert.True(t, ignoreMetrics.Has(container.ReferencedMemoryMetrics)) + assert.True(t, ignoreMetrics.Has(container.SmapsMemoryMetrics)) } func TestCPUTopologyMetricsAreDisabledByDefault(t *testing.T) { @@ -105,7 +105,7 @@ func TestToIncludedMetrics(t *testing.T) { container.AppMetrics: struct{}{}, container.HugetlbUsageMetrics: struct{}{}, container.PerfMetrics: struct{}{}, - container.ReferencedMemoryMetrics: struct{}{}, + container.SmapsMemoryMetrics: struct{}{}, container.CPUTopologyMetrics: struct{}{}, container.ResctrlMetrics: struct{}{}, }, diff --git a/cmd/go.sum b/cmd/go.sum index 5c8be853b4..2e93b9bc6c 100644 --- a/cmd/go.sum +++ b/cmd/go.sum @@ -38,8 +38,8 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.15 h1:qkLXKzb1QoVatRyd/YlXZ/Kg0m5K3SPuoD82jjSOaBc= -github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Rican7/retry v0.1.1-0.20160712041035-272ad122d6e5 h1:6olZmdYuK84eO0PeCQX1iy2EFWlOl8G+JNBi4vFmcU8= github.com/Rican7/retry v0.1.1-0.20160712041035-272ad122d6e5/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= github.com/SeanDolphin/bqschema v0.0.0-20150424181127-f92a08f515e1 h1:4EBKNUkI0tKxZb75f41jFGQQBPG4A/qbbgmgJ1MTTvw= @@ -110,6 +110,8 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -118,8 +120,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible h1:dvc1KSkIYTVjZgHf/CTC2diTYC8PzhaA5sFISRfNVrE= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible h1:SiUATuP//KecDjpOK2tvZJgeScYAklvyjfK8JZlU6fo= -github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.0+incompatible h1:4g8Xjho+7quMwzsTrhtrWpdQU9UTc2rX57A3iALaBmE= +github.com/docker/docker v20.10.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -334,6 +336,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/sys/mountinfo v0.1.3 h1:KIrhRO14+AkwKvG/g2yIpNMOUVZ02xNhOw8KY1WsLOI= github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -460,6 +464,7 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -646,6 +651,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -682,6 +688,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -844,8 +851,9 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/cmd/internal/storage/influxdb/influxdb.go b/cmd/internal/storage/influxdb/influxdb.go index f23630d5ca..cc8610e4c8 100644 --- a/cmd/internal/storage/influxdb/influxdb.go +++ b/cmd/internal/storage/influxdb/influxdb.go @@ -94,14 +94,14 @@ const ( setHugetlbFailcnt = "hugetlb_failcnt" // Perf statistics serPerfStat = "perf_stat" - // Referenced memory - serReferencedMemory = "referenced_memory" // Resctrl - Total memory bandwidth serResctrlMemoryBandwidthTotal = "resctrl_memory_bandwidth_total" // Resctrl - Local memory bandwidth serResctrlMemoryBandwidthLocal = "resctrl_memory_bandwidth_local" // Resctrl - Last level cache usage serResctrlLLCOccupancy = "resctrl_llc_occupancy" + // Smaps memory prefix + serSmapsPrefix = "smaps_" ) func new() (storage.StorageDriver, error) { @@ -230,8 +230,10 @@ func (s *influxdbStorage) containerStatsToPoints( points = append(points, makePoint(serTxBytes, stats.Network.TxBytes)) points = append(points, makePoint(serTxErrors, stats.Network.TxErrors)) - // Referenced Memory - points = append(points, makePoint(serReferencedMemory, stats.ReferencedMemory)) + // Smaps Memory + for k, v := range stats.SmapsMemory { + points = append(points, makePoint(serSmapsPrefix+k, v)) + } s.tagPoints(cInfo, stats, points) diff --git a/cmd/internal/storage/influxdb/influxdb_test.go b/cmd/internal/storage/influxdb/influxdb_test.go index 9e8a58f943..3f88125ba2 100644 --- a/cmd/internal/storage/influxdb/influxdb_test.go +++ b/cmd/internal/storage/influxdb/influxdb_test.go @@ -231,7 +231,7 @@ func TestContainerStatsToPoints(t *testing.T) { // Then assert.NotEmpty(t, points) - assert.Len(t, points, 34+len(stats.Cpu.Usage.PerCpu)) + assert.Len(t, points, 52+len(stats.Cpu.Usage.PerCpu)) // CPU stats assertContainsPointWithValue(t, points, serCpuUsageTotal, stats.Cpu.Usage.Total) @@ -276,7 +276,9 @@ func TestContainerStatsToPoints(t *testing.T) { } // Reference memory - assertContainsPointWithValue(t, points, serReferencedMemory, stats.ReferencedMemory) + for k, v := range stats.SmapsMemory { + assertContainsPointWithValue(t, points, serSmapsPrefix+k, v) + } // Resource Control stats - memory bandwidth for _, rdtMemoryBandwidth := range stats.Resctrl.MemoryBandwidth { @@ -359,8 +361,28 @@ func createTestStats() (*info.ContainerInfo, *info.ContainerStats) { "1GB": {Usage: 1234, MaxUsage: 5678, Failcnt: 9}, "2GB": {Usage: 9876, MaxUsage: 5432, Failcnt: 1}, }, - ReferencedMemory: 12345, - PerfStats: []info.PerfStat{{Cpu: 1, Name: "cycles", ScalingRatio: 1.5, Value: 4589}}, + SmapsMemory: map[string]uint64{ + "AnonHugePages": 1, + "Anonymous": 2, + "KernelPageSize": 3, + "LazyFree": 4, + "Locked": 5, + "MMUPageSize": 6, + "Private_Clean": 7, + "Private_Dirty": 8, + "Private_Hugetlb": 9, + "Pss": 10, + "Referenced": 11, + "Rss": 12, + "Shared_Clean": 13, + "Shared_Dirty": 14, + "Shared_Hugetlb": 15, + "ShmemPmdMapped": 16, + "Size": 17, + "Swap": 18, + "SwapPss": 19, + }, + PerfStats: []info.PerfStat{{Cpu: 1, PerfValue: info.PerfValue{Name: "cycles", ScalingRatio: 1.5, Value: 4589}}}, Resctrl: info.ResctrlStats{ MemoryBandwidth: []info.MemoryBandwidthStats{ {TotalBytes: 11234, LocalBytes: 4567}, diff --git a/cmd/internal/storage/statsd/statsd.go b/cmd/internal/storage/statsd/statsd.go index afcc1de0b6..4f9df114eb 100644 --- a/cmd/internal/storage/statsd/statsd.go +++ b/cmd/internal/storage/statsd/statsd.go @@ -83,14 +83,14 @@ const ( setHugetlbFailcnt string = "hugetlb_failcnt" // Perf statistics serPerfStat string = "perf_stat" - // Referenced memory - serReferencedMemory string = "referenced_memory" // Resctrl - Total memory bandwidth serResctrlMemoryBandwidthTotal string = "resctrl_memory_bandwidth_total" // Resctrl - Local memory bandwidth serResctrlMemoryBandwidthLocal string = "resctrl_memory_bandwidth_local" // Resctrl - Last level cache usage serResctrlLLCOccupancy string = "resctrl_llc_occupancy" + // Smaps prefix + serSmaps string = "smaps_" ) func new() (storage.StorageDriver, error) { @@ -126,8 +126,10 @@ func (s *statsdStorage) containerStatsToValues(stats *info.ContainerStats) (seri series[serTxBytes] = stats.Network.TxBytes series[serTxErrors] = stats.Network.TxErrors - // Referenced Memory - series[serReferencedMemory] = stats.ReferencedMemory + // Smaps + for k, v := range stats.SmapsMemory { + series[serSmaps+k] = v + } return series } diff --git a/cmd/internal/storage/stdout/stdout.go b/cmd/internal/storage/stdout/stdout.go index 771d5c9367..163a6442a9 100644 --- a/cmd/internal/storage/stdout/stdout.go +++ b/cmd/internal/storage/stdout/stdout.go @@ -85,14 +85,14 @@ const ( setHugetlbFailcnt string = "hugetlb_failcnt" // Perf statistics serPerfStat string = "perf_stat" - // Referenced memory - serReferencedMemory string = "referenced_memory" // Resctrl - Total memory bandwidth serResctrlMemoryBandwidthTotal string = "resctrl_memory_bandwidth_total" // Resctrl - Local memory bandwidth serResctrlMemoryBandwidthLocal string = "resctrl_memory_bandwidth_local" // Resctrl - Last level cache usage serResctrlLLCOccupancy string = "resctrl_llc_occupancy" + // Smaps series + serSmapsPrefix string = "smaps_" ) func new() (storage.StorageDriver, error) { @@ -131,8 +131,10 @@ func (driver *stdoutStorage) containerStatsToValues(stats *info.ContainerStats) series[serTxBytes] = stats.Network.TxBytes series[serTxErrors] = stats.Network.TxErrors - // Referenced Memory - series[serReferencedMemory] = stats.ReferencedMemory + // Smaps Memory + for k, v := range stats.SmapsMemory { + series[serSmapsPrefix+k] = v + } return series } diff --git a/container/factory.go b/container/factory.go index 652070b1b4..64e5996ea5 100644 --- a/container/factory.go +++ b/container/factory.go @@ -60,7 +60,7 @@ const ( ProcessMetrics MetricKind = "process" HugetlbUsageMetrics MetricKind = "hugetlb" PerfMetrics MetricKind = "perf_event" - ReferencedMemoryMetrics MetricKind = "referenced_memory" + SmapsMemoryMetrics MetricKind = "smaps_memory" CPUTopologyMetrics MetricKind = "cpu_topology" ResctrlMetrics MetricKind = "resctrl" ) @@ -84,7 +84,7 @@ var AllMetrics = MetricSet{ AppMetrics: struct{}{}, HugetlbUsageMetrics: struct{}{}, PerfMetrics: struct{}{}, - ReferencedMemoryMetrics: struct{}{}, + SmapsMemoryMetrics: struct{}{}, CPUTopologyMetrics: struct{}{}, ResctrlMetrics: struct{}{}, } diff --git a/container/libcontainer/handler.go b/container/libcontainer/handler.go index 1094b10392..a87d315307 100644 --- a/container/libcontainer/handler.go +++ b/container/libcontainer/handler.go @@ -47,7 +47,7 @@ var ( smapsFilePathPattern = "/proc/%d/smaps" clearRefsFilePathPattern = "/proc/%d/clear_refs" - referencedRegexp = regexp.MustCompile(`Referenced:\s*([0-9]+)\s*kB`) + smapsRegexp = regexp.MustCompile(`(?m)^(.+):\s*([0-9]+)\s*kB$`) ) type Handler struct { @@ -104,13 +104,13 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) { } } - if h.includedMetrics.Has(container.ReferencedMemoryMetrics) { + if h.includedMetrics.Has(container.SmapsMemoryMetrics) { h.cycles++ pids, err := h.cgroupManager.GetPids() if err != nil { klog.V(4).Infof("Could not get PIDs for container %d: %v", h.pid, err) } else { - stats.ReferencedMemory, err = referencedBytesStat(pids, h.cycles, *referencedResetInterval) + stats.SmapsMemory, err = smapsStat(pids, h.cycles, *referencedResetInterval) if err != nil { klog.V(4).Infof("Unable to get referenced bytes: %v", err) } @@ -358,23 +358,23 @@ func schedulerStatsFromProcs(rootFs string, pids []int, pidMetricsCache map[int] return schedstats, nil } -// referencedBytesStat gets and clears referenced bytes +// smapsStat gets smaps metrics and clears referenced bytes // see: https://github.com/brendangregg/wss#wsspl-referenced-page-flag -func referencedBytesStat(pids []int, cycles uint64, resetInterval uint64) (uint64, error) { - referencedKBytes, err := getReferencedKBytes(pids) +func smapsStat(pids []int, cycles uint64, resetInterval uint64) (map[string]uint64, error) { + smapsBytes, err := getSmapsBytes(pids) if err != nil { - return uint64(0), err + return nil, err } err = clearReferencedBytes(pids, cycles, resetInterval) if err != nil { - return uint64(0), err + return nil, err } - return referencedKBytes * 1024, nil + return smapsBytes, nil } -func getReferencedKBytes(pids []int) (uint64, error) { - referencedKBytes := uint64(0) +func getSmapsBytes(pids []int) (map[string]uint64, error) { + smapsBytes := map[string]uint64{} readSmapsContent := false foundMatch := false for _, pid := range pids { @@ -385,26 +385,27 @@ func getReferencedKBytes(pids []int) (uint64, error) { if os.IsNotExist(err) { continue //smaps file does not exists for all PIDs } - return 0, err + return nil, err } readSmapsContent = true - allMatches := referencedRegexp.FindAllSubmatch(smapsContent, -1) + allMatches := smapsRegexp.FindAllSubmatch(smapsContent, -1) if len(allMatches) == 0 { - klog.V(5).Infof("Not found any information about referenced bytes in %s file", smapsFilePath) + klog.V(5).Infof("Not found any smaps information in %s file", smapsFilePath) continue // referenced bytes may not exist in smaps file } for _, matches := range allMatches { - if len(matches) != 2 { - return 0, fmt.Errorf("failed to match regexp in output: %s", string(smapsContent)) + if len(matches) != 3 { + return nil, fmt.Errorf("failed to match regexp in output: %s", string(smapsContent)) } foundMatch = true - referenced, err := strconv.ParseUint(string(matches[1]), 10, 64) + key := string(matches[1]) + kbytes, err := strconv.ParseUint(string(matches[2]), 10, 64) if err != nil { - return 0, err + return nil, err } - referencedKBytes += referenced + smapsBytes[key] = smapsBytes[key] + kbytes*1024 } } @@ -412,10 +413,10 @@ func getReferencedKBytes(pids []int) (uint64, error) { if !readSmapsContent { klog.Warningf("Cannot read smaps files for any PID from %s", "CONTAINER") } else if !foundMatch { - klog.Warningf("Not found any information about referenced bytes in smaps files for any PID from %s", "CONTAINER") + klog.Warningf("Not found any information in smaps files for any PID from %s", "CONTAINER") } } - return referencedKBytes, nil + return smapsBytes, nil } func clearReferencedBytes(pids []int, cycles uint64, resetInterval uint64) error { diff --git a/container/libcontainer/handler_test.go b/container/libcontainer/handler_test.go index 21b2ff473b..a56b1952df 100644 --- a/container/libcontainer/handler_test.go +++ b/container/libcontainer/handler_test.go @@ -24,6 +24,28 @@ import ( "github.com/stretchr/testify/assert" ) +var expectedSmaps = map[string]uint64{ + "AnonHugePages": 0x0, + "Anonymous": 0x7000, + "KernelPageSize": 0x6000, + "LazyFree": 0x0, + "Locked": 0x0, + "MMUPageSize": 0x6000, + "Private_Clean": 0x63000, + "Private_Dirty": 0x7000, + "Private_Hugetlb": 0x0, + "Pss": 0x6a000, + "Referenced": 0x68000, + "Rss": 0x6a000, + "Shared_Clean": 0x0, + "Shared_Dirty": 0x0, + "Shared_Hugetlb": 0x0, + "ShmemPmdMapped": 0x0, + "Size": 0x8a000, + "Swap": 0x0, + "SwapPss": 0x0, +} + func TestScanInterfaceStats(t *testing.T) { stats, err := scanInterfaceStats("testdata/procnetdev") if err != nil { @@ -217,15 +239,15 @@ func TestParseLimitsFile(t *testing.T) { } } -func TestReferencedBytesStat(t *testing.T) { +func TestSmapsStat(t *testing.T) { //overwrite package variables smapsFilePathPattern = "testdata/smaps%d" clearRefsFilePathPattern = "testdata/clear_refs%d" pids := []int{4, 6, 8} - stat, err := referencedBytesStat(pids, 1, 3) + stat, err := smapsStat(pids, 1, 3) assert.Nil(t, err) - assert.Equal(t, uint64(416*1024), stat) + assert.Equal(t, expectedSmaps, stat) clearRefsFiles := []string{ "testdata/clear_refs4", @@ -238,15 +260,15 @@ func TestReferencedBytesStat(t *testing.T) { assert.Equal(t, "0\n", getFileContent(t, clearRefsFiles[2])) } -func TestReferencedBytesStatWhenNeverCleared(t *testing.T) { +func TestSmapsStatWhenNeverCleared(t *testing.T) { //overwrite package variables smapsFilePathPattern = "testdata/smaps%d" clearRefsFilePathPattern = "testdata/clear_refs%d" pids := []int{4, 6, 8} - stat, err := referencedBytesStat(pids, 1, 0) + stat, err := smapsStat(pids, 1, 0) assert.Nil(t, err) - assert.Equal(t, uint64(416*1024), stat) + assert.Equal(t, expectedSmaps, stat) clearRefsFiles := []string{ "testdata/clear_refs4", @@ -259,15 +281,15 @@ func TestReferencedBytesStatWhenNeverCleared(t *testing.T) { assert.Equal(t, "0\n", getFileContent(t, clearRefsFiles[2])) } -func TestReferencedBytesStatWhenResetIsNeeded(t *testing.T) { +func TestSmapsStatWhenResetIsNeeded(t *testing.T) { //overwrite package variables smapsFilePathPattern = "testdata/smaps%d" clearRefsFilePathPattern = "testdata/clear_refs%d" pids := []int{4, 6, 8} - stat, err := referencedBytesStat(pids, 1, 1) + stat, err := smapsStat(pids, 1, 1) assert.Nil(t, err) - assert.Equal(t, uint64(416*1024), stat) + assert.Equal(t, expectedSmaps, stat) clearRefsFiles := []string{ "testdata/clear_refs4", @@ -282,16 +304,6 @@ func TestReferencedBytesStatWhenResetIsNeeded(t *testing.T) { clearTestData(t, clearRefsFiles) } -func TestGetReferencedKBytesWhenSmapsMissing(t *testing.T) { - //overwrite package variable - smapsFilePathPattern = "testdata/smaps%d" - - pids := []int{10} - referenced, err := getReferencedKBytes(pids) - assert.Nil(t, err) - assert.Equal(t, uint64(0), referenced) -} - func TestClearReferencedBytesWhenClearRefsMissing(t *testing.T) { //overwrite package variable clearRefsFilePathPattern = "testdata/clear_refs%d" diff --git a/go.mod b/go.mod index 03ce3dab13..35f3e5b72e 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,14 @@ go 1.13 require ( cloud.google.com/go v0.54.0 - github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect - github.com/Microsoft/go-winio v0.4.15 // indirect + github.com/Microsoft/go-winio v0.4.16 // indirect github.com/aws/aws-sdk-go v1.35.24 github.com/blang/semver v3.5.1+incompatible github.com/containerd/containerd v1.4.3 github.com/containerd/ttrpc v1.0.2 // indirect github.com/containerd/typeurl v1.0.1 github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible // indirect - github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible + github.com/docker/docker v20.10.0+incompatible github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.4.0 github.com/euank/go-kmsg-parser v2.0.0+incompatible @@ -26,6 +25,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989 github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible + github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.1 // indirect @@ -46,7 +46,7 @@ require ( google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect google.golang.org/grpc v1.27.1 google.golang.org/protobuf v1.25.0 // indirect - gotest.tools v2.2.0+incompatible // indirect + gotest.tools/v3 v3.0.3 // indirect k8s.io/klog/v2 v2.2.0 k8s.io/utils v0.0.0-20201110183641-67b214c5f920 ) diff --git a/go.sum b/go.sum index a826ff3010..43f5572d0c 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7O github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Microsoft/go-winio v0.4.15 h1:qkLXKzb1QoVatRyd/YlXZ/Kg0m5K3SPuoD82jjSOaBc= -github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -65,6 +65,8 @@ github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4 github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -72,8 +74,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible h1:dvc1KSkIYTVjZgHf/CTC2diTYC8PzhaA5sFISRfNVrE= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible h1:SiUATuP//KecDjpOK2tvZJgeScYAklvyjfK8JZlU6fo= -github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.0+incompatible h1:4g8Xjho+7quMwzsTrhtrWpdQU9UTc2rX57A3iALaBmE= +github.com/docker/docker v20.10.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -191,6 +193,8 @@ github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1 github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/moby/sys/mountinfo v0.1.3 h1:KIrhRO14+AkwKvG/g2yIpNMOUVZ02xNhOw8KY1WsLOI= github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -253,6 +257,7 @@ github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -382,6 +387,7 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 h1:Qo9oJ566/Sq7N4hrGftVXs8GI2CXBCuOd4S2wHE/e0M= golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -412,6 +418,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -514,8 +521,9 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/info/v1/container.go b/info/v1/container.go index 08cff3940f..2a9132f1b5 100644 --- a/info/v1/container.go +++ b/info/v1/container.go @@ -952,11 +952,11 @@ type ContainerStats struct { // Applies only for root container. PerfUncoreStats []PerfUncoreStat `json:"perf_uncore_stats,omitempty"` - // Referenced memory - ReferencedMemory uint64 `json:"referenced_memory,omitempty"` - // Resource Control (resctrl) statistics Resctrl ResctrlStats `json:"resctrl,omitempty"` + + // Referenced memory + SmapsMemory map[string]uint64 `json:"smaps_memory,omitempty"` } func timeEq(t1, t2 time.Time, tolerance time.Duration) bool { diff --git a/info/v1/test/datagen.go b/info/v1/test/datagen.go index af6ec180ed..925d869287 100644 --- a/info/v1/test/datagen.go +++ b/info/v1/test/datagen.go @@ -47,7 +47,12 @@ func GenerateRandomStats(numStats, numCores int, duration time.Duration) []*info stats.Memory.Cache = uint64(rand.Int63n(4096)) stats.Memory.RSS = uint64(rand.Int63n(4096)) stats.Memory.MappedFile = uint64(rand.Int63n(4096)) - stats.ReferencedMemory = uint64(rand.Int63n(1000)) + stats.SmapsMemory = map[string]uint64{} + for _, t := range []string{"Size", "KernelPageSize", "MMUPageSize", "Rss", "Pss", "Shared_Clean", "Shared_Dirty", + "Private_Clean", "Private_Dirty", "Referenced", "Anonymous", "LazyFree", "AnonHugePages", "ShmemPmdMapped", + "Shared_Hugetlb", "Private_Hugetlb", "Swap", "SwapPss", "Locked"} { + stats.SmapsMemory[t] = uint64(rand.Int63n(1000)) + } ret[i] = stats } return ret diff --git a/info/v2/container.go b/info/v2/container.go index a80fb5598d..4423c8ffa1 100644 --- a/info/v2/container.go +++ b/info/v2/container.go @@ -142,10 +142,10 @@ type DeprecatedContainerStats struct { // Statistics originating from perf uncore events. // Applies only for root container. PerfUncoreStats []v1.PerfUncoreStat `json:"perf_uncore_stats,omitempty"` - // Referenced memory - ReferencedMemory uint64 `json:"referenced_memory,omitempty"` // Resource Control (resctrl) statistics Resctrl v1.ResctrlStats `json:"resctrl,omitempty"` + // Smaps memory + SmapsMemory map[string]uint64 `json:"smaps_memory,omitempty"` } type ContainerStats struct { @@ -179,10 +179,10 @@ type ContainerStats struct { // Statistics originating from perf uncore events. // Applies only for root container. PerfUncoreStats []v1.PerfUncoreStat `json:"perf_uncore_stats,omitempty"` - // Referenced memory - ReferencedMemory uint64 `json:"referenced_memory,omitempty"` // Resource Control (resctrl) statistics Resctrl v1.ResctrlStats `json:"resctrl,omitempty"` + // Smaps memory statistics + SmapsMemory map[string]uint64 `json:"smaps,omitempty"` } type Percentiles struct { diff --git a/info/v2/conversion.go b/info/v2/conversion.go index f9a95a0350..515fa81a60 100644 --- a/info/v2/conversion.go +++ b/info/v2/conversion.go @@ -101,8 +101,8 @@ func ContainerStatsFromV1(containerName string, spec *v1.ContainerSpec, stats [] var last *v1.ContainerStats for _, val := range stats { stat := &ContainerStats{ - Timestamp: val.Timestamp, - ReferencedMemory: val.ReferencedMemory, + Timestamp: val.Timestamp, + SmapsMemory: val.SmapsMemory, } if spec.HasCpu { stat.Cpu = &val.Cpu @@ -180,7 +180,7 @@ func DeprecatedStatsFromV1(cont *v1.ContainerInfo) []DeprecatedContainerStats { HasFilesystem: cont.Spec.HasFilesystem, HasDiskIo: cont.Spec.HasDiskIo, HasCustomMetrics: cont.Spec.HasCustomMetrics, - ReferencedMemory: val.ReferencedMemory, + SmapsMemory: val.SmapsMemory, } if stat.HasCpu { stat.Cpu = val.Cpu diff --git a/info/v2/conversion_test.go b/info/v2/conversion_test.go index bf781cbe05..82395ce1d5 100644 --- a/info/v2/conversion_test.go +++ b/info/v2/conversion_test.go @@ -233,7 +233,6 @@ func TestContainerStatsFromV1(t *testing.T) { PMU: "17", }, }, - ReferencedMemory: uint64(1234), Resctrl: v1.ResctrlStats{ MemoryBandwidth: []v1.MemoryBandwidthStats{ { @@ -254,6 +253,27 @@ func TestContainerStatsFromV1(t *testing.T) { }, }, }, + SmapsMemory: map[string]uint64{ + "AnonHugePages": 1, + "Anonymous": 2, + "KernelPageSize": 3, + "LazyFree": 4, + "Locked": 5, + "MMUPageSize": 6, + "Private_Clean": 7, + "Private_Dirty": 8, + "Private_Hugetlb": 9, + "Pss": 10, + "Referenced": 11, + "Rss": 12, + "Shared_Clean": 13, + "Shared_Dirty": 14, + "Shared_Hugetlb": 15, + "ShmemPmdMapped": 16, + "Size": 17, + "Swap": 18, + "SwapPss": 19, + }, } expectedV2Stats := ContainerStats{ Timestamp: timestamp, @@ -270,11 +290,11 @@ func TestContainerStatsFromV1(t *testing.T) { BaseUsageBytes: &v1Stats.Filesystem[0].BaseUsage, InodeUsage: &v1Stats.Filesystem[0].Inodes, }, - Accelerators: v1Stats.Accelerators, - PerfStats: v1Stats.PerfStats, - PerfUncoreStats: v1Stats.PerfUncoreStats, - ReferencedMemory: v1Stats.ReferencedMemory, - Resctrl: v1Stats.Resctrl, + Accelerators: v1Stats.Accelerators, + PerfStats: v1Stats.PerfStats, + PerfUncoreStats: v1Stats.PerfUncoreStats, + Resctrl: v1Stats.Resctrl, + SmapsMemory: v1Stats.SmapsMemory, } v2Stats := ContainerStatsFromV1("test", &v1Spec, []*v1.ContainerStats{&v1Stats}) diff --git a/metrics/prometheus.go b/metrics/prometheus.go index 1064e045a2..af25788225 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -1655,14 +1655,24 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri }, }...) } - if includedMetrics.Has(container.ReferencedMemoryMetrics) { + if includedMetrics.Has(container.SmapsMemoryMetrics) { c.containerMetrics = append(c.containerMetrics, []containerMetric{ { - name: "container_referenced_bytes", - help: "Container referenced bytes during last measurements cycle", - valueType: prometheus.GaugeValue, + name: "container_smaps_bytes", + help: "Container smaps statistics, for type=referenced during last measurements cycle", + valueType: prometheus.GaugeValue, + extraLabels: []string{"type"}, getValues: func(s *info.ContainerStats) metricValues { - return metricValues{{value: float64(s.ReferencedMemory), timestamp: s.Timestamp}} + types := []string{"Size", "KernelPageSize", "MMUPageSize", "Rss", "Pss", "Shared_Clean", "Shared_Dirty", "Private_Clean", "Private_Dirty", "Referenced", "Anonymous", "LazyFree", "AnonHugePages", "ShmemPmdMapped", "Shared_Hugetlb", "Private_Hugetlb", "Swap", "SwapPss", "Locked"} + metrics := make(metricValues, 0, len(types)) + for _, t := range types { + metrics = append(metrics, metricValue{ + value: float64(s.SmapsMemory[t]), + labels: []string{t}, + timestamp: s.Timestamp, + }) + } + return metrics }, }, }...) diff --git a/metrics/prometheus_fake.go b/metrics/prometheus_fake.go index 6368c0b75e..6faba5cc09 100644 --- a/metrics/prometheus_fake.go +++ b/metrics/prometheus_fake.go @@ -687,7 +687,27 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req PMU: "uncore_imc_0", }, }, - ReferencedMemory: 1234, + SmapsMemory: map[string]uint64{ + "AnonHugePages": 1, + "Anonymous": 2, + "KernelPageSize": 3, + "LazyFree": 4, + "Locked": 5, + "MMUPageSize": 6, + "Private_Clean": 7, + "Private_Dirty": 8, + "Private_Hugetlb": 9, + "Pss": 10, + "Referenced": 11, + "Rss": 12, + "Shared_Clean": 13, + "Shared_Dirty": 14, + "Shared_Hugetlb": 15, + "ShmemPmdMapped": 16, + "Size": 17, + "Swap": 18, + "SwapPss": 19, + }, Resctrl: info.ResctrlStats{ MemoryBandwidth: []info.MemoryBandwidthStats{ { diff --git a/metrics/testdata/prometheus_metrics b/metrics/testdata/prometheus_metrics index d8ba128f84..1ff9a23fb3 100644 --- a/metrics/testdata/prometheus_metrics +++ b/metrics/testdata/prometheus_metrics @@ -364,12 +364,30 @@ container_perf_uncore_events_scaling_ratio{container_env_foo_env="prod",containe # HELP container_processes Number of processes running inside the container. # TYPE container_processes gauge container_processes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1 1395066363000 -# HELP container_referenced_bytes Container referenced bytes during last measurements cycle -# TYPE container_referenced_bytes gauge -container_referenced_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1234 1395066363000 # HELP container_scrape_error 1 if there was an error while getting container metrics, 0 otherwise # TYPE container_scrape_error gauge container_scrape_error 0 +# HELP container_smaps_bytes Container smaps statistics, for type=referenced during last measurements cycle +# TYPE container_smaps_bytes gauge +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="AnonHugePages",zone_name="hello"} 1 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Anonymous",zone_name="hello"} 2 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="KernelPageSize",zone_name="hello"} 3 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="LazyFree",zone_name="hello"} 4 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Locked",zone_name="hello"} 5 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="MMUPageSize",zone_name="hello"} 6 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Private_Clean",zone_name="hello"} 7 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Private_Dirty",zone_name="hello"} 8 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Private_Hugetlb",zone_name="hello"} 9 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Pss",zone_name="hello"} 10 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Referenced",zone_name="hello"} 11 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Rss",zone_name="hello"} 12 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Shared_Clean",zone_name="hello"} 13 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Shared_Dirty",zone_name="hello"} 14 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Shared_Hugetlb",zone_name="hello"} 15 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="ShmemPmdMapped",zone_name="hello"} 16 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Size",zone_name="hello"} 17 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="Swap",zone_name="hello"} 18 1395066363000 +container_smaps_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",type="SwapPss",zone_name="hello"} 19 1395066363000 # HELP container_sockets Number of open sockets for the container. # TYPE container_sockets gauge container_sockets{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 3 1395066363000