From 290786dcf37e47195f0877c37c09f5ed6d99ed6d Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 21 Feb 2026 20:29:58 +0000 Subject: [PATCH 01/26] fix: container_fs metrics {device} has no label or info-metric to associate it with a volumeattachment or persistentvolumeclaim --- container/raw/handler.go | 18 ++++++- container/raw/handler_test.go | 52 ++++++++++++++++++++ docs/storage/prometheus.md | 1 + fs/fs.go | 2 + fs/types.go | 2 + info/v1/container.go | 7 +++ integration/tests/metrics/prometheus_test.go | 1 + metrics/prometheus.go | 50 +++++++++++++++++++ metrics/prometheus_test.go | 44 +++++++++++++++++ 9 files changed, 175 insertions(+), 2 deletions(-) diff --git a/container/raw/handler.go b/container/raw/handler.go index a53c018806..1e589b803c 100644 --- a/container/raw/handler.go +++ b/container/raw/handler.go @@ -173,6 +173,7 @@ func fsToFsStats(fs *fs.Fs) info.FsStats { Inodes: inodes, InodesFree: inodesFree, Available: fs.Available, + Mountpoint: fs.Mountpoint, ReadsCompleted: fs.DiskStats.ReadsCompleted, ReadsMerged: fs.DiskStats.ReadsMerged, SectorsRead: fs.DiskStats.SectorsRead, @@ -215,9 +216,22 @@ func (h *rawContainerHandler) getFsStats(stats *info.ContainerStats) error { } if h.includedMetrics.Has(container.DiskUsageMetrics) { + // Build a map from host-side mount directory to container-side path + // from the external mounts (container hints) configuration. + hostToContainerPath := make(map[string]string, len(h.externalMounts)) + for _, m := range h.externalMounts { + if m.HostDir != "" && m.ContainerDir != "" { + hostToContainerPath[m.HostDir] = m.ContainerDir + } + } + for i := range filesystems { - fs := filesystems[i] - stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs)) + fsCopy := filesystems[i] + fsstat := fsToFsStats(&fsCopy) + if containerPath, ok := hostToContainerPath[fsstat.Mountpoint]; ok { + fsstat.ContainerPath = containerPath + } + stats.Filesystem = append(stats.Filesystem, fsstat) } } diff --git a/container/raw/handler_test.go b/container/raw/handler_test.go index 35315dfaab..8e674ea4e7 100644 --- a/container/raw/handler_test.go +++ b/container/raw/handler_test.go @@ -122,6 +122,24 @@ func TestFsToFsStats(t *testing.T) { WeightedIoTime: uint64(100), }, }, + "has_mountpoint": { + fs: &fs.Fs{ + DeviceInfo: fs.DeviceInfo{Device: "/dev/sdb"}, + Mountpoint: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount", + Type: fs.VFS, + Capacity: uint64(1024 * 1024), + Free: uint64(1024), + Available: uint64(1024), + }, + expected: info.FsStats{ + Device: "/dev/sdb", + Mountpoint: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount", + Type: fs.VFS.String(), + Limit: uint64(1024 * 1024), + Usage: uint64(1024*1024) - uint64(1024), + Available: uint64(1024), + }, + }, } for testName, testCase := range testCases { actual := fsToFsStats(testCase.fs) @@ -381,6 +399,40 @@ func TestGetFsStats(t *testing.T) { }, }, }, + "random container with mountpoint and container path": { + name: "/random/container", + includedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}}, + externalMounts: []common.Mount{ + { + HostDir: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount", + ContainerDir: "/data", + }, + }, + getFsInfoForPath: func(mountSet map[string]struct{}) ([]fs.Fs, error) { + return []fs.Fs{{ + DeviceInfo: fs.DeviceInfo{Device: "/dev/sdb", Major: 8, Minor: 0}, + Mountpoint: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount", + Type: "ext4", + Capacity: 1000, + Free: 500, + Available: 450, + Inodes: &inodes, + InodesFree: &inodesFree, + }}, nil + }, + expectedFilesystems: []info.FsStats{{ + Device: "/dev/sdb", + Mountpoint: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount", + ContainerPath: "/data", + Type: "ext4", + Limit: 1000, + Usage: 500, + Available: 450, + HasInodes: true, + Inodes: 2000, + InodesFree: 1000, + }}, + }, "random container with disk metrics enabled": { name: "/random/container", includedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}, container.DiskIOMetrics: struct{}{}}, diff --git a/docs/storage/prometheus.md b/docs/storage/prometheus.md index 1edc8e5dbe..e405d3bafe 100644 --- a/docs/storage/prometheus.md +++ b/docs/storage/prometheus.md @@ -30,6 +30,7 @@ Metric name | Type | Description | Unit (where applicable) | option parameter | `container_cpu_usage_seconds_total` | Counter | Cumulative cpu time consumed | seconds | cpu | `container_cpu_user_seconds_total` | Counter | Cumulative user cpu time consumed | seconds | cpu | `container_file_descriptors` | Gauge | Number of open file descriptors for the container | | process | +`container_fs_device_info` | Gauge | Device information for the filesystem used by the container, with `device` label identifying the device and `major` and `minor` labels identifying the major and minor device numbers | | disk | `container_fs_inodes_free` | Gauge | Number of available Inodes | | disk | `container_fs_inodes_total` | Gauge | Total number of Inodes | | disk | `container_fs_io_current` | Gauge | Number of I/Os currently in progress | | diskIO | diff --git a/fs/fs.go b/fs/fs.go index ec2c3b2ccd..1e6bd96aca 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -429,6 +429,7 @@ func (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error Major: uint(partition.major), Minor: uint(partition.minor), } + fs.Mountpoint = partition.mountpoint if val, ok := diskStatsMap[device]; ok { fs.DiskStats = val } else { @@ -483,6 +484,7 @@ func (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error Major: uint(partition.major), Minor: uint(partition.minor), } + fs.Mountpoint = partition.mountpoint if val, ok := diskStatsMap[device]; ok { fs.DiskStats = val diff --git a/fs/types.go b/fs/types.go index 6bc91985cb..b9843eee2c 100644 --- a/fs/types.go +++ b/fs/types.go @@ -71,6 +71,8 @@ type Fs struct { Inodes *uint64 InodesFree *uint64 DiskStats DiskStats + // Mountpoint is the host-side path where this device is mounted. + Mountpoint string } type DiskStats struct { diff --git a/info/v1/container.go b/info/v1/container.go index 3d2d282135..63ebd500a8 100644 --- a/info/v1/container.go +++ b/info/v1/container.go @@ -860,6 +860,13 @@ type FsStats struct { // last update of this field. This can provide an easy measure of both // I/O completion time and the backlog that may be accumulating. WeightedIoTime uint64 `json:"weighted_io_time"` + + // Mountpoint is the host-side path where this filesystem device is mounted. + Mountpoint string `json:"mountpoint,omitempty"` + + // ContainerPath is the path inside the container corresponding to this + // filesystem mount (populated from external mounts / container hints config). + ContainerPath string `json:"container_path,omitempty"` } type AcceleratorStats struct { diff --git a/integration/tests/metrics/prometheus_test.go b/integration/tests/metrics/prometheus_test.go index a2a4535b99..f020f32111 100644 --- a/integration/tests/metrics/prometheus_test.go +++ b/integration/tests/metrics/prometheus_test.go @@ -432,6 +432,7 @@ func TestDiskIOMetricsExist(t *testing.T) { "container_fs_writes_bytes_total", "container_fs_reads_total", "container_fs_writes_total", + "container_fs_device_info", } foundCount := 0 diff --git a/metrics/prometheus.go b/metrics/prometheus.go index 3702dd79cb..ef657859d2 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -78,6 +78,36 @@ func ioValues(ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) return values } +type volumePath struct { + volumeName string +} + +// kubeletVolumePathRE matches the standard kubelet volume mount path format: +// +// /var/lib/kubelet/pods//volumes//[/…] +// +// Capture group 1 is the volume name, which for CSI volumes corresponds to the +// PersistentVolumeClaim name. +var kubeletVolumePathRE = regexp.MustCompile(`/pods/[^/]+/volumes/[^/]+/([^/]+)`) + +// parseMountPointIntoVolumePath extracts the volume name from a kubelet volume mount +// path. For CSI volumes this is the PersistentVolumeClaim name. Returns an +// empty string for paths that do not match the standard kubelet volume path. +// +// Example: +// +// /var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount → "my-pvc" +func parseMountPointIntoVolumePath(path string) volumePath { + m := kubeletVolumePathRE.FindStringSubmatch(path) + if m == nil { + return volumePath{} + } + + return volumePath{ + volumeName: m[1], + } +} + // containerMetric describes a multi-dimensional metric used for exposing a // certain type of container statistic. type containerMetric struct { @@ -600,6 +630,26 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri return float64(fs.Usage) }, s.Timestamp) }, + }, { + name: "container_fs_device_info", + help: "Filesystem device and mount information for containers. Value is always 1; join on (id, device) with other container_fs_* metrics to associate devices with PVCs or container mount paths.", + valueType: prometheus.GaugeValue, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name"}, + getValues: func(s *info.ContainerStats) metricValues { + values := make(metricValues, 0, len(s.Filesystem)) + for _, fs := range s.Filesystem { + if fs.Device == "" { + continue + } + volumeMountInfo := parseMountPointIntoVolumePath(fs.Mountpoint) + values = append(values, metricValue{ + value: 1.0, + labels: []string{fs.Device, fs.Mountpoint, fs.ContainerPath, volumeMountInfo.volumeName}, + timestamp: s.Timestamp, + }) + } + return values + }, }, }...) } diff --git a/metrics/prometheus_test.go b/metrics/prometheus_test.go index 928fbf1674..32f1bc7873 100644 --- a/metrics/prometheus_test.go +++ b/metrics/prometheus_test.go @@ -464,3 +464,47 @@ func TestCPUBurstMetrics(t *testing.T) { }) } } + +func TestParseMountPointIntoVolumePath(t *testing.T) { + testCases := []struct { + name string + path string + expected string + }{ + { + name: "standard CSI volume path", + path: "/var/lib/kubelet/pods/abc123-def456/volumes/kubernetes.io~csi/my-database-pvc/mount", + expected: "my-database-pvc", + }, + { + name: "NFS volume path", + path: "/var/lib/kubelet/pods/abc/volumes/kubernetes.io~nfs/nfs-vol/mount", + expected: "nfs-vol", + }, + { + name: "non-standard kubelet root dir", + path: "/data/kubelet/pods/abc/volumes/kubernetes.io~csi/my-pvc/mount", + expected: "my-pvc", + }, + { + name: "no match - plain host path", + path: "/mnt/data", + expected: "", + }, + { + name: "empty string", + path: "", + expected: "", + }, + { + name: "root cgroup path", + path: "/", + expected: "", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, parseMountPointIntoVolumePath(tc.path).volumeName) + }) + } +} From 3aec924e1c90670860a530dd9a72c497972f78d4 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 21 Feb 2026 22:12:28 +0000 Subject: [PATCH 02/26] fix: add in volume type field to simplify filters --- metrics/prometheus.go | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/metrics/prometheus.go b/metrics/prometheus.go index ef657859d2..2d9d7606de 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -80,15 +80,12 @@ func ioValues(ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) type volumePath struct { volumeName string + volumeType string } -// kubeletVolumePathRE matches the standard kubelet volume mount path format: -// -// /var/lib/kubelet/pods//volumes//[/…] -// -// Capture group 1 is the volume name, which for CSI volumes corresponds to the -// PersistentVolumeClaim name. -var kubeletVolumePathRE = regexp.MustCompile(`/pods/[^/]+/volumes/[^/]+/([^/]+)`) +type matchTypes struct { + regex *regexp.Regexp +} // parseMountPointIntoVolumePath extracts the volume name from a kubelet volume mount // path. For CSI volumes this is the PersistentVolumeClaim name. Returns an @@ -98,14 +95,29 @@ var kubeletVolumePathRE = regexp.MustCompile(`/pods/[^/]+/volumes/[^/]+/([^/]+)` // // /var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount → "my-pvc" func parseMountPointIntoVolumePath(path string) volumePath { - m := kubeletVolumePathRE.FindStringSubmatch(path) - if m == nil { - return volumePath{} + volumeMatchTypes := []matchTypes{ + // /var/lib/kubelet/pods//volumes//[/…] + // + // Capture group 1 is the volume name, which for CSI volumes corresponds to the + // PersistentVolumeClaim name. + { + regex: regexp.MustCompile(`/pods/[^/]+/volumes/([^/]+)/([^/]+)`), + }, } - return volumePath{ - volumeName: m[1], + for _, matchType := range volumeMatchTypes { + m := matchType.regex.FindStringSubmatch(path) + if m == nil { + continue + } + + return volumePath{ + volumeName: m[2], + volumeType: m[1], + } } + + return volumePath{} } // containerMetric describes a multi-dimensional metric used for exposing a @@ -634,7 +646,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri name: "container_fs_device_info", help: "Filesystem device and mount information for containers. Value is always 1; join on (id, device) with other container_fs_* metrics to associate devices with PVCs or container mount paths.", valueType: prometheus.GaugeValue, - extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { values := make(metricValues, 0, len(s.Filesystem)) for _, fs := range s.Filesystem { @@ -644,7 +656,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri volumeMountInfo := parseMountPointIntoVolumePath(fs.Mountpoint) values = append(values, metricValue{ value: 1.0, - labels: []string{fs.Device, fs.Mountpoint, fs.ContainerPath, volumeMountInfo.volumeName}, + labels: []string{fs.Device, fs.Mountpoint, fs.ContainerPath, volumeMountInfo.volumeName, volumeMountInfo.volumeType}, timestamp: s.Timestamp, }) } From 2826591579a80ba78f2a139decdc742fa87824e1 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 21 Feb 2026 22:35:06 +0000 Subject: [PATCH 03/26] fix: remove erroenous disk io metric --- integration/tests/metrics/prometheus_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/integration/tests/metrics/prometheus_test.go b/integration/tests/metrics/prometheus_test.go index f020f32111..a2a4535b99 100644 --- a/integration/tests/metrics/prometheus_test.go +++ b/integration/tests/metrics/prometheus_test.go @@ -432,7 +432,6 @@ func TestDiskIOMetricsExist(t *testing.T) { "container_fs_writes_bytes_total", "container_fs_reads_total", "container_fs_writes_total", - "container_fs_device_info", } foundCount := 0 From 2d39afee87ce2e57a927cb61bd579ba183192148 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 21 Feb 2026 22:54:52 +0000 Subject: [PATCH 04/26] tests: update fixtures --- metrics/testdata/prometheus_metrics | 4 ++++ metrics/testdata/prometheus_metrics_whitelist_filtered | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/metrics/testdata/prometheus_metrics b/metrics/testdata/prometheus_metrics index b29a01a177..3afba11162 100644 --- a/metrics/testdata/prometheus_metrics +++ b/metrics/testdata/prometheus_metrics @@ -64,6 +64,10 @@ container_custom_app_metric_3{app_test_label="test_value",container_env_foo_env= # HELP container_file_descriptors Number of open file descriptors for the container. # TYPE container_file_descriptors gauge container_file_descriptors{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 5 1395066363000 +# HELP container_fs_device_info Filesystem device and mount information for containers. Value is always 1; join on (id, device) with other container_fs_* metrics to associate devices with PVCs or container mount paths. +# TYPE container_fs_device_info gauge +container_fs_device_info{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 +container_fs_device_info{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 # HELP container_fs_inodes_free Number of available Inodes # TYPE container_fs_inodes_free gauge container_fs_inodes_free{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 524288 1395066363000 diff --git a/metrics/testdata/prometheus_metrics_whitelist_filtered b/metrics/testdata/prometheus_metrics_whitelist_filtered index 0bab1a7dcf..717fccaf77 100644 --- a/metrics/testdata/prometheus_metrics_whitelist_filtered +++ b/metrics/testdata/prometheus_metrics_whitelist_filtered @@ -64,6 +64,10 @@ container_custom_app_metric_3{app_test_label="test_value",container_env_foo_env= # HELP container_file_descriptors Number of open file descriptors for the container. # TYPE container_file_descriptors gauge container_file_descriptors{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 5 1395066363000 +# HELP container_fs_device_info Filesystem device and mount information for containers. Value is always 1; join on (id, device) with other container_fs_* metrics to associate devices with PVCs or container mount paths. +# TYPE container_fs_device_info gauge +container_fs_device_info{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 +container_fs_device_info{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 # HELP container_fs_inodes_free Number of available Inodes # TYPE container_fs_inodes_free gauge container_fs_inodes_free{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 524288 1395066363000 From 3364ac99b4a1bcdbfeeef65233d695913e52f769 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sun, 15 Mar 2026 22:09:28 +0000 Subject: [PATCH 05/26] fix: export all mountpoints in container_fs_device_info --- container/raw/handler.go | 1 + fs/fs.go | 29 ++++++++++++++++++++++++----- fs/types.go | 5 ++++- info/v1/container.go | 5 +++++ metrics/prometheus.go | 22 ++++++++++++++++------ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/container/raw/handler.go b/container/raw/handler.go index 1e589b803c..0eba467d49 100644 --- a/container/raw/handler.go +++ b/container/raw/handler.go @@ -174,6 +174,7 @@ func fsToFsStats(fs *fs.Fs) info.FsStats { InodesFree: inodesFree, Available: fs.Available, Mountpoint: fs.Mountpoint, + AllMountpoints: fs.AllMountpoints, ReadsCompleted: fs.DiskStats.ReadsCompleted, ReadsMerged: fs.DiskStats.ReadsMerged, SectorsRead: fs.DiskStats.SectorsRead, diff --git a/fs/fs.go b/fs/fs.go index 1e6bd96aca..f7c20e5b7b 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -89,6 +89,9 @@ type RealFsInfo struct { dmsetup devicemapper.DmsetupClient // fsUUIDToDeviceName is a map from the filesystem UUID to its device name. fsUUIDToDeviceName map[string]string + // deviceToMountpoints maps each block device to all of its host-side mount + // paths, including bind mounts that processMounts de-duplicates away. + deviceToMountpoints map[string][]string } func NewFsInfo(context Context) (FsInfo, error) { @@ -110,12 +113,26 @@ func NewFsInfo(context Context) (FsInfo, error) { // Avoid devicemapper container mounts - these are tracked by the ThinPoolWatcher excluded := []string{fmt.Sprintf("%s/devicemapper/mnt", context.Docker.Root)} + + // Build device → all-mountpoints map before processMounts de-duplicates. + // We record every mountpoint for devices whose FSType has a plugin, so that + // container_fs_device_info can emit metrics for bind-mount paths (e.g. the + // per-pod kubelet volume path alongside the CSI plugin globalmount path). + deviceToMountpoints := make(map[string][]string) + for _, mnt := range mounts { + if GetPluginForFsType(mnt.FSType) == nil { + continue + } + deviceToMountpoints[mnt.Source] = append(deviceToMountpoints[mnt.Source], mnt.Mountpoint) + } + fsInfo := &RealFsInfo{ - partitions: processMounts(mounts, excluded), - labels: make(map[string]string), - mounts: make(map[string]mount.Info), - dmsetup: devicemapper.NewDmsetupClient(), - fsUUIDToDeviceName: fsUUIDToDeviceName, + partitions: processMounts(mounts, excluded), + labels: make(map[string]string), + mounts: make(map[string]mount.Info), + dmsetup: devicemapper.NewDmsetupClient(), + fsUUIDToDeviceName: fsUUIDToDeviceName, + deviceToMountpoints: deviceToMountpoints, } for _, mnt := range mounts { @@ -430,6 +447,7 @@ func (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error Minor: uint(partition.minor), } fs.Mountpoint = partition.mountpoint + fs.AllMountpoints = i.deviceToMountpoints[device] if val, ok := diskStatsMap[device]; ok { fs.DiskStats = val } else { @@ -485,6 +503,7 @@ func (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error Minor: uint(partition.minor), } fs.Mountpoint = partition.mountpoint + fs.AllMountpoints = i.deviceToMountpoints[device] if val, ok := diskStatsMap[device]; ok { fs.DiskStats = val diff --git a/fs/types.go b/fs/types.go index b9843eee2c..424a548738 100644 --- a/fs/types.go +++ b/fs/types.go @@ -71,8 +71,11 @@ type Fs struct { Inodes *uint64 InodesFree *uint64 DiskStats DiskStats - // Mountpoint is the host-side path where this device is mounted. + // Mountpoint is the primary host-side path where this device is mounted. Mountpoint string + // AllMountpoints lists every host-side path where this device is mounted, + // including bind mounts (e.g. CSI plugin globalmount + per-pod kubelet path). + AllMountpoints []string } type DiskStats struct { diff --git a/info/v1/container.go b/info/v1/container.go index 63ebd500a8..823415cd74 100644 --- a/info/v1/container.go +++ b/info/v1/container.go @@ -864,6 +864,11 @@ type FsStats struct { // Mountpoint is the host-side path where this filesystem device is mounted. Mountpoint string `json:"mountpoint,omitempty"` + // AllMountpoints lists every host-side path where this device is mounted, + // including bind mounts (e.g. both the CSI plugin globalmount path and the + // per-pod kubelet volume path). Mountpoint is always present in this slice. + AllMountpoints []string `json:"all_mountpoints,omitempty"` + // ContainerPath is the path inside the container corresponding to this // filesystem mount (populated from external mounts / container hints config). ContainerPath string `json:"container_path,omitempty"` diff --git a/metrics/prometheus.go b/metrics/prometheus.go index 2d9d7606de..01017f4da3 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -653,12 +653,22 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri if fs.Device == "" { continue } - volumeMountInfo := parseMountPointIntoVolumePath(fs.Mountpoint) - values = append(values, metricValue{ - value: 1.0, - labels: []string{fs.Device, fs.Mountpoint, fs.ContainerPath, volumeMountInfo.volumeName, volumeMountInfo.volumeType}, - timestamp: s.Timestamp, - }) + // Emit one metric per host mountpoint so that both the CSI + // plugin globalmount path and the per-pod kubelet volume path + // are visible. Fall back to the primary Mountpoint when + // AllMountpoints is unpopulated (e.g. non-root containers). + mountpoints := fs.AllMountpoints + if len(mountpoints) == 0 { + mountpoints = []string{fs.Mountpoint} + } + for _, mp := range mountpoints { + volumeMountInfo := parseMountPointIntoVolumePath(mp) + values = append(values, metricValue{ + value: 1.0, + labels: []string{fs.Device, mp, fs.ContainerPath, volumeMountInfo.volumeName, volumeMountInfo.volumeType}, + timestamp: s.Timestamp, + }) + } } return values }, From 136540967d8ed793fd440b423903a11f58286b7c Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Mon, 16 Mar 2026 11:47:45 +0000 Subject: [PATCH 06/26] fix: expose volume details on container metrics directly --- metrics/prometheus.go | 269 ++++++++++++------ metrics/prometheus_test.go | 23 ++ metrics/testdata/prometheus_metrics | 160 +++++------ .../prometheus_metrics_whitelist_filtered | 160 +++++------ 4 files changed, 357 insertions(+), 255 deletions(-) diff --git a/metrics/prometheus.go b/metrics/prometheus.go index 01017f4da3..f1f3eece91 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -18,6 +18,7 @@ import ( "fmt" "regexp" "strconv" + "strings" "time" "github.com/google/cadvisor/container" @@ -120,6 +121,98 @@ func parseMountPointIntoVolumePath(path string) volumePath { return volumePath{} } +// deviceFsInfo holds the filesystem identity labels for a block device. +type deviceFsInfo struct { + hostMountpoint string + containerMountpath string + volumeName string + volumeType string +} + +// bestMountpoint selects the most informative host-side mountpoint from fs.AllMountpoints. +// It prefers paths containing "/pods/" (the kubelet per-pod volume path) since those +// can be decoded into a PVC name via parseMountPointIntoVolumePath. +func bestMountpoint(fs *info.FsStats) string { + for _, mp := range fs.AllMountpoints { + if strings.Contains(mp, "/pods/") { + return mp + } + } + if len(fs.AllMountpoints) > 0 { + return fs.AllMountpoints[0] + } + return fs.Mountpoint +} + +// buildDeviceFsMap builds a map from device name to filesystem identity labels +// by inspecting the container's filesystem stats. For the aggregator to correlate +// disk IO with PVCs, the kubelet per-pod volume path is preferred over globalmount. +func buildDeviceFsMap(fsStats []info.FsStats) map[string]deviceFsInfo { + m := make(map[string]deviceFsInfo, len(fsStats)) + for i := range fsStats { + fs := &fsStats[i] + if fs.Device == "" { + continue + } + mp := bestMountpoint(fs) + vp := parseMountPointIntoVolumePath(mp) + m[fs.Device] = deviceFsInfo{ + hostMountpoint: mp, + containerMountpath: fs.ContainerPath, + volumeName: vp.volumeName, + volumeType: vp.volumeType, + } + } + return m +} + +// fsValuesEnriched is like fsValues but appends host_mountpoint, container_mountpath, +// volume_name, and volume_type labels derived from the filesystem info. +func fsValuesEnriched(fsStats []info.FsStats, valueFn func(*info.FsStats) float64, timestamp time.Time) metricValues { + values := make(metricValues, 0, len(fsStats)) + for i := range fsStats { + fs := &fsStats[i] + mp := bestMountpoint(fs) + vp := parseMountPointIntoVolumePath(mp) + values = append(values, metricValue{ + value: valueFn(fs), + labels: []string{fs.Device, mp, fs.ContainerPath, vp.volumeName, vp.volumeType}, + timestamp: timestamp, + }) + } + return values +} + +// ioValuesEnriched is like ioValues but appends host_mountpoint, container_mountpath, +// volume_name, and volume_type labels. For ioStats entries the device is looked up +// in fsMap; for fsStats entries the info is read directly. +func ioValuesEnriched( + ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) float64, + fsStats []info.FsStats, valueFn func(*info.FsStats) float64, + fsMap map[string]deviceFsInfo, timestamp time.Time, +) metricValues { + values := make(metricValues, 0, len(ioStats)+len(fsStats)) + for _, stat := range ioStats { + fi := fsMap[stat.Device] + values = append(values, metricValue{ + value: ioValueFn(stat.Stats[ioType]), + labels: []string{stat.Device, fi.hostMountpoint, fi.containerMountpath, fi.volumeName, fi.volumeType}, + timestamp: timestamp, + }) + } + for i := range fsStats { + fs := &fsStats[i] + mp := bestMountpoint(fs) + vp := parseMountPointIntoVolumePath(mp) + values = append(values, metricValue{ + value: valueFn(fs), + labels: []string{fs.Device, mp, fs.ContainerPath, vp.volumeName, vp.volumeType}, + timestamp: timestamp, + }) + } + return values +} + // containerMetric describes a multi-dimensional metric used for exposing a // certain type of container statistic. type containerMetric struct { @@ -606,9 +699,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri name: "container_fs_inodes_free", help: "Number of available Inodes", valueType: prometheus.GaugeValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { + return fsValuesEnriched(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.InodesFree) }, s.Timestamp) }, @@ -616,9 +709,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri name: "container_fs_inodes_total", help: "Number of Inodes", valueType: prometheus.GaugeValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { + return fsValuesEnriched(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.Inodes) }, s.Timestamp) }, @@ -626,9 +719,9 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri name: "container_fs_limit_bytes", help: "Number of bytes that can be consumed by the container on this filesystem.", valueType: prometheus.GaugeValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { + return fsValuesEnriched(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.Limit) }, s.Timestamp) }, @@ -636,42 +729,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri name: "container_fs_usage_bytes", help: "Number of bytes that are consumed by the container on this filesystem.", valueType: prometheus.GaugeValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { + return fsValuesEnriched(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.Usage) }, s.Timestamp) }, - }, { - name: "container_fs_device_info", - help: "Filesystem device and mount information for containers. Value is always 1; join on (id, device) with other container_fs_* metrics to associate devices with PVCs or container mount paths.", - valueType: prometheus.GaugeValue, - extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, - getValues: func(s *info.ContainerStats) metricValues { - values := make(metricValues, 0, len(s.Filesystem)) - for _, fs := range s.Filesystem { - if fs.Device == "" { - continue - } - // Emit one metric per host mountpoint so that both the CSI - // plugin globalmount path and the per-pod kubelet volume path - // are visible. Fall back to the primary Mountpoint when - // AllMountpoints is unpopulated (e.g. non-root containers). - mountpoints := fs.AllMountpoints - if len(mountpoints) == 0 { - mountpoints = []string{fs.Mountpoint} - } - for _, mp := range mountpoints { - volumeMountInfo := parseMountPointIntoVolumePath(mp) - values = append(values, metricValue{ - value: 1.0, - labels: []string{fs.Device, mp, fs.ContainerPath, volumeMountInfo.volumeName, volumeMountInfo.volumeType}, - timestamp: s.Timestamp, - }) - } - } - return values - }, }, }...) } @@ -681,173 +744,185 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri name: "container_fs_reads_bytes_total", help: "Cumulative count of bytes read", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoServiceBytes, "Read", asFloat64, nil, nil, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_reads_total", help: "Cumulative count of reads completed", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoServiced, "Read", asFloat64, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.ReadsCompleted) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_sector_reads_total", help: "Cumulative count of sector reads completed", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.Sectors, "Read", asFloat64, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.SectorsRead) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_reads_merged_total", help: "Cumulative count of reads merged", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoMerged, "Read", asFloat64, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.ReadsMerged) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_read_seconds_total", help: "Cumulative count of seconds spent reading", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoServiceTime, "Read", asNanosecondsToSeconds, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.ReadTime) / float64(time.Second) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_writes_bytes_total", help: "Cumulative count of bytes written", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoServiceBytes, "Write", asFloat64, nil, nil, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_writes_total", help: "Cumulative count of writes completed", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoServiced, "Write", asFloat64, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.WritesCompleted) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_sector_writes_total", help: "Cumulative count of sector writes completed", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.Sectors, "Write", asFloat64, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.SectorsWritten) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_writes_merged_total", help: "Cumulative count of writes merged", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoMerged, "Write", asFloat64, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.WritesMerged) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_write_seconds_total", help: "Cumulative count of seconds spent writing", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoServiceTime, "Write", asNanosecondsToSeconds, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.WriteTime) / float64(time.Second) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_io_current", help: "Number of I/Os currently in progress", valueType: prometheus.GaugeValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoQueued, "Total", asFloat64, s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.IoInProgress) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_io_time_seconds_total", help: "Cumulative count of seconds spent doing I/Os", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoServiceTime, "Total", asNanosecondsToSeconds, s.Filesystem, func(fs *info.FsStats) float64 { return float64(float64(fs.IoTime) / float64(time.Second)) }, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_io_time_weighted_seconds_total", help: "Cumulative weighted I/O time in seconds", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return fsValues(s.Filesystem, func(fs *info.FsStats) float64 { + return fsValuesEnriched(s.Filesystem, func(fs *info.FsStats) float64 { return float64(fs.WeightedIoTime) / float64(time.Second) }, s.Timestamp) }, @@ -855,48 +930,52 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri name: "container_fs_io_cost_usage_seconds_total", help: "Cumulative IOCost usage in seconds", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoCostUsage, "Count", asMicrosecondsToSeconds, []info.FsStats{}, nil, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_io_cost_wait_seconds_total", help: "Cumulative IOCost wait in seconds", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoCostWait, "Count", asMicrosecondsToSeconds, []info.FsStats{}, nil, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_io_cost_indebt_seconds_total", help: "Cumulative IOCost debt in seconds", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoCostIndebt, "Count", asMicrosecondsToSeconds, []info.FsStats{}, nil, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, { name: "container_fs_io_cost_indelay_seconds_total", help: "Cumulative IOCost delay in seconds", valueType: prometheus.CounterValue, - extraLabels: []string{"device"}, + extraLabels: []string{"device", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { - return ioValues( + fsMap := buildDeviceFsMap(s.Filesystem) + return ioValuesEnriched( s.DiskIo.IoCostIndelay, "Count", asMicrosecondsToSeconds, []info.FsStats{}, nil, - s.Timestamp, + fsMap, s.Timestamp, ) }, }, @@ -904,17 +983,25 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri name: "container_blkio_device_usage_total", help: "Blkio Device bytes usage", valueType: prometheus.CounterValue, - extraLabels: []string{"device", "major", "minor", "operation"}, + extraLabels: []string{"device", "major", "minor", "operation", "host_mountpoint", "container_mountpath", "volume_name", "volume_type"}, getValues: func(s *info.ContainerStats) metricValues { + fsMap := buildDeviceFsMap(s.Filesystem) var values metricValues for _, diskStat := range s.DiskIo.IoServiceBytes { + fi := fsMap[diskStat.Device] for operation, value := range diskStat.Stats { values = append(values, metricValue{ value: float64(value), - labels: []string{diskStat.Device, + labels: []string{ + diskStat.Device, strconv.Itoa(int(diskStat.Major)), strconv.Itoa(int(diskStat.Minor)), - operation}, + operation, + fi.hostMountpoint, + fi.containerMountpath, + fi.volumeName, + fi.volumeType, + }, timestamp: s.Timestamp, }) } diff --git a/metrics/prometheus_test.go b/metrics/prometheus_test.go index 32f1bc7873..b1f08ec474 100644 --- a/metrics/prometheus_test.go +++ b/metrics/prometheus_test.go @@ -16,6 +16,7 @@ package metrics import ( "errors" + "flag" "os" "testing" "time" @@ -26,6 +27,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/expfmt" "github.com/stretchr/testify/assert" clock "k8s.io/utils/clock/testing" ) @@ -75,7 +77,28 @@ func TestPrometheusCollectorWithPerfAggregated(t *testing.T) { testPrometheusCollector(t, reg, "testdata/prometheus_metrics_perf_aggregated") } +var update = flag.Bool("update", false, "update golden fixture files") + func testPrometheusCollector(t *testing.T, gatherer prometheus.Gatherer, metricsFile string) { + if *update { + f, err := os.Create(metricsFile) + if err != nil { + t.Fatalf("failed to create fixture %s: %s", metricsFile, err) + } + defer f.Close() + mfs, err := gatherer.Gather() + if err != nil { + t.Fatalf("failed to gather metrics: %s", err) + } + enc := expfmt.NewEncoder(f, expfmt.NewFormat(expfmt.TypeTextPlain)) + for _, mf := range mfs { + if err := enc.Encode(mf); err != nil { + t.Fatalf("failed to encode metric family: %s", err) + } + } + return + } + wantMetrics, err := os.Open(metricsFile) if err != nil { t.Fatalf("unable to read input test file %s", metricsFile) diff --git a/metrics/testdata/prometheus_metrics b/metrics/testdata/prometheus_metrics index 3afba11162..7f751bca2f 100644 --- a/metrics/testdata/prometheus_metrics +++ b/metrics/testdata/prometheus_metrics @@ -3,12 +3,18 @@ cadvisor_version_info{cadvisorRevision="abcdef",cadvisorVersion="0.16.0",dockerVersion="1.8.1",kernelVersion="4.1.6-200.fc22.x86_64",osVersion="Fedora 22 (Twenty Two)"} 1 # HELP container_blkio_device_usage_total Blkio Device bytes usage # TYPE container_blkio_device_usage_total counter -container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Async",zone_name="hello"} 1 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Discard",zone_name="hello"} 2 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Read",zone_name="hello"} 3 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Sync",zone_name="hello"} 4 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Total",zone_name="hello"} 5 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Write",zone_name="hello"} 6 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Async",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Discard",volume_name="",volume_type="",zone_name="hello"} 2 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Read",volume_name="",volume_type="",zone_name="hello"} 3 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Sync",volume_name="",volume_type="",zone_name="hello"} 4 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Total",volume_name="",volume_type="",zone_name="hello"} 5 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Write",volume_name="",volume_type="",zone_name="hello"} 6 1395066363000 +# HELP container_cpu_cfs_burst_periods_total Number of periods when burst occurs. +# TYPE container_cpu_cfs_burst_periods_total counter +container_cpu_cfs_burst_periods_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 25 1395066363000 +# HELP container_cpu_cfs_burst_seconds_total Total time duration the container has been bursted. +# TYPE container_cpu_cfs_burst_seconds_total counter +container_cpu_cfs_burst_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.5 1395066363000 # HELP container_cpu_cfs_periods_total Number of elapsed enforcement period intervals. # TYPE container_cpu_cfs_periods_total counter container_cpu_cfs_periods_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 723 1395066363000 @@ -18,12 +24,6 @@ container_cpu_cfs_throttled_periods_total{container_env_foo_env="prod",container # HELP container_cpu_cfs_throttled_seconds_total Total time duration the container has been throttled. # TYPE container_cpu_cfs_throttled_seconds_total counter container_cpu_cfs_throttled_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.724314 1395066363000 -# HELP container_cpu_cfs_burst_periods_total Number of periods when burst occurs. -# TYPE container_cpu_cfs_burst_periods_total counter -container_cpu_cfs_burst_periods_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 25 1395066363000 -# HELP container_cpu_cfs_burst_seconds_total Total time duration the container has been bursted. -# TYPE container_cpu_cfs_burst_seconds_total counter -container_cpu_cfs_burst_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.5 1395066363000 # HELP container_cpu_load_average_10s Value of container cpu load average over the last 10 seconds. # TYPE container_cpu_load_average_10s gauge container_cpu_load_average_10s{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2 1395066363000 @@ -64,88 +64,84 @@ container_custom_app_metric_3{app_test_label="test_value",container_env_foo_env= # HELP container_file_descriptors Number of open file descriptors for the container. # TYPE container_file_descriptors gauge container_file_descriptors{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 5 1395066363000 -# HELP container_fs_device_info Filesystem device and mount information for containers. Value is always 1; join on (id, device) with other container_fs_* metrics to associate devices with PVCs or container mount paths. -# TYPE container_fs_device_info gauge -container_fs_device_info{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 -container_fs_device_info{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 # HELP container_fs_inodes_free Number of available Inodes # TYPE container_fs_inodes_free gauge -container_fs_inodes_free{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 524288 1395066363000 -container_fs_inodes_free{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 262144 1395066363000 +container_fs_inodes_free{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 524288 1395066363000 +container_fs_inodes_free{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 262144 1395066363000 # HELP container_fs_inodes_total Number of Inodes # TYPE container_fs_inodes_total gauge -container_fs_inodes_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2.097152e+06 1395066363000 -container_fs_inodes_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2.097152e+06 1395066363000 +container_fs_inodes_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 2.097152e+06 1395066363000 +container_fs_inodes_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 2.097152e+06 1395066363000 +# HELP container_fs_io_cost_indebt_seconds_total Cumulative IOCost debt in seconds +# TYPE container_fs_io_cost_indebt_seconds_total counter +container_fs_io_cost_indebt_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 0.5 1395066363000 +# HELP container_fs_io_cost_indelay_seconds_total Cumulative IOCost delay in seconds +# TYPE container_fs_io_cost_indelay_seconds_total counter +container_fs_io_cost_indelay_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 0.75 1395066363000 +# HELP container_fs_io_cost_usage_seconds_total Cumulative IOCost usage in seconds +# TYPE container_fs_io_cost_usage_seconds_total counter +container_fs_io_cost_usage_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1.5 1395066363000 +# HELP container_fs_io_cost_wait_seconds_total Cumulative IOCost wait in seconds +# TYPE container_fs_io_cost_wait_seconds_total counter +container_fs_io_cost_wait_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 2.5 1395066363000 # HELP container_fs_io_current Number of I/Os currently in progress # TYPE container_fs_io_current gauge -container_fs_io_current{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 42 1395066363000 -container_fs_io_current{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 47 1395066363000 +container_fs_io_current{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 42 1395066363000 +container_fs_io_current{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 47 1395066363000 # HELP container_fs_io_time_seconds_total Cumulative count of seconds spent doing I/Os # TYPE container_fs_io_time_seconds_total counter -container_fs_io_time_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.3e-08 1395066363000 -container_fs_io_time_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.8e-08 1395066363000 +container_fs_io_time_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.3e-08 1395066363000 +container_fs_io_time_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.8e-08 1395066363000 # HELP container_fs_io_time_weighted_seconds_total Cumulative weighted I/O time in seconds # TYPE container_fs_io_time_weighted_seconds_total counter -container_fs_io_time_weighted_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.4e-08 1395066363000 -container_fs_io_time_weighted_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.9e-08 1395066363000 -# HELP container_fs_io_cost_usage_seconds_total Cumulative IOCost usage in seconds -# TYPE container_fs_io_cost_usage_seconds_total counter -container_fs_io_cost_usage_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.5 1395066363000 -# HELP container_fs_io_cost_wait_seconds_total Cumulative IOCost wait in seconds -# TYPE container_fs_io_cost_wait_seconds_total counter -container_fs_io_cost_wait_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2.5 1395066363000 -# HELP container_fs_io_cost_indebt_seconds_total Cumulative IOCost debt in seconds -# TYPE container_fs_io_cost_indebt_seconds_total counter -container_fs_io_cost_indebt_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.5 1395066363000 -# HELP container_fs_io_cost_indelay_seconds_total Cumulative IOCost delay in seconds -# TYPE container_fs_io_cost_indelay_seconds_total counter -container_fs_io_cost_indelay_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.75 1395066363000 +container_fs_io_time_weighted_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.4e-08 1395066363000 +container_fs_io_time_weighted_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.9e-08 1395066363000 # HELP container_fs_limit_bytes Number of bytes that can be consumed by the container on this filesystem. # TYPE container_fs_limit_bytes gauge -container_fs_limit_bytes{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 22 1395066363000 -container_fs_limit_bytes{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 37 1395066363000 +container_fs_limit_bytes{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 22 1395066363000 +container_fs_limit_bytes{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 37 1395066363000 # HELP container_fs_read_seconds_total Cumulative count of seconds spent reading # TYPE container_fs_read_seconds_total counter -container_fs_read_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2.7e-08 1395066363000 -container_fs_read_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.2e-08 1395066363000 +container_fs_read_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 2.7e-08 1395066363000 +container_fs_read_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.2e-08 1395066363000 # HELP container_fs_reads_bytes_total Cumulative count of bytes read # TYPE container_fs_reads_bytes_total counter -container_fs_reads_bytes_total{container_env_foo_env="prod",container_label_foo_label="bar",device="/dev/sdb",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 3 1395066363000 +container_fs_reads_bytes_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 3 1395066363000 # HELP container_fs_reads_merged_total Cumulative count of reads merged # TYPE container_fs_reads_merged_total counter -container_fs_reads_merged_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 25 1395066363000 -container_fs_reads_merged_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 40 1395066363000 +container_fs_reads_merged_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 25 1395066363000 +container_fs_reads_merged_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 40 1395066363000 # HELP container_fs_reads_total Cumulative count of reads completed # TYPE container_fs_reads_total counter -container_fs_reads_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 24 1395066363000 -container_fs_reads_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 39 1395066363000 +container_fs_reads_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 24 1395066363000 +container_fs_reads_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 39 1395066363000 # HELP container_fs_sector_reads_total Cumulative count of sector reads completed # TYPE container_fs_sector_reads_total counter -container_fs_sector_reads_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 26 1395066363000 -container_fs_sector_reads_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 41 1395066363000 +container_fs_sector_reads_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 26 1395066363000 +container_fs_sector_reads_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 41 1395066363000 # HELP container_fs_sector_writes_total Cumulative count of sector writes completed # TYPE container_fs_sector_writes_total counter -container_fs_sector_writes_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 40 1395066363000 -container_fs_sector_writes_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 45 1395066363000 +container_fs_sector_writes_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 40 1395066363000 +container_fs_sector_writes_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 45 1395066363000 # HELP container_fs_usage_bytes Number of bytes that are consumed by the container on this filesystem. # TYPE container_fs_usage_bytes gauge -container_fs_usage_bytes{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 23 1395066363000 -container_fs_usage_bytes{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 38 1395066363000 +container_fs_usage_bytes{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 23 1395066363000 +container_fs_usage_bytes{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 38 1395066363000 # HELP container_fs_write_seconds_total Cumulative count of seconds spent writing # TYPE container_fs_write_seconds_total counter -container_fs_write_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.1e-08 1395066363000 -container_fs_write_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.6e-08 1395066363000 +container_fs_write_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.1e-08 1395066363000 +container_fs_write_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.6e-08 1395066363000 # HELP container_fs_writes_bytes_total Cumulative count of bytes written # TYPE container_fs_writes_bytes_total counter -container_fs_writes_bytes_total{container_env_foo_env="prod",container_label_foo_label="bar",device="/dev/sdb",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 6 1395066363000 +container_fs_writes_bytes_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 6 1395066363000 # HELP container_fs_writes_merged_total Cumulative count of writes merged # TYPE container_fs_writes_merged_total counter -container_fs_writes_merged_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 39 1395066363000 -container_fs_writes_merged_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 44 1395066363000 +container_fs_writes_merged_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 39 1395066363000 +container_fs_writes_merged_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 44 1395066363000 # HELP container_fs_writes_total Cumulative count of writes completed # TYPE container_fs_writes_total counter -container_fs_writes_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 28 1395066363000 -container_fs_writes_total{container_env_foo_env="prod",container_label_foo_label="bar",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 43 1395066363000 +container_fs_writes_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 28 1395066363000 +container_fs_writes_total{container_env_foo_env="prod",container_label_foo_label="bar",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 43 1395066363000 # HELP container_health_state The result of the container's health check # TYPE container_health_state gauge container_health_state{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1 1395066363000 @@ -164,6 +160,18 @@ container_hugetlb_usage_bytes{container_env_foo_env="prod",container_label_foo_l # HELP container_last_seen Last time a container was seen by the exporter # TYPE container_last_seen gauge container_last_seen{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.395066363e+09 1395066363000 +# HELP container_llc_occupancy_bytes Last level cache usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). +# TYPE container_llc_occupancy_bytes gauge +container_llc_occupancy_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 162626 1395066363000 +container_llc_occupancy_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 213777 1395066363000 +# HELP container_memory_bandwidth_bytes Total memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). +# TYPE container_memory_bandwidth_bytes gauge +container_memory_bandwidth_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 4.512312e+06 1395066363000 +container_memory_bandwidth_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 2.173713e+06 1395066363000 +# HELP container_memory_bandwidth_local_bytes Local memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). +# TYPE container_memory_bandwidth_local_bytes gauge +container_memory_bandwidth_local_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 2.390393e+06 1395066363000 +container_memory_bandwidth_local_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 1.231233e+06 1395066363000 # HELP container_memory_cache Number of bytes of page cache memory. # TYPE container_memory_cache gauge container_memory_cache{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 14 1395066363000 @@ -386,26 +394,26 @@ container_network_udp_usage_total{container_env_foo_env="prod",container_label_f # HELP container_oom_events_total Count of out of memory events observed for the container # TYPE container_oom_events_total counter container_oom_events_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0 1395066363000 -# HELP container_perf_events_total Perf event metric. -# TYPE container_perf_events_total counter -container_perf_events_total{container_env_foo_env="prod",container_label_foo_label="bar",cpu="0",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 123 1395066363000 -container_perf_events_total{container_env_foo_env="prod",container_label_foo_label="bar",cpu="0",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 321 1395066363000 -container_perf_events_total{container_env_foo_env="prod",container_label_foo_label="bar",cpu="1",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 456 1395066363000 -container_perf_events_total{container_env_foo_env="prod",container_label_foo_label="bar",cpu="1",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 789 1395066363000 # HELP container_perf_events_scaling_ratio Perf event metric scaling ratio. # TYPE container_perf_events_scaling_ratio gauge container_perf_events_scaling_ratio{container_env_foo_env="prod",container_label_foo_label="bar",cpu="0",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1 1395066363000 container_perf_events_scaling_ratio{container_env_foo_env="prod",container_label_foo_label="bar",cpu="0",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.66666666666 1395066363000 container_perf_events_scaling_ratio{container_env_foo_env="prod",container_label_foo_label="bar",cpu="1",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.5 1395066363000 container_perf_events_scaling_ratio{container_env_foo_env="prod",container_label_foo_label="bar",cpu="1",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.33333333333 1395066363000 -# HELP container_perf_uncore_events_total Perf uncore event metric. -# TYPE container_perf_uncore_events_total counter -container_perf_uncore_events_total{container_env_foo_env="prod",container_label_foo_label="bar",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="0",zone_name="hello"} 1.231231512e+09 1395066363000 -container_perf_uncore_events_total{container_env_foo_env="prod",container_label_foo_label="bar",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="1",zone_name="hello"} 1.111231331e+09 1395066363000 +# HELP container_perf_events_total Perf event metric. +# TYPE container_perf_events_total counter +container_perf_events_total{container_env_foo_env="prod",container_label_foo_label="bar",cpu="0",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 123 1395066363000 +container_perf_events_total{container_env_foo_env="prod",container_label_foo_label="bar",cpu="0",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 321 1395066363000 +container_perf_events_total{container_env_foo_env="prod",container_label_foo_label="bar",cpu="1",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 456 1395066363000 +container_perf_events_total{container_env_foo_env="prod",container_label_foo_label="bar",cpu="1",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 789 1395066363000 # HELP container_perf_uncore_events_scaling_ratio Perf uncore event metric scaling ratio. # TYPE container_perf_uncore_events_scaling_ratio gauge container_perf_uncore_events_scaling_ratio{container_env_foo_env="prod",container_label_foo_label="bar",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="0",zone_name="hello"} 1 1395066363000 container_perf_uncore_events_scaling_ratio{container_env_foo_env="prod",container_label_foo_label="bar",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="1",zone_name="hello"} 1 1395066363000 +# HELP container_perf_uncore_events_total Perf uncore event metric. +# TYPE container_perf_uncore_events_total counter +container_perf_uncore_events_total{container_env_foo_env="prod",container_label_foo_label="bar",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="0",zone_name="hello"} 1.231231512e+09 1395066363000 +container_perf_uncore_events_total{container_env_foo_env="prod",container_label_foo_label="bar",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="1",zone_name="hello"} 1.111231331e+09 1395066363000 # HELP container_pressure_cpu_stalled_seconds_total Total time duration no tasks in the container could make progress due to CPU congestion. # TYPE container_pressure_cpu_stalled_seconds_total counter container_pressure_cpu_stalled_seconds_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.0001 1395066363000 @@ -464,15 +472,3 @@ container_threads_max{container_env_foo_env="prod",container_label_foo_label="ba # HELP container_ulimits_soft Soft ulimit values for the container root process. Unlimited if -1, except priority and nice # TYPE container_ulimits_soft gauge container_ulimits_soft{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",ulimit="max_open_files",zone_name="hello"} 16384 1395066363000 -# HELP container_llc_occupancy_bytes Last level cache usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). -# TYPE container_llc_occupancy_bytes gauge -container_llc_occupancy_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 162626 1395066363000 -container_llc_occupancy_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 213777 1395066363000 -# HELP container_memory_bandwidth_bytes Total memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). -# TYPE container_memory_bandwidth_bytes gauge -container_memory_bandwidth_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 4.512312e+06 1395066363000 -container_memory_bandwidth_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 2.173713e+06 1395066363000 -# HELP container_memory_bandwidth_local_bytes Local memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). -# TYPE container_memory_bandwidth_local_bytes gauge -container_memory_bandwidth_local_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 2.390393e+06 1395066363000 -container_memory_bandwidth_local_bytes{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 1.231233e+06 1395066363000 diff --git a/metrics/testdata/prometheus_metrics_whitelist_filtered b/metrics/testdata/prometheus_metrics_whitelist_filtered index 717fccaf77..f7f14ab483 100644 --- a/metrics/testdata/prometheus_metrics_whitelist_filtered +++ b/metrics/testdata/prometheus_metrics_whitelist_filtered @@ -3,12 +3,18 @@ cadvisor_version_info{cadvisorRevision="abcdef",cadvisorVersion="0.16.0",dockerVersion="1.8.1",kernelVersion="4.1.6-200.fc22.x86_64",osVersion="Fedora 22 (Twenty Two)"} 1 # HELP container_blkio_device_usage_total Blkio Device bytes usage # TYPE container_blkio_device_usage_total counter -container_blkio_device_usage_total{container_env_foo_env="prod",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Async",zone_name="hello"} 1 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Discard",zone_name="hello"} 2 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Read",zone_name="hello"} 3 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Sync",zone_name="hello"} 4 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Total",zone_name="hello"} 5 1395066363000 -container_blkio_device_usage_total{container_env_foo_env="prod",device="/dev/sdb",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Write",zone_name="hello"} 6 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Async",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Discard",volume_name="",volume_type="",zone_name="hello"} 2 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Read",volume_name="",volume_type="",zone_name="hello"} 3 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Sync",volume_name="",volume_type="",zone_name="hello"} 4 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Total",volume_name="",volume_type="",zone_name="hello"} 5 1395066363000 +container_blkio_device_usage_total{container_env_foo_env="prod",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",major="8",minor="0",name="testcontaineralias",operation="Write",volume_name="",volume_type="",zone_name="hello"} 6 1395066363000 +# HELP container_cpu_cfs_burst_periods_total Number of periods when burst occurs. +# TYPE container_cpu_cfs_burst_periods_total counter +container_cpu_cfs_burst_periods_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 25 1395066363000 +# HELP container_cpu_cfs_burst_seconds_total Total time duration the container has been bursted. +# TYPE container_cpu_cfs_burst_seconds_total counter +container_cpu_cfs_burst_seconds_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.5 1395066363000 # HELP container_cpu_cfs_periods_total Number of elapsed enforcement period intervals. # TYPE container_cpu_cfs_periods_total counter container_cpu_cfs_periods_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 723 1395066363000 @@ -18,12 +24,6 @@ container_cpu_cfs_throttled_periods_total{container_env_foo_env="prod",id="testc # HELP container_cpu_cfs_throttled_seconds_total Total time duration the container has been throttled. # TYPE container_cpu_cfs_throttled_seconds_total counter container_cpu_cfs_throttled_seconds_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.724314 1395066363000 -# HELP container_cpu_cfs_burst_periods_total Number of periods when burst occurs. -# TYPE container_cpu_cfs_burst_periods_total counter -container_cpu_cfs_burst_periods_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 25 1395066363000 -# HELP container_cpu_cfs_burst_seconds_total Total time duration the container has been bursted. -# TYPE container_cpu_cfs_burst_seconds_total counter -container_cpu_cfs_burst_seconds_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.5 1395066363000 # HELP container_cpu_load_average_10s Value of container cpu load average over the last 10 seconds. # TYPE container_cpu_load_average_10s gauge container_cpu_load_average_10s{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2 1395066363000 @@ -64,88 +64,84 @@ container_custom_app_metric_3{app_test_label="test_value",container_env_foo_env= # HELP container_file_descriptors Number of open file descriptors for the container. # TYPE container_file_descriptors gauge container_file_descriptors{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 5 1395066363000 -# HELP container_fs_device_info Filesystem device and mount information for containers. Value is always 1; join on (id, device) with other container_fs_* metrics to associate devices with PVCs or container mount paths. -# TYPE container_fs_device_info gauge -container_fs_device_info{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 -container_fs_device_info{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1 1395066363000 # HELP container_fs_inodes_free Number of available Inodes # TYPE container_fs_inodes_free gauge -container_fs_inodes_free{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 524288 1395066363000 -container_fs_inodes_free{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 262144 1395066363000 +container_fs_inodes_free{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 524288 1395066363000 +container_fs_inodes_free{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 262144 1395066363000 # HELP container_fs_inodes_total Number of Inodes # TYPE container_fs_inodes_total gauge -container_fs_inodes_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2.097152e+06 1395066363000 -container_fs_inodes_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2.097152e+06 1395066363000 +container_fs_inodes_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 2.097152e+06 1395066363000 +container_fs_inodes_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 2.097152e+06 1395066363000 +# HELP container_fs_io_cost_indebt_seconds_total Cumulative IOCost debt in seconds +# TYPE container_fs_io_cost_indebt_seconds_total counter +container_fs_io_cost_indebt_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 0.5 1395066363000 +# HELP container_fs_io_cost_indelay_seconds_total Cumulative IOCost delay in seconds +# TYPE container_fs_io_cost_indelay_seconds_total counter +container_fs_io_cost_indelay_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 0.75 1395066363000 +# HELP container_fs_io_cost_usage_seconds_total Cumulative IOCost usage in seconds +# TYPE container_fs_io_cost_usage_seconds_total counter +container_fs_io_cost_usage_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 1.5 1395066363000 +# HELP container_fs_io_cost_wait_seconds_total Cumulative IOCost wait in seconds +# TYPE container_fs_io_cost_wait_seconds_total counter +container_fs_io_cost_wait_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 2.5 1395066363000 # HELP container_fs_io_current Number of I/Os currently in progress # TYPE container_fs_io_current gauge -container_fs_io_current{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 42 1395066363000 -container_fs_io_current{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 47 1395066363000 +container_fs_io_current{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 42 1395066363000 +container_fs_io_current{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 47 1395066363000 # HELP container_fs_io_time_seconds_total Cumulative count of seconds spent doing I/Os # TYPE container_fs_io_time_seconds_total counter -container_fs_io_time_seconds_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.3e-08 1395066363000 -container_fs_io_time_seconds_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.8e-08 1395066363000 +container_fs_io_time_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.3e-08 1395066363000 +container_fs_io_time_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.8e-08 1395066363000 # HELP container_fs_io_time_weighted_seconds_total Cumulative weighted I/O time in seconds # TYPE container_fs_io_time_weighted_seconds_total counter -container_fs_io_time_weighted_seconds_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.4e-08 1395066363000 -container_fs_io_time_weighted_seconds_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.9e-08 1395066363000 -# HELP container_fs_io_cost_usage_seconds_total Cumulative IOCost usage in seconds -# TYPE container_fs_io_cost_usage_seconds_total counter -container_fs_io_cost_usage_seconds_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.5 1395066363000 -# HELP container_fs_io_cost_wait_seconds_total Cumulative IOCost wait in seconds -# TYPE container_fs_io_cost_wait_seconds_total counter -container_fs_io_cost_wait_seconds_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2.5 1395066363000 -# HELP container_fs_io_cost_indebt_seconds_total Cumulative IOCost debt in seconds -# TYPE container_fs_io_cost_indebt_seconds_total counter -container_fs_io_cost_indebt_seconds_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.5 1395066363000 -# HELP container_fs_io_cost_indelay_seconds_total Cumulative IOCost delay in seconds -# TYPE container_fs_io_cost_indelay_seconds_total counter -container_fs_io_cost_indelay_seconds_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.75 1395066363000 +container_fs_io_time_weighted_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.4e-08 1395066363000 +container_fs_io_time_weighted_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.9e-08 1395066363000 # HELP container_fs_limit_bytes Number of bytes that can be consumed by the container on this filesystem. # TYPE container_fs_limit_bytes gauge -container_fs_limit_bytes{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 22 1395066363000 -container_fs_limit_bytes{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 37 1395066363000 +container_fs_limit_bytes{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 22 1395066363000 +container_fs_limit_bytes{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 37 1395066363000 # HELP container_fs_read_seconds_total Cumulative count of seconds spent reading # TYPE container_fs_read_seconds_total counter -container_fs_read_seconds_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 2.7e-08 1395066363000 -container_fs_read_seconds_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.2e-08 1395066363000 +container_fs_read_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 2.7e-08 1395066363000 +container_fs_read_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.2e-08 1395066363000 # HELP container_fs_reads_bytes_total Cumulative count of bytes read # TYPE container_fs_reads_bytes_total counter -container_fs_reads_bytes_total{container_env_foo_env="prod",device="/dev/sdb",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 3 1395066363000 +container_fs_reads_bytes_total{container_env_foo_env="prod",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 3 1395066363000 # HELP container_fs_reads_merged_total Cumulative count of reads merged # TYPE container_fs_reads_merged_total counter -container_fs_reads_merged_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 25 1395066363000 -container_fs_reads_merged_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 40 1395066363000 +container_fs_reads_merged_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 25 1395066363000 +container_fs_reads_merged_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 40 1395066363000 # HELP container_fs_reads_total Cumulative count of reads completed # TYPE container_fs_reads_total counter -container_fs_reads_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 24 1395066363000 -container_fs_reads_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 39 1395066363000 +container_fs_reads_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 24 1395066363000 +container_fs_reads_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 39 1395066363000 # HELP container_fs_sector_reads_total Cumulative count of sector reads completed # TYPE container_fs_sector_reads_total counter -container_fs_sector_reads_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 26 1395066363000 -container_fs_sector_reads_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 41 1395066363000 +container_fs_sector_reads_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 26 1395066363000 +container_fs_sector_reads_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 41 1395066363000 # HELP container_fs_sector_writes_total Cumulative count of sector writes completed # TYPE container_fs_sector_writes_total counter -container_fs_sector_writes_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 40 1395066363000 -container_fs_sector_writes_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 45 1395066363000 +container_fs_sector_writes_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 40 1395066363000 +container_fs_sector_writes_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 45 1395066363000 # HELP container_fs_usage_bytes Number of bytes that are consumed by the container on this filesystem. # TYPE container_fs_usage_bytes gauge -container_fs_usage_bytes{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 23 1395066363000 -container_fs_usage_bytes{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 38 1395066363000 +container_fs_usage_bytes{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 23 1395066363000 +container_fs_usage_bytes{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 38 1395066363000 # HELP container_fs_write_seconds_total Cumulative count of seconds spent writing # TYPE container_fs_write_seconds_total counter -container_fs_write_seconds_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.1e-08 1395066363000 -container_fs_write_seconds_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 4.6e-08 1395066363000 +container_fs_write_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.1e-08 1395066363000 +container_fs_write_seconds_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 4.6e-08 1395066363000 # HELP container_fs_writes_bytes_total Cumulative count of bytes written # TYPE container_fs_writes_bytes_total counter -container_fs_writes_bytes_total{container_env_foo_env="prod",device="/dev/sdb",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 6 1395066363000 +container_fs_writes_bytes_total{container_env_foo_env="prod",container_mountpath="",device="/dev/sdb",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 6 1395066363000 # HELP container_fs_writes_merged_total Cumulative count of writes merged # TYPE container_fs_writes_merged_total counter -container_fs_writes_merged_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 39 1395066363000 -container_fs_writes_merged_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 44 1395066363000 +container_fs_writes_merged_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 39 1395066363000 +container_fs_writes_merged_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 44 1395066363000 # HELP container_fs_writes_total Cumulative count of writes completed # TYPE container_fs_writes_total counter -container_fs_writes_total{container_env_foo_env="prod",device="sda1",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 28 1395066363000 -container_fs_writes_total{container_env_foo_env="prod",device="sda2",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 43 1395066363000 +container_fs_writes_total{container_env_foo_env="prod",container_mountpath="",device="sda1",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 28 1395066363000 +container_fs_writes_total{container_env_foo_env="prod",container_mountpath="",device="sda2",host_mountpoint="",id="testcontainer",image="test",name="testcontaineralias",volume_name="",volume_type="",zone_name="hello"} 43 1395066363000 # HELP container_health_state The result of the container's health check # TYPE container_health_state gauge container_health_state{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1 1395066363000 @@ -164,6 +160,18 @@ container_hugetlb_usage_bytes{container_env_foo_env="prod",id="testcontainer",im # HELP container_last_seen Last time a container was seen by the exporter # TYPE container_last_seen gauge container_last_seen{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.395066363e+09 1395066363000 +# HELP container_llc_occupancy_bytes Last level cache usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). +# TYPE container_llc_occupancy_bytes gauge +container_llc_occupancy_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 162626 1395066363000 +container_llc_occupancy_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 213777 1395066363000 +# HELP container_memory_bandwidth_bytes Total memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). +# TYPE container_memory_bandwidth_bytes gauge +container_memory_bandwidth_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 4.512312e+06 1395066363000 +container_memory_bandwidth_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 2.173713e+06 1395066363000 +# HELP container_memory_bandwidth_local_bytes Local memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). +# TYPE container_memory_bandwidth_local_bytes gauge +container_memory_bandwidth_local_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 2.390393e+06 1395066363000 +container_memory_bandwidth_local_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 1.231233e+06 1395066363000 # HELP container_memory_cache Number of bytes of page cache memory. # TYPE container_memory_cache gauge container_memory_cache{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 14 1395066363000 @@ -386,26 +394,26 @@ container_network_udp_usage_total{container_env_foo_env="prod",id="testcontainer # HELP container_oom_events_total Count of out of memory events observed for the container # TYPE container_oom_events_total counter container_oom_events_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0 1395066363000 -# HELP container_perf_events_total Perf event metric. -# TYPE container_perf_events_total counter -container_perf_events_total{container_env_foo_env="prod",cpu="0",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 123 1395066363000 -container_perf_events_total{container_env_foo_env="prod",cpu="0",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 321 1395066363000 -container_perf_events_total{container_env_foo_env="prod",cpu="1",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 456 1395066363000 -container_perf_events_total{container_env_foo_env="prod",cpu="1",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 789 1395066363000 # HELP container_perf_events_scaling_ratio Perf event metric scaling ratio. # TYPE container_perf_events_scaling_ratio gauge container_perf_events_scaling_ratio{container_env_foo_env="prod",cpu="0",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1 1395066363000 container_perf_events_scaling_ratio{container_env_foo_env="prod",cpu="0",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.66666666666 1395066363000 container_perf_events_scaling_ratio{container_env_foo_env="prod",cpu="1",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.5 1395066363000 container_perf_events_scaling_ratio{container_env_foo_env="prod",cpu="1",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.33333333333 1395066363000 -# HELP container_perf_uncore_events_total Perf uncore event metric. -# TYPE container_perf_uncore_events_total counter -container_perf_uncore_events_total{container_env_foo_env="prod",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="0",zone_name="hello"} 1.231231512e+09 1395066363000 -container_perf_uncore_events_total{container_env_foo_env="prod",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="1",zone_name="hello"} 1.111231331e+09 1395066363000 +# HELP container_perf_events_total Perf event metric. +# TYPE container_perf_events_total counter +container_perf_events_total{container_env_foo_env="prod",cpu="0",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 123 1395066363000 +container_perf_events_total{container_env_foo_env="prod",cpu="0",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 321 1395066363000 +container_perf_events_total{container_env_foo_env="prod",cpu="1",event="instructions",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 456 1395066363000 +container_perf_events_total{container_env_foo_env="prod",cpu="1",event="instructions_retired",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 789 1395066363000 # HELP container_perf_uncore_events_scaling_ratio Perf uncore event metric scaling ratio. # TYPE container_perf_uncore_events_scaling_ratio gauge container_perf_uncore_events_scaling_ratio{container_env_foo_env="prod",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="0",zone_name="hello"} 1 1395066363000 container_perf_uncore_events_scaling_ratio{container_env_foo_env="prod",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="1",zone_name="hello"} 1 1395066363000 +# HELP container_perf_uncore_events_total Perf uncore event metric. +# TYPE container_perf_uncore_events_total counter +container_perf_uncore_events_total{container_env_foo_env="prod",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="0",zone_name="hello"} 1.231231512e+09 1395066363000 +container_perf_uncore_events_total{container_env_foo_env="prod",event="cas_count_read",id="testcontainer",image="test",name="testcontaineralias",pmu="uncore_imc_0",socket="1",zone_name="hello"} 1.111231331e+09 1395066363000 # HELP container_pressure_cpu_stalled_seconds_total Total time duration no tasks in the container could make progress due to CPU congestion. # TYPE container_pressure_cpu_stalled_seconds_total counter container_pressure_cpu_stalled_seconds_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0.0001 1395066363000 @@ -464,15 +472,3 @@ container_threads_max{container_env_foo_env="prod",id="testcontainer",image="tes # HELP container_ulimits_soft Soft ulimit values for the container root process. Unlimited if -1, except priority and nice # TYPE container_ulimits_soft gauge container_ulimits_soft{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",ulimit="max_open_files",zone_name="hello"} 16384 1395066363000 -# HELP container_llc_occupancy_bytes Last level cache usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). -# TYPE container_llc_occupancy_bytes gauge -container_llc_occupancy_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 162626 1395066363000 -container_llc_occupancy_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 213777 1395066363000 -# HELP container_memory_bandwidth_bytes Total memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). -# TYPE container_memory_bandwidth_bytes gauge -container_memory_bandwidth_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 4.512312e+06 1395066363000 -container_memory_bandwidth_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 2.173713e+06 1395066363000 -# HELP container_memory_bandwidth_local_bytes Local memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). -# TYPE container_memory_bandwidth_local_bytes gauge -container_memory_bandwidth_local_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="0",zone_name="hello"} 2.390393e+06 1395066363000 -container_memory_bandwidth_local_bytes{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",node_id="1",zone_name="hello"} 1.231233e+06 1395066363000 From 385941ae1632e22fdec9e6f23727e42062c9a4ce Mon Sep 17 00:00:00 2001 From: Great Date: Sat, 16 May 2026 04:06:43 -0400 Subject: [PATCH 07/26] fix: fallback to major:minor format for unrecognized devices in deviceIdentifierMap (#1) Signed-off-by: Umegbewe Nwebedu --- container/common/helpers.go | 4 +++ container/common/helpers_test.go | 61 ++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/container/common/helpers.go b/container/common/helpers.go index 3b3d27f300..69e0adff2b 100644 --- a/container/common/helpers.go +++ b/container/common/helpers.go @@ -437,6 +437,10 @@ func (m deviceIdentifierMap) Find(major, minor uint64, namer DeviceNamer) string return s } s, _ := namer.DeviceName(major, minor) + if s == "" { + s = fmt.Sprintf("%d:%d", major, minor) + } + m[d] = s return s } diff --git a/container/common/helpers_test.go b/container/common/helpers_test.go index db9e13829f..8bb82f3cf6 100644 --- a/container/common/helpers_test.go +++ b/container/common/helpers_test.go @@ -250,6 +250,67 @@ func TestRemoveNetMetrics(t *testing.T) { } } +type deviceNamerFunc func(major, minor uint64) (string, bool) + +func (f deviceNamerFunc) DeviceName(major, minor uint64) (string, bool) { + return f(major, minor) +} + +func TestDeviceIdentifierMapFindFallsBackToMajorMinor(t *testing.T) { + for _, tc := range []struct { + name string + namer DeviceNamer + expected string + }{ + { + name: "unrecognized device", + namer: deviceNamerFunc(func(_, _ uint64) (string, bool) { + return "", false + }), + expected: "8:0", + }, + { + name: "recognized empty device", + namer: deviceNamerFunc(func(_, _ uint64) (string, bool) { + return "", true + }), + expected: "8:0", + }, + { + name: "recognized device", + namer: deviceNamerFunc(func(_, _ uint64) (string, bool) { + return "/dev/sda", true + }), + expected: "/dev/sda", + }, + } { + t.Run(tc.name, func(t *testing.T) { + devices := make(deviceIdentifierMap) + assert.Equal(t, tc.expected, devices.Find(8, 0, tc.namer)) + }) + } +} + +func TestAssignDeviceNamesToDiskStatsKeepsUnresolvedDevicesUnique(t *testing.T) { + stats := &info.DiskIoStats{ + IoServiceBytes: []info.PerDiskStats{ + {Major: 8, Minor: 0}, + {Major: 259, Minor: 1}, + }, + IoServiced: []info.PerDiskStats{ + {Major: 8, Minor: 0}, + }, + } + + AssignDeviceNamesToDiskStats(deviceNamerFunc(func(_, _ uint64) (string, bool) { + return "", false + }), stats) + + assert.Equal(t, "8:0", stats.IoServiceBytes[0].Device) + assert.Equal(t, "259:1", stats.IoServiceBytes[1].Device) + assert.Equal(t, "8:0", stats.IoServiced[0].Device) +} + func BenchmarkGetSpecCgroupV2(b *testing.B) { root, err := os.Getwd() if err != nil { From 4b6ca6789a8097ec726d85809e395931d4af7897 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 16 May 2026 09:08:16 +0100 Subject: [PATCH 08/26] fix: remove fsValues --- metrics/prometheus.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/metrics/prometheus.go b/metrics/prometheus.go index f1f3eece91..1901dd95c6 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -44,19 +44,6 @@ func asNanosecondsToSeconds(v uint64) float64 { return float64(v) / 1e9 } -// fsValues is a helper method for assembling per-filesystem stats. -func fsValues(fsStats []info.FsStats, valueFn func(*info.FsStats) float64, timestamp time.Time) metricValues { - values := make(metricValues, 0, len(fsStats)) - for _, stat := range fsStats { - values = append(values, metricValue{ - value: valueFn(&stat), - labels: []string{stat.Device}, - timestamp: timestamp, - }) - } - return values -} - // ioValues is a helper method for assembling per-disk and per-filesystem stats. func ioValues(ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) float64, fsStats []info.FsStats, valueFn func(*info.FsStats) float64, timestamp time.Time) metricValues { From b1f8581acb9563ad0446eaa60be15270e46285e1 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 16 May 2026 09:09:40 +0100 Subject: [PATCH 09/26] chore: rename module and go mod tidy --- go.mod | 31 +++++++++++++------------ go.sum | 72 +++++++++++++++++++++++++++++++--------------------------- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/go.mod b/go.mod index 53ac3f4ff4..866daeaa38 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ -module github.com/google/cadvisor +module github.com/baselinehq/cadvisor go 1.24.0 require ( - cloud.google.com/go/compute/metadata v0.7.0 + cloud.google.com/go/compute/metadata v0.9.0 github.com/Microsoft/go-winio v0.6.2 github.com/aws/aws-sdk-go-v2/config v1.29.14 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 @@ -11,14 +11,15 @@ require ( github.com/containerd/containerd/api v1.10.0 github.com/containerd/errdefs v1.0.0 github.com/containerd/errdefs/pkg v0.3.0 - github.com/containerd/ttrpc v1.2.7 + github.com/containerd/ttrpc v1.2.8 github.com/containerd/typeurl/v2 v2.2.3 github.com/docker/go-connections v0.6.0 github.com/docker/go-units v0.5.0 github.com/euank/go-kmsg-parser v2.0.0+incompatible + github.com/google/cadvisor v0.57.0 github.com/mistifyio/go-zfs v2.1.1+incompatible - github.com/moby/moby/api v1.52.0 - github.com/moby/moby/client v0.2.1 + github.com/moby/moby/api v1.54.1 + github.com/moby/moby/client v0.4.0 github.com/moby/sys/mountinfo v0.7.2 github.com/opencontainers/cgroups v0.0.6 github.com/opencontainers/runc v1.4.0 @@ -27,9 +28,9 @@ require ( github.com/prometheus/client_model v0.6.2 github.com/prometheus/common v0.64.0 github.com/stretchr/testify v1.11.1 - golang.org/x/sys v0.37.0 - google.golang.org/grpc v1.72.2 - google.golang.org/protobuf v1.36.8 + golang.org/x/sys v0.39.0 + google.golang.org/grpc v1.79.3 + google.golang.org/protobuf v1.36.10 k8s.io/klog/v2 v2.130.1 k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 ) @@ -68,13 +69,13 @@ require ( github.com/prometheus/procfs v0.16.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/stretchr/objx v0.5.2 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.36.0 // indirect - go.opentelemetry.io/otel/metric v1.36.0 // indirect - go.opentelemetry.io/otel/trace v1.36.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f3dc223330..2c33ad2fdf 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= -cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= @@ -42,8 +42,8 @@ github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151X github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ= -github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= +github.com/containerd/ttrpc v1.2.8 h1:xbVu6D4qF2jihdh9rDVOKqUMiFBQk6YctTdo1zk087Y= +github.com/containerd/ttrpc v1.2.8/go.mod h1:wyZW2K79t4Hfcxl+GUvkZqRBzJlqFFvgEeeWXa42tyE= github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= @@ -74,6 +74,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/cadvisor v0.57.0 h1:2LoXUZIJPR3VQJC1bZmqAGdh09yPfpS7MEeC4fJy80k= +github.com/google/cadvisor v0.57.0/go.mod h1:z6bozbhp/EAWhJqF6KK78MESLoeAhi7pJ9g7fRYGPEc= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -90,10 +92,10 @@ github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJd github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= -github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= -github.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k= -github.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE= +github.com/moby/moby/api v1.54.1 h1:TqVzuJkOLsgLDDwNLmYqACUuTehOHRGKiPhvH8V3Nn4= +github.com/moby/moby/api v1.54.1/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.0 h1:S+2XegzHQrrvTCvF6s5HFzcrywWQmuVnhOXe2kiWjIw= +github.com/moby/moby/client v0.4.0/go.mod h1:QWPbvWchQbxBNdaLSpoKpCdf5E+WxFAgNHogCWDoa7g= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= @@ -120,8 +122,8 @@ github.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQP github.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -132,20 +134,20 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -155,8 +157,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -164,12 +166,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -178,12 +180,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= -google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From b76146ce92294cf46bd3c3ffd55d50f0dd35eeaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Bod=C3=A1n?= Date: Thu, 5 Mar 2026 15:45:28 +0100 Subject: [PATCH 10/26] Fix start/creation time metrics in docker, podman and containerd Add container_creation_time_seconds and keep container_start_time_seconds as runtime start time. Fixed for: - docker - podman - containerd --- container/containerd/client.go | 5 +++++ container/containerd/handler.go | 12 +++++++++++ container/docker/handler.go | 11 ++++++++++ container/podman/handler.go | 13 ++++++++++++ info/v1/container.go | 10 +++++++++ info/v2/container.go | 4 ++++ info/v2/conversion.go | 1 + info/v2/conversion_test.go | 3 +++ metrics/prometheus.go | 21 +++++++++++++------ metrics/prometheus_fake.go | 1 + metrics/testdata/prometheus_metrics | 5 ++++- .../prometheus_metrics_perf_aggregated | 5 ++++- .../prometheus_metrics_whitelist_filtered | 5 ++++- 13 files changed, 87 insertions(+), 9 deletions(-) diff --git a/container/containerd/client.go b/container/containerd/client.go index e568eb7f77..c538e102fb 100644 --- a/container/containerd/client.go +++ b/container/containerd/client.go @@ -168,6 +168,7 @@ func (c *client) Version(ctx context.Context) (string, error) { func containerFromProto(containerpb *containersapi.Container) *containers.Container { var runtime containers.RuntimeInfo + var createdAt time.Time // TODO: is nil check required for containerpb if containerpb.Runtime != nil { runtime = containers.RuntimeInfo{ @@ -175,6 +176,9 @@ func containerFromProto(containerpb *containersapi.Container) *containers.Contai Options: containerpb.Runtime.Options, } } + if containerpb.GetCreatedAt() != nil { + createdAt = containerpb.GetCreatedAt().AsTime() + } return &containers.Container{ ID: containerpb.ID, Labels: containerpb.Labels, @@ -184,5 +188,6 @@ func containerFromProto(containerpb *containersapi.Container) *containers.Contai Snapshotter: containerpb.Snapshotter, SnapshotKey: containerpb.SnapshotKey, Extensions: containerpb.Extensions, + CreatedAt: createdAt, } } diff --git a/container/containerd/handler.go b/container/containerd/handler.go index 0fd69e253f..e91e894dc6 100644 --- a/container/containerd/handler.go +++ b/container/containerd/handler.go @@ -46,6 +46,8 @@ type containerdContainerHandler struct { reference info.ContainerReference envs map[string]string labels map[string]string + // Time at which this container was created. + creationTime time.Time // Image name used for this container. image string // Filesystem handler. @@ -148,6 +150,9 @@ func newContainerdContainerHandler( libcontainerHandler: libcontainerHandler, client: client, } + if !cntr.CreatedAt.IsZero() && !cntr.CreatedAt.Before(time.Unix(0, 0)) { + handler.creationTime = cntr.CreatedAt + } // Add the name and bare ID as aliases of the container. handler.image = cntr.Image @@ -183,6 +188,13 @@ func (h *containerdContainerHandler) GetSpec() (info.ContainerSpec, error) { spec.Labels = h.labels spec.Envs = h.envs spec.Image = h.image + startTime := spec.CreationTime + if !h.creationTime.IsZero() { + spec.CreationTime = h.creationTime + } + if !startTime.IsZero() { + spec.StartTime = startTime + } return spec, err } diff --git a/container/docker/handler.go b/container/docker/handler.go index 8ddc2c93c5..806559e474 100644 --- a/container/docker/handler.go +++ b/container/docker/handler.go @@ -71,6 +71,9 @@ type containerHandler struct { // Time at which this container was created. creationTime time.Time + // Time at which this container was started. + startTime time.Time + // Metadata associated with the container. envs map[string]string labels map[string]string @@ -247,6 +250,13 @@ func newContainerHandler( return nil, fmt.Errorf("failed to parse the create timestamp %q for container %q: %v", ctnr.Created, id, err) } + // StartedAt may be unset for containers that never started. + if startedAt := ctnr.State.StartedAt; startedAt != "" { + if t, err := time.Parse(time.RFC3339Nano, startedAt); err == nil && !t.Before(time.Unix(0, 0)) { + handler.startTime = t + } + } + if ctnr.RestartCount > 0 { handler.labels["restartcount"] = strconv.Itoa(ctnr.RestartCount) } @@ -326,6 +336,7 @@ func (h *containerHandler) GetSpec() (info.ContainerSpec, error) { spec.Envs = h.envs spec.Image = h.image spec.CreationTime = h.creationTime + spec.StartTime = h.startTime return spec, nil } diff --git a/container/podman/handler.go b/container/podman/handler.go index 0eee88f5fc..352686aba8 100644 --- a/container/podman/handler.go +++ b/container/podman/handler.go @@ -55,6 +55,9 @@ type containerHandler struct { // Time at which this container was created. creationTime time.Time + // Time at which this container was started. + startTime time.Time + // Metadata associated with the container. envs map[string]string labels map[string]string @@ -190,6 +193,15 @@ func newContainerHandler( return nil, fmt.Errorf("failed to parse the create timestamp %q for container %q: %v", ctnr.Created, id, err) } + // StartedAt may be unset for containers that never started. + if startedAt := ctnr.State.StartedAt; startedAt != "" { + if t, err := time.Parse(time.RFC3339Nano, startedAt); err == nil && !t.Before(time.Unix(0, 0)) { + handler.startTime = t + } else if t, err := time.Parse(time.RFC3339, startedAt); err == nil && !t.Before(time.Unix(0, 0)) { + handler.startTime = t + } + } + if ctnr.RestartCount > 0 { handler.labels["restartcount"] = strconv.Itoa(ctnr.RestartCount) } @@ -259,6 +271,7 @@ func (h *containerHandler) GetSpec() (info.ContainerSpec, error) { spec.Envs = h.envs spec.Image = h.image spec.CreationTime = h.creationTime + spec.StartTime = h.startTime return spec, nil } diff --git a/info/v1/container.go b/info/v1/container.go index 823415cd74..0b26b612e4 100644 --- a/info/v1/container.go +++ b/info/v1/container.go @@ -49,6 +49,10 @@ type ContainerSpec struct { // Time at which the container was created. CreationTime time.Time `json:"creation_time,omitempty"` + // Time at which the container was started. + // This may be unset if the runtime does not provide it. + StartTime time.Time `json:"start_time,omitempty"` + // Metadata labels associated with this container. Labels map[string]string `json:"labels,omitempty"` // Metadata envs associated with this container. Only whitelisted envs are added. @@ -190,6 +194,12 @@ func (s *ContainerSpec) Eq(b *ContainerSpec) bool { return false } + // Start time within 1s of each other. + startDiff := s.StartTime.Sub(b.StartTime) + if (startDiff > time.Second) || (startDiff < -time.Second) { + return false + } + if s.HasCpu != b.HasCpu { return false } diff --git a/info/v2/container.go b/info/v2/container.go index 7f9c1c1891..f922a8ddc8 100644 --- a/info/v2/container.go +++ b/info/v2/container.go @@ -69,6 +69,10 @@ type ContainerSpec struct { // Time at which the container was created. CreationTime time.Time `json:"creation_time,omitempty"` + // Time at which the container was started. + // This may be unset if the runtime does not provide it. + StartTime time.Time `json:"start_time,omitempty"` + // Other names by which the container is known within a certain namespace. // This is unique within that namespace. Aliases []string `json:"aliases,omitempty"` diff --git a/info/v2/conversion.go b/info/v2/conversion.go index 41da7ea4a9..577335cc02 100644 --- a/info/v2/conversion.go +++ b/info/v2/conversion.go @@ -285,6 +285,7 @@ func InstCpuStats(last, cur *v1.ContainerStats) (*CpuInstStats, error) { func ContainerSpecFromV1(specV1 *v1.ContainerSpec, aliases []string, namespace string) ContainerSpec { specV2 := ContainerSpec{ CreationTime: specV1.CreationTime, + StartTime: specV1.StartTime, HasCpu: specV1.HasCpu, HasMemory: specV1.HasMemory, HasHugetlb: specV1.HasHugetlb, diff --git a/info/v2/conversion_test.go b/info/v2/conversion_test.go index ca470e9480..c360dc7118 100644 --- a/info/v2/conversion_test.go +++ b/info/v2/conversion_test.go @@ -31,8 +31,10 @@ var ( ) func TestContainerSpecFromV1(t *testing.T) { + startTime := timestamp.Add(1 * time.Hour) v1Spec := v1.ContainerSpec{ CreationTime: timestamp, + StartTime: startTime, Labels: labels, Envs: envs, HasCpu: true, @@ -67,6 +69,7 @@ func TestContainerSpecFromV1(t *testing.T) { expectedV2Spec := ContainerSpec{ CreationTime: timestamp, + StartTime: startTime, Labels: labels, Envs: envs, HasCpu: true, diff --git a/metrics/prometheus.go b/metrics/prometheus.go index 1901dd95c6..da34cdc5d3 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -2027,11 +2027,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri } var ( - versionInfoDesc = prometheus.NewDesc("cadvisor_version_info", "A metric with a constant '1' value labeled by kernel version, OS version, docker version, cadvisor version & cadvisor revision.", []string{"kernelVersion", "osVersion", "dockerVersion", "cadvisorVersion", "cadvisorRevision"}, nil) - startTimeDesc = prometheus.NewDesc("container_start_time_seconds", "Start time of the container since unix epoch in seconds.", nil, nil) - cpuPeriodDesc = prometheus.NewDesc("container_spec_cpu_period", "CPU period of the container.", nil, nil) - cpuQuotaDesc = prometheus.NewDesc("container_spec_cpu_quota", "CPU quota of the container.", nil, nil) - cpuSharesDesc = prometheus.NewDesc("container_spec_cpu_shares", "CPU share of the container.", nil, nil) + versionInfoDesc = prometheus.NewDesc("cadvisor_version_info", "A metric with a constant '1' value labeled by kernel version, OS version, docker version, cadvisor version & cadvisor revision.", []string{"kernelVersion", "osVersion", "dockerVersion", "cadvisorVersion", "cadvisorRevision"}, nil) + creationTimeDesc = prometheus.NewDesc("container_creation_time_seconds", "Container creation time since unix epoch in seconds.", nil, nil) + startTimeDesc = prometheus.NewDesc("container_start_time_seconds", "Start time of the container since unix epoch in seconds.", nil, nil) + cpuPeriodDesc = prometheus.NewDesc("container_spec_cpu_period", "CPU period of the container.", nil, nil) + cpuQuotaDesc = prometheus.NewDesc("container_spec_cpu_quota", "CPU quota of the container.", nil, nil) + cpuSharesDesc = prometheus.NewDesc("container_spec_cpu_shares", "CPU share of the container.", nil, nil) ) // Describe describes all the metrics ever exported by cadvisor. It @@ -2041,6 +2042,7 @@ func (c *PrometheusCollector) Describe(ch chan<- *prometheus.Desc) { for _, cm := range c.containerMetrics { ch <- cm.desc([]string{}) } + ch <- creationTimeDesc ch <- startTimeDesc ch <- cpuPeriodDesc ch <- cpuQuotaDesc @@ -2152,9 +2154,16 @@ func (c *PrometheusCollector) collectContainersInfo(ch chan<- prometheus.Metric) } // Container spec - desc := prometheus.NewDesc("container_start_time_seconds", "Start time of the container since unix epoch in seconds.", labels, nil) + desc := prometheus.NewDesc("container_creation_time_seconds", "Container creation time since unix epoch in seconds.", labels, nil) ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(cont.Spec.CreationTime.Unix()), values...) + desc = prometheus.NewDesc("container_start_time_seconds", "Start time of the container since unix epoch in seconds.", labels, nil) + startTime := cont.Spec.CreationTime + if !cont.Spec.StartTime.IsZero() { + startTime = cont.Spec.StartTime + } + ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(startTime.Unix()), values...) + if cont.Spec.HasCpu { desc = prometheus.NewDesc("container_spec_cpu_period", "CPU period of the container.", labels, nil) ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(cont.Spec.Cpu.Period), values...) diff --git a/metrics/prometheus_fake.go b/metrics/prometheus_fake.go index ab48cce860..7c8c99e095 100644 --- a/metrics/prometheus_fake.go +++ b/metrics/prometheus_fake.go @@ -299,6 +299,7 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req Limit: 100, }, CreationTime: time.Unix(1257894000, 0), + StartTime: time.Unix(1257895000, 0), Labels: map[string]string{ "foo.label": "bar", }, diff --git a/metrics/testdata/prometheus_metrics b/metrics/testdata/prometheus_metrics index 7f751bca2f..fc7738afad 100644 --- a/metrics/testdata/prometheus_metrics +++ b/metrics/testdata/prometheus_metrics @@ -453,9 +453,12 @@ container_spec_cpu_quota{container_env_foo_env="prod",container_label_foo_label= # HELP container_spec_cpu_shares CPU share of the container. # TYPE container_spec_cpu_shares gauge container_spec_cpu_shares{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1000 +# HELP container_creation_time_seconds Container creation time since unix epoch in seconds. +# TYPE container_creation_time_seconds gauge +container_creation_time_seconds{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257894e+09 # HELP container_start_time_seconds Start time of the container since unix epoch in seconds. # TYPE container_start_time_seconds gauge -container_start_time_seconds{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257894e+09 +container_start_time_seconds{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257895e+09 # HELP container_tasks_state Number of tasks in given state # TYPE container_tasks_state gauge container_tasks_state{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",state="iowaiting",zone_name="hello"} 54 1395066363000 diff --git a/metrics/testdata/prometheus_metrics_perf_aggregated b/metrics/testdata/prometheus_metrics_perf_aggregated index fd3647529f..14fb56342a 100644 --- a/metrics/testdata/prometheus_metrics_perf_aggregated +++ b/metrics/testdata/prometheus_metrics_perf_aggregated @@ -35,6 +35,9 @@ container_spec_cpu_quota{container_env_foo_env="prod",container_label_foo_label= # HELP container_spec_cpu_shares CPU share of the container. # TYPE container_spec_cpu_shares gauge container_spec_cpu_shares{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1000 +# HELP container_creation_time_seconds Container creation time since unix epoch in seconds. +# TYPE container_creation_time_seconds gauge +container_creation_time_seconds{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257894e+09 # HELP container_start_time_seconds Start time of the container since unix epoch in seconds. # TYPE container_start_time_seconds gauge -container_start_time_seconds{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257894e+09 +container_start_time_seconds{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257895e+09 diff --git a/metrics/testdata/prometheus_metrics_whitelist_filtered b/metrics/testdata/prometheus_metrics_whitelist_filtered index f7f14ab483..25fb529959 100644 --- a/metrics/testdata/prometheus_metrics_whitelist_filtered +++ b/metrics/testdata/prometheus_metrics_whitelist_filtered @@ -453,9 +453,12 @@ container_spec_cpu_quota{container_env_foo_env="prod",id="testcontainer",image=" # HELP container_spec_cpu_shares CPU share of the container. # TYPE container_spec_cpu_shares gauge container_spec_cpu_shares{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1000 +# HELP container_creation_time_seconds Container creation time since unix epoch in seconds. +# TYPE container_creation_time_seconds gauge +container_creation_time_seconds{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257894e+09 # HELP container_start_time_seconds Start time of the container since unix epoch in seconds. # TYPE container_start_time_seconds gauge -container_start_time_seconds{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257894e+09 +container_start_time_seconds{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 1.257895e+09 # HELP container_tasks_state Number of tasks in given state # TYPE container_tasks_state gauge container_tasks_state{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",state="iowaiting",zone_name="hello"} 54 1395066363000 From 2f0f2fa54a2fa27dac39141890d99cadb870ef5c Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 10 Apr 2026 09:21:37 +0200 Subject: [PATCH 11/26] deps: bump github.com/containerd/ttrpc v1.2.8 fixes a panic when a streamid sent to the server is not found; the send status will return and then panic attempting to convert nil to a stream handler. full diff: https://github.com/containerd/ttrpc/compare/v1.2.7...v1.2.8 Signed-off-by: Sebastiaan van Stijn --- cmd/go.mod | 2 +- cmd/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/go.mod b/cmd/go.mod index 7fe3539e3e..5eeb5c3d63 100644 --- a/cmd/go.mod +++ b/cmd/go.mod @@ -53,7 +53,7 @@ require ( github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/log v0.1.0 // indirect - github.com/containerd/ttrpc v1.2.7 // indirect + github.com/containerd/ttrpc v1.2.8 // indirect github.com/containerd/typeurl/v2 v2.2.3 // indirect github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/cyphar/filepath-securejoin v0.6.1 // indirect diff --git a/cmd/go.sum b/cmd/go.sum index 6b8fea7d88..b1ed5d4e4f 100644 --- a/cmd/go.sum +++ b/cmd/go.sum @@ -60,8 +60,8 @@ github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151X github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ= -github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= +github.com/containerd/ttrpc v1.2.8 h1:xbVu6D4qF2jihdh9rDVOKqUMiFBQk6YctTdo1zk087Y= +github.com/containerd/ttrpc v1.2.8/go.mod h1:wyZW2K79t4Hfcxl+GUvkZqRBzJlqFFvgEeeWXa42tyE= github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= From 45ec1d7cb0f7320a4ed21638cb61df1918794349 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 10 Apr 2026 09:35:35 +0200 Subject: [PATCH 12/26] deps: github.com/moby/moby/client v0.4.0, moby/api v1.54.1 Adds back support for API v1.40 and up (docker 19.03 daemons and newer). Signed-off-by: Sebastiaan van Stijn --- cmd/go.mod | 4 ++-- cmd/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/go.mod b/cmd/go.mod index 5eeb5c3d63..a54f06ef2f 100644 --- a/cmd/go.mod +++ b/cmd/go.mod @@ -87,8 +87,8 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/moby/api v1.52.0 // indirect - github.com/moby/moby/client v0.2.1 // indirect + github.com/moby/moby/api v1.54.1 // indirect + github.com/moby/moby/client v0.4.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect diff --git a/cmd/go.sum b/cmd/go.sum index b1ed5d4e4f..580e44bed0 100644 --- a/cmd/go.sum +++ b/cmd/go.sum @@ -179,10 +179,10 @@ 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/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= -github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= -github.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k= -github.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE= +github.com/moby/moby/api v1.54.1 h1:TqVzuJkOLsgLDDwNLmYqACUuTehOHRGKiPhvH8V3Nn4= +github.com/moby/moby/api v1.54.1/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.0 h1:S+2XegzHQrrvTCvF6s5HFzcrywWQmuVnhOXe2kiWjIw= +github.com/moby/moby/client v0.4.0/go.mod h1:QWPbvWchQbxBNdaLSpoKpCdf5E+WxFAgNHogCWDoa7g= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= From d00f0acda085b54aaeb8525ab10231a7fae551a2 Mon Sep 17 00:00:00 2001 From: Sambhav Jain Date: Mon, 13 Apr 2026 13:17:36 +0000 Subject: [PATCH 13/26] update k8s-staging-test-infra image in integ tests --- build/integration-in-docker-crio.sh | 2 +- build/integration-in-docker.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/integration-in-docker-crio.sh b/build/integration-in-docker-crio.sh index b4683f4291..980134f5ce 100755 --- a/build/integration-in-docker-crio.sh +++ b/build/integration-in-docker-crio.sh @@ -76,7 +76,7 @@ function run_tests() { --cgroupns=host \ --pid=host \ --entrypoint="" \ - gcr.io/k8s-staging-test-infra/bootstrap:v20250702-52f5173c3a \ + gcr.io/k8s-staging-test-infra/bootstrap:v20251209-855adc2699 \ bash -c "export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ apt-get install -y $PACKAGES curl conntrack iptables dbus && \ diff --git a/build/integration-in-docker.sh b/build/integration-in-docker.sh index fcd6b56398..54a0234e6f 100755 --- a/build/integration-in-docker.sh +++ b/build/integration-in-docker.sh @@ -61,7 +61,7 @@ function run_tests() { --privileged \ --cap-add="sys_admin" \ --entrypoint="" \ - gcr.io/k8s-staging-test-infra/bootstrap:v20250702-52f5173c3a \ + gcr.io/k8s-staging-test-infra/bootstrap:v20251209-855adc2699 \ bash -c "export DEBIAN_FRONTEND=noninteractive && \ apt update && \ apt install -y $PACKAGES && \ From 36770debd1bb82d8c487869689950603379c0f57 Mon Sep 17 00:00:00 2001 From: Sambhav Jain Date: Tue, 14 Apr 2026 10:50:59 +0000 Subject: [PATCH 14/26] fix(test/integration): fix TestDockerContainerSpec --- integration/tests/api/docker_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/integration/tests/api/docker_test.go b/integration/tests/api/docker_test.go index be3c9e6ac6..5e754d86b0 100644 --- a/integration/tests/api/docker_test.go +++ b/integration/tests/api/docker_test.go @@ -215,14 +215,14 @@ func TestDockerContainerSpec(t *testing.T) { assert.True(containerInfo.Spec.HasCpu, "CPU should be isolated") if cgroups.IsCgroup2UnifiedMode() { - // cpu shares are rounded slightly on cgroupv2 due to conversion between cgroupv1 (cpu.shares) and cgroupv2 (cpu.weight) - // When container is created via docker, runc will convert cpu shares to cpu.weight https://github.com/opencontainers/runc/blob/d11f4d756e85ece5cdba8bb69f8bd4db3cdcbeab/libcontainer/cgroups/utils.go#L423-L428 + // cpu shares are converted on cgroupv2 due to conversion between cgroupv1 (cpu.shares) and cgroupv2 (cpu.weight) + // When container is created via docker, runc will convert cpu shares to cpu.weight using a log2-based quadratic formula https://github.com/opencontainers/cgroups/blob/v0.0.6/utils.go#L405-L427 // And cAdvisor will convert cpu.weight back to cpu shares in https://github.com/google/cadvisor/blob/24e7a9883d12f944fd4403861707f4bafcaf4f3d/container/common/helpers.go#L249-L260 // Worked example: // cpuShares = 2048 (input to docker --cpu-shares) - // cpuWeight = int((1 + ((cpuShares-2)*9999)/262142))=79 (conversion done by runc) - // cpuWeight back to cpuShares = int(2 + ((cpuWeight-1)*262142)/9999)= 2046 - var cgroupV2Shares uint64 = 2046 + // l = log2(2048) = 11; exponent = (l*l + 125*l)/612 - 7/34 = 2.2386; cpuWeight = ceil(10^exponent) = 174 (conversion done by runc) + // cpuWeight back to cpuShares = int(2 + ((cpuWeight-1)*262142)/9999)= 4537 + var cgroupV2Shares uint64 = 4537 assert.Equal(cgroupV2Shares, containerInfo.Spec.Cpu.Limit, "Container should have %d shares, has %d", cgroupV2Shares, containerInfo.Spec.Cpu.Limit) } else { assert.Equal(cpuShares, containerInfo.Spec.Cpu.Limit, "Container should have %d shares, has %d", cpuShares, containerInfo.Spec.Cpu.Limit) From 98375a05572885bd4496b29087295addb30ad7b5 Mon Sep 17 00:00:00 2001 From: Sambhav Jain Date: Wed, 1 Apr 2026 16:22:54 +0000 Subject: [PATCH 15/26] feat(manager): add constraint data in OOM events --- info/v1/container.go | 3 +++ manager/manager.go | 1 + 2 files changed, 4 insertions(+) diff --git a/info/v1/container.go b/info/v1/container.go index 0b26b612e4..0f6ffc59d4 100644 --- a/info/v1/container.go +++ b/info/v1/container.go @@ -1149,6 +1149,9 @@ type OomKillEventData struct { // The name of the killed process ProcessName string `json:"process_name"` + + // the constraint that triggered the OOM + Constraint string `json:"constraint"` } // Information related to a container deletion event diff --git a/manager/manager.go b/manager/manager.go index 0ea1f297d8..f0f9cd1f89 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -1238,6 +1238,7 @@ func (m *manager) watchForNewOoms() error { OomKill: &info.OomKillEventData{ Pid: oomInstance.Pid, ProcessName: oomInstance.ProcessName, + Constraint: oomInstance.Constraint, }, }, } From b481ab1b84ddde16cf8b6632dddae464defd9435 Mon Sep 17 00:00:00 2001 From: Sambhav Jain Date: Thu, 2 Apr 2026 08:56:52 +0000 Subject: [PATCH 16/26] test(integration): add integration test for oom constraint --- integration/tests/api/event_test.go | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/integration/tests/api/event_test.go b/integration/tests/api/event_test.go index 52c0bb695d..786668bbce 100644 --- a/integration/tests/api/event_test.go +++ b/integration/tests/api/event_test.go @@ -66,6 +66,58 @@ func TestStreamingEventInformationIsReturned(t *testing.T) { waitForStaticEvent(containerID, "?creation_events=true&subcontainers=true", t, fm, info.EventContainerCreation) } +func TestOomKillEventConstraint(t *testing.T) { + tests := []struct { + name string + memLimit string + wantConstraint string + }{ + { + name: "memory cgroup constraint", + memLimit: "8M", + wantConstraint: "CONSTRAINT_MEMCG", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fm := framework.New(t) + defer fm.Cleanup() + + containerID := fm.Docker().Run( + framework.DockerRunArgs{ + Image: "registry.k8s.io/busybox:1.27", + Args: []string{"-m=" + tt.memLimit}, + }, + "sh", "-c", "a=1; while true; do a=\"${a}${a}\"; done", + ) + + err := framework.RetryForDuration(func() error { + events, err := fm.Cadvisor().Client().EventStaticInfo("?oom_kill_events=true&subcontainers=true") + if err != nil { + return err + } + for _, ev := range events { + if ev.EventType == info.EventOomKill && + strings.Contains(ev.ContainerName, containerID) { + if ev.EventData.OomKill == nil { + return fmt.Errorf("OOM kill event data is nil") + } + if ev.EventData.OomKill.Constraint != tt.wantConstraint { + t.Errorf("expected constraint %q, got %q", + tt.wantConstraint, ev.EventData.OomKill.Constraint) + } + return nil + } + } + return fmt.Errorf("OOM kill event not found for container %s", containerID) + }, 30*time.Second) + + require.NoError(t, err) + }) + } +} + func waitForStaticEvent(containerID string, urlRequest string, t *testing.T, fm framework.Framework, typeEvent info.EventType) { einfo, err := fm.Cadvisor().Client().EventStaticInfo(urlRequest) require.NoError(t, err) From 23badf15236f9585e6d7fe678b3845eb434227ef Mon Sep 17 00:00:00 2001 From: Sambhav Jain Date: Tue, 17 Mar 2026 13:59:31 +0000 Subject: [PATCH 17/26] add initial splay and max jitter factors --- manager/container.go | 27 +++++++++++++++----- manager/container_test.go | 53 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/manager/container.go b/manager/container.go index 5020e945b2..a50d728e0f 100644 --- a/manager/container.go +++ b/manager/container.go @@ -47,9 +47,13 @@ import ( "k8s.io/utils/clock" ) +const jitterDefault = 1.0 + // Housekeeping interval. var enableLoadReader = flag.Bool("enable_load_reader", false, "Whether to enable cpu load reader") var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second, "Interval between container housekeepings") +var InitialSplayFactor = flag.Float64("initial_splay_factor", jitterDefault, "Factor for the initial splay b/w the container housekeepings, default is 1.0. If negative value is passed, the value will be reset to default") +var JitterFactor = flag.Float64("jitter_factor", jitterDefault, "Factor for the jitters after the initial splay b/w the container housekeepings, default is 1.0. If negative value is passed, the value will be reset to default") // TODO: replace regular expressions with something simpler, such as strings.Split(). // cgroup type chosen to fetch the cgroup path of a process. @@ -91,6 +95,9 @@ type containerData struct { housekeepingInterval time.Duration maxHousekeepingInterval time.Duration allowDynamicHousekeeping bool + firstHousekeeping bool + initialSplayFactor float64 + jitterFactor float64 infoLastUpdatedTime atomicTime // Unix nano statsLastUpdatedTime atomicTime // Unix nano lastErrorTime time.Time @@ -121,11 +128,11 @@ type containerData struct { } // jitter returns a time.Duration between duration and duration + maxFactor * duration, -// to allow clients to avoid converging on periodic behavior. If maxFactor is 0.0, a -// suggested default value will be chosen. +// to allow clients to avoid converging on periodic behavior. If maxFactor is 0.0, no +// jitter is applied. If maxFactor is negative, a suggested default value will be chosen. func jitter(duration time.Duration, maxFactor float64) time.Duration { - if maxFactor <= 0.0 { - maxFactor = 1.0 + if maxFactor < 0.0 { + maxFactor = jitterDefault } wait := duration + time.Duration(rand.Float64()*maxFactor*float64(duration)) return wait @@ -458,6 +465,9 @@ func newContainerData(containerName string, memoryCache *memory.InMemoryCache, h housekeepingInterval: *HousekeepingInterval, maxHousekeepingInterval: maxHousekeepingInterval, allowDynamicHousekeeping: allowDynamicHousekeeping, + firstHousekeeping: true, + initialSplayFactor: *InitialSplayFactor, + jitterFactor: *JitterFactor, logUsage: logUsage, loadAvg: -1.0, // negative value indicates uninitialized. loadDAvg: -1.0, // negative value indicates uninitialized. @@ -491,7 +501,6 @@ func newContainerData(containerName string, memoryCache *memory.InMemoryCache, h cont.summaryReader = nil klog.V(5).Infof("Failed to create summary reader for %q: %v", ref.Name, err) } - return cont, nil } @@ -519,7 +528,13 @@ func (cd *containerData) nextHousekeepingInterval() time.Duration { } } - return jitter(cd.housekeepingInterval, 1.0) + jitterFactor := cd.jitterFactor + if cd.firstHousekeeping { + jitterFactor = cd.initialSplayFactor + cd.firstHousekeeping = false + } + + return jitter(cd.housekeepingInterval, jitterFactor) } // TODO(vmarmol): Implement stats collecting as a custom collector. diff --git a/manager/container_test.go b/manager/container_test.go index 892f4b6c87..f4f68f8185 100644 --- a/manager/container_test.go +++ b/manager/container_test.go @@ -538,3 +538,56 @@ func TestGetCgroupPath(t *testing.T) { }) } } + +func TestNextHousekeepingInterval(t *testing.T) { + base := 1 * time.Second + tests := []struct { + name string + splayFactor float64 + jitterFactor float64 + firstHousekeeping bool + expectedMin time.Duration + expectedMax time.Duration + }{ + { + name: "first housekeeping uses splay factor", + splayFactor: 2.0, + jitterFactor: 1.0, + firstHousekeeping: true, + expectedMin: base, + expectedMax: base + time.Duration(2.0*float64(base)), + }, + { + name: "subsequent housekeeping uses jitter factor", + splayFactor: 1.0, + jitterFactor: 0.5, + firstHousekeeping: false, + expectedMin: base, + expectedMax: base + time.Duration(0.5*float64(base)), + }, + { + name: "zero jitter factor results in no jitter", + splayFactor: 1.0, + jitterFactor: 0.0, + firstHousekeeping: false, + expectedMin: base, + expectedMax: base, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + cd, _, _, _ := newTestContainerData(t) + cd.allowDynamicHousekeeping = false + cd.housekeepingInterval = base + cd.firstHousekeeping = tc.firstHousekeeping + cd.initialSplayFactor = tc.splayFactor + cd.jitterFactor = tc.jitterFactor + + got := cd.nextHousekeepingInterval() + assert.GreaterOrEqual(t, got, tc.expectedMin) + assert.LessOrEqual(t, got, tc.expectedMax) + assert.False(t, cd.firstHousekeeping) + }) + } +} From 097d28e5551c17fa0ad9a92fe9b80057ab8218e8 Mon Sep 17 00:00:00 2001 From: hwan515 Date: Fri, 27 Mar 2026 01:29:54 +0900 Subject: [PATCH 18/26] fix: add v-prefixed GHCR image tags for consistency with GitHub Releases GitHub Releases use v-prefixed tags (e.g. v0.55.1), but GHCR image tags only have the bare version (e.g. 0.55.1). This causes users to get "not found" errors when they use the release tag directly in docker pull. Add `type=semver,pattern=v{{version}}` so both `0.55.1` and `v0.55.1` tags are published, matching user expectations. Fixes #3856 --- .github/workflows/publish-container.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish-container.yml b/.github/workflows/publish-container.yml index 69ae73fc30..dd6fe2bfaa 100644 --- a/.github/workflows/publish-container.yml +++ b/.github/workflows/publish-container.yml @@ -54,6 +54,7 @@ jobs: images: ghcr.io/${{ github.repository }} tags: | type=semver,pattern={{version}} + type=semver,pattern=v{{version}} type=semver,pattern={{major}}.{{minor}} type=raw,value=latest,enable=${{ github.event_name != 'workflow_dispatch' && github.ref == format('refs/tags/{0}', github.ref_name) }} type=raw,value=${{ github.event.inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' }} From 5192f92a504d21b325ddce360139345599b6d1be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 02:06:16 +0000 Subject: [PATCH 19/26] build(deps): bump the go_modules group across 2 directories with 1 update Bumps the go_modules group with 1 update in the / directory: [google.golang.org/grpc](https://github.com/grpc/grpc-go). Bumps the go_modules group with 1 update in the /cmd directory: [google.golang.org/grpc](https://github.com/grpc/grpc-go). Updates `google.golang.org/grpc` from 1.72.2 to 1.79.3 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.72.2...v1.79.3) Updates `google.golang.org/grpc` from 1.72.2 to 1.79.3 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.72.2...v1.79.3) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-version: 1.79.3 dependency-type: direct:production dependency-group: go_modules - dependency-name: google.golang.org/grpc dependency-version: 1.79.3 dependency-type: indirect dependency-group: go_modules ... Signed-off-by: dependabot[bot] --- cmd/go.mod | 25 ++++++++++--------- cmd/go.sum | 70 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/cmd/go.mod b/cmd/go.mod index a54f06ef2f..19babfafbc 100644 --- a/cmd/go.mod +++ b/cmd/go.mod @@ -21,7 +21,7 @@ require ( github.com/onsi/gomega v1.24.1 // indirect github.com/prometheus/client_golang v1.22.0 github.com/stretchr/testify v1.11.1 - golang.org/x/oauth2 v0.30.0 + golang.org/x/oauth2 v0.34.0 google.golang.org/api v0.235.0 gopkg.in/olivere/elastic.v2 v2.0.61 k8s.io/klog/v2 v2.130.1 @@ -31,7 +31,7 @@ require ( require ( cloud.google.com/go/auth v0.16.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.7.0 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect github.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect @@ -105,19 +105,18 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/stretchr/objx v0.5.2 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.36.0 // indirect - go.opentelemetry.io/otel/metric v1.36.0 // indirect - go.opentelemetry.io/otel/trace v1.36.0 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sync v0.19.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/net v0.48.0 // indirect golang.org/x/sys v0.39.0 // indirect golang.org/x/telemetry v0.0.0-20251215142616-e75fd47794af // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect - google.golang.org/grpc v1.72.2 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/cmd/go.sum b/cmd/go.sum index 580e44bed0..aa10e9d81f 100644 --- a/cmd/go.sum +++ b/cmd/go.sum @@ -2,8 +2,8 @@ cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU= cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= -cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= -cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/SeanDolphin/bqschema v1.0.0 h1:iCYFd5Qsw6caM2k5/SsITSL9+3kQCr+oz6pnNjWTq90= @@ -228,8 +228,8 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg= github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -256,20 +256,20 @@ github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6Ut github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= @@ -281,8 +281,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -301,10 +301,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -338,40 +338,42 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.235.0 h1:C3MkpQSRxS1Jy6AkzTGKKrpSCOd2WOGrezZ+icKSkKo= google.golang.org/api v0.235.0/go.mod h1:QpeJkemzkFKe5VCE/PMv7GsUfn9ZF+u+q1Q7w6ckxTg= google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78= google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= -google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0= -google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= -google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From c20473b2b95919068d28e23e7e8ab8e91a53a594 Mon Sep 17 00:00:00 2001 From: Sohan Kunkerkar Date: Thu, 7 May 2026 00:31:45 -0400 Subject: [PATCH 20/26] Expose cgroup v2 memory.events as Prometheus metrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kubernetes KEP-2570 (MemoryQoS) uses cgroup v2 memory.high for throttling and memory.min/memory.low for memory protection. To observe the effect of these settings, operators need visibility into memory pressure events. cadvisor currently does not read the memory.events cgroup file — the existing container_oom_events_total metric comes from kernel log parsing, not cgroup counters. Read memory.events on cgroup v2 and expose two new Prometheus counter metrics: - container_memory_events_high_total: times the container was throttled for breaching memory.high - container_memory_events_max_total: times the container's usage hit memory.max Signed-off-by: Sohan Kunkerkar --- container/libcontainer/handler.go | 14 +++++ container/libcontainer/handler_test.go | 56 +++++++++++++++++++ info/v1/container.go | 7 +++ integration/tests/api/event_test.go | 42 ++++++++++++++ integration/tests/metrics/prometheus_test.go | 4 ++ metrics/prometheus.go | 14 +++++ metrics/prometheus_fake.go | 4 ++ metrics/testdata/prometheus_metrics | 6 ++ .../prometheus_metrics_whitelist_filtered | 6 ++ 9 files changed, 153 insertions(+) diff --git a/container/libcontainer/handler.go b/container/libcontainer/handler.go index 4d6e8a40fc..7d8da59ddd 100644 --- a/container/libcontainer/handler.go +++ b/container/libcontainer/handler.go @@ -32,6 +32,7 @@ import ( "github.com/opencontainers/cgroups" "github.com/opencontainers/cgroups/fs2" + "github.com/opencontainers/cgroups/fscommon" "k8s.io/klog/v2" "github.com/google/cadvisor/container" @@ -92,6 +93,10 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) { } stats := newContainerStats(cgroupStats, h.includedMetrics) + if cgroups.IsCgroup2UnifiedMode() { + setMemoryEvents(h.cgroupManager.Path(""), stats) + } + if h.includedMetrics.Has(container.ProcessSchedulerMetrics) { stats.Cpu.Schedstat, err = h.schedulerStatsFromProcs() if err != nil { @@ -862,6 +867,15 @@ func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) { ret.Memory.WorkingSet = workingSet } +func setMemoryEvents(cgroupPath string, ret *info.ContainerStats) { + if val, err := fscommon.GetValueByKey(cgroupPath, "memory.events", "high"); err == nil { + ret.Memory.Events.High = val + } + if val, err := fscommon.GetValueByKey(cgroupPath, "memory.events", "max"); err == nil { + ret.Memory.Events.Max = val + } +} + func setCPUSetStats(s *cgroups.Stats, ret *info.ContainerStats) { ret.CpuSet.MemoryMigrate = s.CPUSetStats.MemoryMigrate } diff --git a/container/libcontainer/handler_test.go b/container/libcontainer/handler_test.go index 8d6b4cfb03..d117a5a199 100644 --- a/container/libcontainer/handler_test.go +++ b/container/libcontainer/handler_test.go @@ -18,6 +18,7 @@ package libcontainer import ( "os" + "path/filepath" "reflect" "testing" @@ -351,3 +352,58 @@ func TestProcessMaxOpenFileLimitLine(t *testing.T) { assert.Equal(t, int64(1073741816), ulimit.SoftLimit) assert.Equal(t, int64(1073741816), ulimit.HardLimit) } + +func TestSetMemoryEvents(t *testing.T) { + cgroups.TestMode = true + defer func() { cgroups.TestMode = false }() + + testData := []struct { + name string + content string + high uint64 + max uint64 + }{ + { + "all counters", + "low 0\nhigh 42\nmax 5\noom 1\noom_kill 0\noom_group_kill 0\n", + 42, 5, + }, + { + "zeros", + "low 0\nhigh 0\nmax 0\noom 0\noom_kill 0\noom_group_kill 0\n", + 0, 0, + }, + { + "high only", + "low 0\nhigh 238\nmax 0\noom 0\noom_kill 0\noom_group_kill 0\n", + 238, 0, + }, + { + "empty file", + "", + 0, 0, + }, + } + + for _, testItem := range testData { + t.Run(testItem.name, func(t *testing.T) { + dir := t.TempDir() + err := os.WriteFile(filepath.Join(dir, "memory.events"), []byte(testItem.content), 0o644) + assert.Nil(t, err) + + var ret info.ContainerStats + setMemoryEvents(dir, &ret) + + assert.Equal(t, testItem.high, ret.Memory.Events.High) + assert.Equal(t, testItem.max, ret.Memory.Events.Max) + }) + } +} + +func TestSetMemoryEventsFileNotFound(t *testing.T) { + var ret info.ContainerStats + setMemoryEvents("/nonexistent/path", &ret) + + assert.Equal(t, uint64(0), ret.Memory.Events.High) + assert.Equal(t, uint64(0), ret.Memory.Events.Max) +} diff --git a/info/v1/container.go b/info/v1/container.go index 0f6ffc59d4..52cfc3b3b5 100644 --- a/info/v1/container.go +++ b/info/v1/container.go @@ -456,6 +456,13 @@ type MemoryStats struct { HierarchicalData MemoryStatsMemoryData `json:"hierarchical_data,omitempty"` PSI PSIStats `json:"psi"` + + Events MemoryEvents `json:"events,omitempty"` +} + +type MemoryEvents struct { + High uint64 `json:"high"` + Max uint64 `json:"max"` } type CPUSetStats struct { diff --git a/integration/tests/api/event_test.go b/integration/tests/api/event_test.go index 786668bbce..1b873292d3 100644 --- a/integration/tests/api/event_test.go +++ b/integration/tests/api/event_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + "github.com/opencontainers/cgroups" "github.com/stretchr/testify/require" info "github.com/google/cadvisor/info/v1" @@ -118,6 +119,47 @@ func TestOomKillEventConstraint(t *testing.T) { } } +func TestMemoryEventsMaxMetricAfterOom(t *testing.T) { + if !cgroups.IsCgroup2UnifiedMode() { + t.Skip("memory.events requires cgroup v2") + } + + fm := framework.New(t) + defer fm.Cleanup() + + containerID := fm.Docker().Run( + framework.DockerRunArgs{ + Image: "registry.k8s.io/busybox:1.27", + Args: []string{"-m=8M", "--memory-swap=8M"}, + }, + "sh", "-c", "dd if=/dev/zero of=/tmp/data bs=1M count=100; sleep 60", + ) + + client := framework.NewMetricsClient(fm.Hostname()) + + err := framework.RetryForDuration(func() error { + families, err := client.FetchAndParse() + if err != nil { + return err + } + mf, ok := framework.GetMetricFamily(families, "container_memory_events_max_total") + if !ok { + return fmt.Errorf("container_memory_events_max_total metric not found") + } + metrics := framework.FindMetricsWithLabelSubstring(mf, "id", containerID) + if len(metrics) == 0 { + return fmt.Errorf("no container_memory_events_max_total for container %s", containerID) + } + val := framework.GetCounterValue(metrics[0]) + if val <= 0 { + return fmt.Errorf("container_memory_events_max_total is %v, want > 0", val) + } + return nil + }, 30*time.Second) + + require.NoError(t, err) +} + func waitForStaticEvent(containerID string, urlRequest string, t *testing.T, fm framework.Framework, typeEvent info.EventType) { einfo, err := fm.Cadvisor().Client().EventStaticInfo(urlRequest) require.NoError(t, err) diff --git a/integration/tests/metrics/prometheus_test.go b/integration/tests/metrics/prometheus_test.go index a2a4535b99..07e96756ea 100644 --- a/integration/tests/metrics/prometheus_test.go +++ b/integration/tests/metrics/prometheus_test.go @@ -117,6 +117,8 @@ func TestCoreMemoryMetricsExist(t *testing.T) { "container_memory_working_set_bytes", "container_memory_cache", "container_memory_rss", + "container_memory_events_high_total", + "container_memory_events_max_total", } for _, name := range memoryMetrics { @@ -248,6 +250,8 @@ func TestMetricsHaveCorrectTypes(t *testing.T) { "container_cpu_system_seconds_total", "container_network_receive_bytes_total", "container_network_transmit_bytes_total", + "container_memory_events_high_total", + "container_memory_events_max_total", } for _, name := range counterMetrics { if mf, ok := families[name]; ok { diff --git a/metrics/prometheus.go b/metrics/prometheus.go index da34cdc5d3..1617594afc 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -640,6 +640,20 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri }, } }, + }, { + name: "container_memory_events_high_total", + help: "Cumulative count of memory.high throttle events for the container", + valueType: prometheus.CounterValue, + getValues: func(s *info.ContainerStats) metricValues { + return metricValues{{value: float64(s.Memory.Events.High), timestamp: s.Timestamp}} + }, + }, { + name: "container_memory_events_max_total", + help: "Cumulative count of memory.max limit hit events for the container", + valueType: prometheus.CounterValue, + getValues: func(s *info.ContainerStats) metricValues { + return metricValues{{value: float64(s.Memory.Events.Max), timestamp: s.Timestamp}} + }, }, }...) } diff --git a/metrics/prometheus_fake.go b/metrics/prometheus_fake.go index 7c8c99e095..ceb105babd 100644 --- a/metrics/prometheus_fake.go +++ b/metrics/prometheus_fake.go @@ -389,6 +389,10 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req Total: 2000, }, }, + Events: info.MemoryEvents{ + High: 42, + Max: 5, + }, }, Hugetlb: map[string]info.HugetlbStats{ "2Mi": { diff --git a/metrics/testdata/prometheus_metrics b/metrics/testdata/prometheus_metrics index fc7738afad..1f37ba03fc 100644 --- a/metrics/testdata/prometheus_metrics +++ b/metrics/testdata/prometheus_metrics @@ -175,6 +175,12 @@ container_memory_bandwidth_local_bytes{container_env_foo_env="prod",container_la # HELP container_memory_cache Number of bytes of page cache memory. # TYPE container_memory_cache gauge container_memory_cache{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 14 1395066363000 +# HELP container_memory_events_high_total Cumulative count of memory.high throttle events for the container +# TYPE container_memory_events_high_total counter +container_memory_events_high_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 42 1395066363000 +# HELP container_memory_events_max_total Cumulative count of memory.max limit hit events for the container +# TYPE container_memory_events_max_total counter +container_memory_events_max_total{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 5 1395066363000 # HELP container_memory_failcnt Number of memory usage hits limits # TYPE container_memory_failcnt counter container_memory_failcnt{container_env_foo_env="prod",container_label_foo_label="bar",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0 1395066363000 diff --git a/metrics/testdata/prometheus_metrics_whitelist_filtered b/metrics/testdata/prometheus_metrics_whitelist_filtered index 25fb529959..e7ce19866b 100644 --- a/metrics/testdata/prometheus_metrics_whitelist_filtered +++ b/metrics/testdata/prometheus_metrics_whitelist_filtered @@ -175,6 +175,12 @@ container_memory_bandwidth_local_bytes{container_env_foo_env="prod",id="testcont # HELP container_memory_cache Number of bytes of page cache memory. # TYPE container_memory_cache gauge container_memory_cache{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 14 1395066363000 +# HELP container_memory_events_high_total Cumulative count of memory.high throttle events for the container +# TYPE container_memory_events_high_total counter +container_memory_events_high_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 42 1395066363000 +# HELP container_memory_events_max_total Cumulative count of memory.max limit hit events for the container +# TYPE container_memory_events_max_total counter +container_memory_events_max_total{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 5 1395066363000 # HELP container_memory_failcnt Number of memory usage hits limits # TYPE container_memory_failcnt counter container_memory_failcnt{container_env_foo_env="prod",id="testcontainer",image="test",name="testcontaineralias",zone_name="hello"} 0 1395066363000 From 231a236e0f6cfef4c76e265877678912785fcbbb Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Thu, 14 May 2026 11:05:05 -0400 Subject: [PATCH 21/26] deploy: bump base images to Alpine 3.23 Move the build stage and final image to alpine 3.23 (current stable, released 2025-12-03) so that a rebuild picks up: - busybox 1.37.0-r20+ (addresses CVE-2024-58251, BusyBox netstat ANSI-escape DoS) - Go 1.25.10 via golang:1.25-alpine3.23 (addresses CVE-2025-58183, archive/tar unbounded sparse-region allocation, fixed in 1.25.9) Refs #3837 Signed-off-by: Davanum Srinivas --- deploy/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 03d653c0db..eafe1ac436 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.hub.docker.com/library/golang:1.25-alpine3.22 AS build +FROM registry.hub.docker.com/library/golang:1.25-alpine3.23 AS build # Install build depdencies for all supported arches RUN apk --no-cache add bash build-base cmake device-mapper findutils git \ @@ -49,7 +49,7 @@ RUN export GO_TAGS="libpfm,netgo"; \ fi; \ GO_FLAGS="-tags=$GO_TAGS" ./build/build.sh -FROM mirror.gcr.io/library/alpine:3.22 +FROM mirror.gcr.io/library/alpine:3.23 MAINTAINER dengnan@google.com vmarmol@google.com vishnuk@google.com jimmidyson@gmail.com stclair@google.com RUN apk --no-cache add libc6-compat device-mapper findutils ndctl thin-provisioning-tools zfs && \ From befdcea2850ab1cc20311bbaa1f7809f4bb96e4e Mon Sep 17 00:00:00 2001 From: Great Date: Sat, 16 May 2026 04:06:43 -0400 Subject: [PATCH 22/26] fix: fallback to major:minor format for unrecognized devices in deviceIdentifierMap (#1) Signed-off-by: Umegbewe Nwebedu --- container/common/helpers.go | 4 +++ container/common/helpers_test.go | 61 ++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/container/common/helpers.go b/container/common/helpers.go index 3b3d27f300..69e0adff2b 100644 --- a/container/common/helpers.go +++ b/container/common/helpers.go @@ -437,6 +437,10 @@ func (m deviceIdentifierMap) Find(major, minor uint64, namer DeviceNamer) string return s } s, _ := namer.DeviceName(major, minor) + if s == "" { + s = fmt.Sprintf("%d:%d", major, minor) + } + m[d] = s return s } diff --git a/container/common/helpers_test.go b/container/common/helpers_test.go index db9e13829f..8bb82f3cf6 100644 --- a/container/common/helpers_test.go +++ b/container/common/helpers_test.go @@ -250,6 +250,67 @@ func TestRemoveNetMetrics(t *testing.T) { } } +type deviceNamerFunc func(major, minor uint64) (string, bool) + +func (f deviceNamerFunc) DeviceName(major, minor uint64) (string, bool) { + return f(major, minor) +} + +func TestDeviceIdentifierMapFindFallsBackToMajorMinor(t *testing.T) { + for _, tc := range []struct { + name string + namer DeviceNamer + expected string + }{ + { + name: "unrecognized device", + namer: deviceNamerFunc(func(_, _ uint64) (string, bool) { + return "", false + }), + expected: "8:0", + }, + { + name: "recognized empty device", + namer: deviceNamerFunc(func(_, _ uint64) (string, bool) { + return "", true + }), + expected: "8:0", + }, + { + name: "recognized device", + namer: deviceNamerFunc(func(_, _ uint64) (string, bool) { + return "/dev/sda", true + }), + expected: "/dev/sda", + }, + } { + t.Run(tc.name, func(t *testing.T) { + devices := make(deviceIdentifierMap) + assert.Equal(t, tc.expected, devices.Find(8, 0, tc.namer)) + }) + } +} + +func TestAssignDeviceNamesToDiskStatsKeepsUnresolvedDevicesUnique(t *testing.T) { + stats := &info.DiskIoStats{ + IoServiceBytes: []info.PerDiskStats{ + {Major: 8, Minor: 0}, + {Major: 259, Minor: 1}, + }, + IoServiced: []info.PerDiskStats{ + {Major: 8, Minor: 0}, + }, + } + + AssignDeviceNamesToDiskStats(deviceNamerFunc(func(_, _ uint64) (string, bool) { + return "", false + }), stats) + + assert.Equal(t, "8:0", stats.IoServiceBytes[0].Device) + assert.Equal(t, "259:1", stats.IoServiceBytes[1].Device) + assert.Equal(t, "8:0", stats.IoServiced[0].Device) +} + func BenchmarkGetSpecCgroupV2(b *testing.B) { root, err := os.Getwd() if err != nil { From 651958f200c40867b6029cc6c23f77d1e7faaad6 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 16 May 2026 09:21:02 +0100 Subject: [PATCH 23/26] fix: PR comments --- container/raw/handler.go | 7 +++ container/raw/handler_test.go | 42 ++++++++++++++ docs/storage/prometheus.md | 1 - fs/fs.go | 103 +++++++++++++++++++++++----------- fs/fs_test.go | 25 +++++++++ go.mod | 2 + go.sum | 2 - metrics/prometheus.go | 28 +++------ 8 files changed, 155 insertions(+), 55 deletions(-) diff --git a/container/raw/handler.go b/container/raw/handler.go index 0eba467d49..bf27c54f32 100644 --- a/container/raw/handler.go +++ b/container/raw/handler.go @@ -231,6 +231,13 @@ func (h *rawContainerHandler) getFsStats(stats *info.ContainerStats) error { fsstat := fsToFsStats(&fsCopy) if containerPath, ok := hostToContainerPath[fsstat.Mountpoint]; ok { fsstat.ContainerPath = containerPath + } else { + for _, mountpoint := range fsstat.AllMountpoints { + if containerPath, ok := hostToContainerPath[mountpoint]; ok { + fsstat.ContainerPath = containerPath + break + } + } } stats.Filesystem = append(stats.Filesystem, fsstat) } diff --git a/container/raw/handler_test.go b/container/raw/handler_test.go index 8e674ea4e7..2a8539da1b 100644 --- a/container/raw/handler_test.go +++ b/container/raw/handler_test.go @@ -433,6 +433,48 @@ func TestGetFsStats(t *testing.T) { InodesFree: 1000, }}, }, + "random container with all mountpoints container path": { + name: "/random/container", + includedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}}, + externalMounts: []common.Mount{ + { + HostDir: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount", + ContainerDir: "/data", + }, + }, + getFsInfoForPath: func(mountSet map[string]struct{}) ([]fs.Fs, error) { + return []fs.Fs{{ + DeviceInfo: fs.DeviceInfo{Device: "/dev/sdb", Major: 8, Minor: 0}, + Mountpoint: "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc/globalmount", + AllMountpoints: []string{ + "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc/globalmount", + "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount", + }, + Type: "ext4", + Capacity: 1000, + Free: 500, + Available: 450, + Inodes: &inodes, + InodesFree: &inodesFree, + }}, nil + }, + expectedFilesystems: []info.FsStats{{ + Device: "/dev/sdb", + Mountpoint: "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc/globalmount", + AllMountpoints: []string{ + "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc/globalmount", + "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount", + }, + ContainerPath: "/data", + Type: "ext4", + Limit: 1000, + Usage: 500, + Available: 450, + HasInodes: true, + Inodes: 2000, + InodesFree: 1000, + }}, + }, "random container with disk metrics enabled": { name: "/random/container", includedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}, container.DiskIOMetrics: struct{}{}}, diff --git a/docs/storage/prometheus.md b/docs/storage/prometheus.md index e405d3bafe..1edc8e5dbe 100644 --- a/docs/storage/prometheus.md +++ b/docs/storage/prometheus.md @@ -30,7 +30,6 @@ Metric name | Type | Description | Unit (where applicable) | option parameter | `container_cpu_usage_seconds_total` | Counter | Cumulative cpu time consumed | seconds | cpu | `container_cpu_user_seconds_total` | Counter | Cumulative user cpu time consumed | seconds | cpu | `container_file_descriptors` | Gauge | Number of open file descriptors for the container | | process | -`container_fs_device_info` | Gauge | Device information for the filesystem used by the container, with `device` label identifying the device and `major` and `minor` labels identifying the major and minor device numbers | | disk | `container_fs_inodes_free` | Gauge | Number of available Inodes | | disk | `container_fs_inodes_total` | Gauge | Total number of Inodes | | disk | `container_fs_io_current` | Gauge | Number of I/Os currently in progress | | diskIO | diff --git a/fs/fs.go b/fs/fs.go index f7c20e5b7b..627ee31514 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -114,20 +114,11 @@ func NewFsInfo(context Context) (FsInfo, error) { // Avoid devicemapper container mounts - these are tracked by the ThinPoolWatcher excluded := []string{fmt.Sprintf("%s/devicemapper/mnt", context.Docker.Root)} - // Build device → all-mountpoints map before processMounts de-duplicates. - // We record every mountpoint for devices whose FSType has a plugin, so that - // container_fs_device_info can emit metrics for bind-mount paths (e.g. the - // per-pod kubelet volume path alongside the CSI plugin globalmount path). - deviceToMountpoints := make(map[string][]string) - for _, mnt := range mounts { - if GetPluginForFsType(mnt.FSType) == nil { - continue - } - deviceToMountpoints[mnt.Source] = append(deviceToMountpoints[mnt.Source], mnt.Mountpoint) - } + partitions := processMounts(mounts, excluded) + deviceToMountpoints := buildDeviceToMountpoints(mounts, excluded, partitions) fsInfo := &RealFsInfo{ - partitions: processMounts(mounts, excluded), + partitions: partitions, labels: make(map[string]string), mounts: make(map[string]mount.Info), dmsetup: devicemapper.NewDmsetupClient(), @@ -186,12 +177,6 @@ func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) ma partitions := make(map[string]partition) for _, mnt := range mounts { - // Use plugin system to determine if filesystem is supported - plugin := GetPluginForFsType(mnt.FSType) - if plugin == nil { - continue - } - // Avoid bind mounts, but allow tmpfs duplicates (handled by plugin's ProcessMount) if _, ok := partitions[mnt.Source]; ok { if mnt.FSType != "tmpfs" { @@ -199,20 +184,7 @@ func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) ma } } - // Check for excluded mountpoint prefixes - hasPrefix := false - for _, prefix := range excludedMountpointPrefixes { - if strings.HasPrefix(mnt.Mountpoint, prefix) { - hasPrefix = true - break - } - } - if hasPrefix { - continue - } - - // Let plugin process the mount (handles filesystem-specific modifications) - include, processedMnt, err := plugin.ProcessMount(mnt) + include, processedMnt, err := processMountInfo(mnt, excludedMountpointPrefixes) if err != nil { klog.Warningf("error processing mount for %s: %v", mnt.FSType, err) continue @@ -232,6 +204,73 @@ func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) ma return partitions } +func buildDeviceToMountpoints( + mounts []*mount.Info, + excludedMountpointPrefixes []string, + partitions map[string]partition, +) map[string][]string { + deviceToMountpoints := make(map[string][]string, len(partitions)) + for device, partition := range partitions { + deviceToMountpoints[device] = []string{partition.mountpoint} + } + + for _, mnt := range mounts { + include, processedMnt, err := processMountInfo(mnt, excludedMountpointPrefixes) + if err != nil { + klog.Warningf("error processing mount for %s: %v", mnt.FSType, err) + continue + } + if !include { + continue + } + if _, ok := partitions[processedMnt.Source]; !ok { + continue + } + appendUniqueMountpoint(deviceToMountpoints, processedMnt.Source, processedMnt.Mountpoint) + } + + return deviceToMountpoints +} + +func processMountInfo( + mnt *mount.Info, + excludedMountpointPrefixes []string, +) (bool, *mount.Info, error) { + plugin := GetPluginForFsType(mnt.FSType) + if plugin == nil { + return false, nil, nil + } + if isExcludedMountpoint(mnt.Mountpoint, excludedMountpointPrefixes) { + return false, nil, nil + } + include, processedMnt, err := plugin.ProcessMount(mnt) + if err != nil { + return false, nil, err + } + if !include { + return false, nil, nil + } + return true, processedMnt, nil +} + +func isExcludedMountpoint(mountpoint string, excludedMountpointPrefixes []string) bool { + for _, prefix := range excludedMountpointPrefixes { + if strings.HasPrefix(mountpoint, prefix) { + return true + } + } + return false +} + +func appendUniqueMountpoint(deviceToMountpoints map[string][]string, device, mountpoint string) { + for _, existing := range deviceToMountpoints[device] { + if existing == mountpoint { + return + } + } + deviceToMountpoints[device] = append(deviceToMountpoints[device], mountpoint) +} + // getDockerDeviceMapperInfo returns information about the devicemapper device and "partition" if // docker is using devicemapper for its storage driver. If a loopback device is being used, don't // return any information or error, as we want to report based on the actual partition where the diff --git a/fs/fs_test.go b/fs/fs_test.go index 1db4ceca9c..b75f9f2b98 100644 --- a/fs/fs_test.go +++ b/fs/fs_test.go @@ -730,3 +730,28 @@ func TestProcessMounts(t *testing.T) { } } } + +func TestBuildDeviceToMountpoints(t *testing.T) { + mounts := []*mount.Info{ + {Root: "/", Mountpoint: "/var/lib/containers/storage/overlay", Source: "overlay", FSType: "overlay", Major: 253, Minor: 5}, + {Root: "/", Mountpoint: "/var/lib/kubelet/pods/abc/volumes/kubernetes.io~csi/pvc/mount", Source: "overlay", FSType: "overlay", Major: 253, Minor: 5}, + {Root: "/", Mountpoint: "/tmpfs-primary", Source: "tmpfs", FSType: "tmpfs", Major: 253, Minor: 4}, + {Root: "/", Mountpoint: "/tmpfs-secondary", Source: "tmpfs", FSType: "tmpfs", Major: 253, Minor: 4}, + {Root: "/", Mountpoint: "/exclude/me", Source: "/dev/sda1", FSType: "xfs", Major: 253, Minor: 1}, + } + excludedPrefixes := []string{"/exclude"} + + partitions := processMounts(mounts, excludedPrefixes) + actual := buildDeviceToMountpoints(mounts, excludedPrefixes, partitions) + + expected := map[string][]string{ + "overlay_253-5": { + "/var/lib/kubelet/pods/abc/volumes/kubernetes.io~csi/pvc/mount", + "/var/lib/containers/storage/overlay", + }, + "/tmpfs-primary": {"/tmpfs-primary"}, + "/tmpfs-secondary": {"/tmpfs-secondary"}, + } + + assert.Equal(t, expected, actual) +} diff --git a/go.mod b/go.mod index 866daeaa38..344a08e0ce 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/baselinehq/cadvisor go 1.24.0 +replace github.com/google/cadvisor => . + require ( cloud.google.com/go/compute/metadata v0.9.0 github.com/Microsoft/go-winio v0.6.2 diff --git a/go.sum b/go.sum index 2c33ad2fdf..b8a9e3325a 100644 --- a/go.sum +++ b/go.sum @@ -74,8 +74,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cadvisor v0.57.0 h1:2LoXUZIJPR3VQJC1bZmqAGdh09yPfpS7MEeC4fJy80k= -github.com/google/cadvisor v0.57.0/go.mod h1:z6bozbhp/EAWhJqF6KK78MESLoeAhi7pJ9g7fRYGPEc= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= diff --git a/metrics/prometheus.go b/metrics/prometheus.go index 1617594afc..4957dd89f8 100644 --- a/metrics/prometheus.go +++ b/metrics/prometheus.go @@ -44,6 +44,8 @@ func asNanosecondsToSeconds(v uint64) float64 { return float64(v) / 1e9 } +var kubeletVolumePathRegexp = regexp.MustCompile(`/pods/[^/]+/volumes/([^/]+)/([^/]+)`) + // ioValues is a helper method for assembling per-disk and per-filesystem stats. func ioValues(ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) float64, fsStats []info.FsStats, valueFn func(*info.FsStats) float64, timestamp time.Time) metricValues { @@ -71,10 +73,6 @@ type volumePath struct { volumeType string } -type matchTypes struct { - regex *regexp.Regexp -} - // parseMountPointIntoVolumePath extracts the volume name from a kubelet volume mount // path. For CSI volumes this is the PersistentVolumeClaim name. Returns an // empty string for paths that do not match the standard kubelet volume path. @@ -83,22 +81,12 @@ type matchTypes struct { // // /var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount → "my-pvc" func parseMountPointIntoVolumePath(path string) volumePath { - volumeMatchTypes := []matchTypes{ - // /var/lib/kubelet/pods//volumes//[/…] - // - // Capture group 1 is the volume name, which for CSI volumes corresponds to the - // PersistentVolumeClaim name. - { - regex: regexp.MustCompile(`/pods/[^/]+/volumes/([^/]+)/([^/]+)`), - }, - } - - for _, matchType := range volumeMatchTypes { - m := matchType.regex.FindStringSubmatch(path) - if m == nil { - continue - } - + // /var/lib/kubelet/pods//volumes//[/…] + // + // Capture group 1 is the volume type, and capture group 2 is the volume name, + // which for CSI volumes corresponds to the PersistentVolumeClaim name. + m := kubeletVolumePathRegexp.FindStringSubmatch(path) + if m != nil { return volumePath{ volumeName: m[2], volumeType: m[1], From 59a5c3b483a7c85c11cff2d2e0fa9765c9d2a875 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 16 May 2026 09:22:28 +0100 Subject: [PATCH 24/26] fix: host container paths --- cmd/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/go.mod b/cmd/go.mod index 19babfafbc..e0ca99dd4a 100644 --- a/cmd/go.mod +++ b/cmd/go.mod @@ -6,7 +6,7 @@ go 1.24.0 // The github.com/google/cadvisor/cmd module is built using the Makefile // from a clone of the github.com/google/cadvisor repository, so we // always use the relative local source rather than specifying a module version. -require github.com/google/cadvisor v0.0.0 +require github.com/google/cadvisor v0.57.0 // Use the relative local source of the github.com/google/cadvisor library to build replace github.com/google/cadvisor => ../ From 216e114862411983ccba4021b51520318f5fa000 Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 16 May 2026 09:32:26 +0100 Subject: [PATCH 25/26] fix: final PR comments --- build/integration-in-docker-crio.sh | 2 +- cmd/go.mod | 6 +++--- cmd/go.sum | 12 ++++++------ deploy/Dockerfile | 5 ++--- go.mod | 6 +++--- go.sum | 12 ++++++------ integration/tests/api/event_test.go | 2 +- manager/container_test.go | 16 ++++++++++++++++ 8 files changed, 38 insertions(+), 23 deletions(-) diff --git a/build/integration-in-docker-crio.sh b/build/integration-in-docker-crio.sh index 980134f5ce..47d686cc5b 100755 --- a/build/integration-in-docker-crio.sh +++ b/build/integration-in-docker-crio.sh @@ -76,7 +76,7 @@ function run_tests() { --cgroupns=host \ --pid=host \ --entrypoint="" \ - gcr.io/k8s-staging-test-infra/bootstrap:v20251209-855adc2699 \ + gcr.io/k8s-staging-test-infra/bootstrap@sha256:2e537f9aea810021ecd022bf085e99099a25fc4bb95de96eeb510e92a524b471 \ bash -c "export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ apt-get install -y $PACKAGES curl conntrack iptables dbus && \ diff --git a/cmd/go.mod b/cmd/go.mod index e0ca99dd4a..c3554c9e8f 100644 --- a/cmd/go.mod +++ b/cmd/go.mod @@ -107,9 +107,9 @@ require ( github.com/stretchr/objx v0.5.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.39.0 // indirect - go.opentelemetry.io/otel/metric v1.39.0 // indirect - go.opentelemetry.io/otel/trace v1.39.0 // indirect + go.opentelemetry.io/otel v1.41.0 // indirect + go.opentelemetry.io/otel/metric v1.41.0 // indirect + go.opentelemetry.io/otel/trace v1.41.0 // indirect golang.org/x/crypto v0.46.0 // indirect golang.org/x/net v0.48.0 // indirect golang.org/x/sys v0.39.0 // indirect diff --git a/cmd/go.sum b/cmd/go.sum index aa10e9d81f..49b8e5cf6d 100644 --- a/cmd/go.sum +++ b/cmd/go.sum @@ -260,16 +260,16 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= +go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= +go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= +go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= +go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= diff --git a/deploy/Dockerfile b/deploy/Dockerfile index eafe1ac436..9d111113bd 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.hub.docker.com/library/golang:1.25-alpine3.23 AS build +FROM registry.hub.docker.com/library/golang:1.25-alpine3.23@sha256:8d22e29d960bc50cd025d93d5b7c7d220b1ee9aa7a239b3c8f55a57e987e8d45 AS build # Install build depdencies for all supported arches RUN apk --no-cache add bash build-base cmake device-mapper findutils git \ @@ -49,7 +49,7 @@ RUN export GO_TAGS="libpfm,netgo"; \ fi; \ GO_FLAGS="-tags=$GO_TAGS" ./build/build.sh -FROM mirror.gcr.io/library/alpine:3.23 +FROM mirror.gcr.io/library/alpine:3.23@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 MAINTAINER dengnan@google.com vmarmol@google.com vishnuk@google.com jimmidyson@gmail.com stclair@google.com RUN apk --no-cache add libc6-compat device-mapper findutils ndctl thin-provisioning-tools zfs && \ @@ -77,4 +77,3 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \ # Use entrypoint wrapper ENTRYPOINT ["/usr/bin/entrypoint.sh"] - diff --git a/go.mod b/go.mod index 344a08e0ce..245b38ae3d 100644 --- a/go.mod +++ b/go.mod @@ -73,9 +73,9 @@ require ( github.com/stretchr/objx v0.5.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.39.0 // indirect - go.opentelemetry.io/otel/metric v1.39.0 // indirect - go.opentelemetry.io/otel/trace v1.39.0 // indirect + go.opentelemetry.io/otel v1.41.0 // indirect + go.opentelemetry.io/otel/metric v1.41.0 // indirect + go.opentelemetry.io/otel/trace v1.41.0 // indirect golang.org/x/net v0.48.0 // indirect golang.org/x/text v0.32.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect diff --git a/go.sum b/go.sum index b8a9e3325a..7f96b11b3b 100644 --- a/go.sum +++ b/go.sum @@ -136,16 +136,16 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= +go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= +go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= +go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= +go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/integration/tests/api/event_test.go b/integration/tests/api/event_test.go index 1b873292d3..d5e040e94d 100644 --- a/integration/tests/api/event_test.go +++ b/integration/tests/api/event_test.go @@ -88,7 +88,7 @@ func TestOomKillEventConstraint(t *testing.T) { containerID := fm.Docker().Run( framework.DockerRunArgs{ Image: "registry.k8s.io/busybox:1.27", - Args: []string{"-m=" + tt.memLimit}, + Args: []string{"-m=" + tt.memLimit, "--memory-swap=" + tt.memLimit}, }, "sh", "-c", "a=1; while true; do a=\"${a}${a}\"; done", ) diff --git a/manager/container_test.go b/manager/container_test.go index f4f68f8185..d92888feb6 100644 --- a/manager/container_test.go +++ b/manager/container_test.go @@ -573,6 +573,22 @@ func TestNextHousekeepingInterval(t *testing.T) { expectedMin: base, expectedMax: base, }, + { + name: "negative splay factor resets to default", + splayFactor: -1.0, + jitterFactor: 0.5, + firstHousekeeping: true, + expectedMin: base, + expectedMax: base + time.Duration(jitterDefault*float64(base)), + }, + { + name: "negative jitter factor resets to default", + splayFactor: 1.0, + jitterFactor: -0.5, + firstHousekeeping: false, + expectedMin: base, + expectedMax: base + time.Duration(jitterDefault*float64(base)), + }, } for _, tc := range tests { From fbfa336df42c598ea025b2b7ddf96e716a4cf0ca Mon Sep 17 00:00:00 2001 From: Emmanuel Bakare Date: Sat, 16 May 2026 09:43:24 +0100 Subject: [PATCH 26/26] fix: revert go module name --- go.mod | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 245b38ae3d..9ef8c3a764 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,7 @@ -module github.com/baselinehq/cadvisor +module github.com/google/cadvisor go 1.24.0 -replace github.com/google/cadvisor => . - require ( cloud.google.com/go/compute/metadata v0.9.0 github.com/Microsoft/go-winio v0.6.2 @@ -18,7 +16,6 @@ require ( github.com/docker/go-connections v0.6.0 github.com/docker/go-units v0.5.0 github.com/euank/go-kmsg-parser v2.0.0+incompatible - github.com/google/cadvisor v0.57.0 github.com/mistifyio/go-zfs v2.1.1+incompatible github.com/moby/moby/api v1.54.1 github.com/moby/moby/client v0.4.0