cgroups

package module
v0.52.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2024 License: Apache-2.0 Imports: 20 Imported by: 1

Documentation

Overview

Package cgroups implements helpers to extract information from Linux cgroups. It supports cgroups v1 and v2.

Index

Constants

View Source
const (
	// ContainerRegexpStr defines the regexp used to match container IDs
	// ([0-9a-f]{64}) is standard container id used pretty much everywhere
	// ([0-9a-f]{32}-[0-9]{10}) is container id used by AWS ECS
	// ([0-9a-f]{8}(-[0-9a-f]{4}){4}$) is container id used by Garden
	ContainerRegexpStr = "([0-9a-f]{64})|([0-9a-f]{32}-[0-9]{10})|([0-9a-f]{8}(-[0-9a-f]{4}){4}$)"
)
View Source
const (
	SelfCgroupIdentifier = "self"
)

SelfCgroupIdentifier is the identifier to be used to get self cgroup

View Source
const (
	UserHZToNano uint64 = uint64(time.Second) / 100
)

UserHZToNano holds the divisor to convert HZ to Nanoseconds It's safe to consider it being 100Hz in userspace mode

Variables

ContainerRegexp defines the regexp used to match container ids First part is usual containerid (opencontainers standard) Second part is PCF/Garden regexp. We currently assume no suffix ($) to avoid matching pod UIDs

Functions

func ContainerFilter

func ContainerFilter(path, name string) (string, error)

ContainerFilter returns a filter that will match cgroup folders containing a container id

func DefaultFilter

func DefaultFilter(path, name string) (string, error)

DefaultFilter matches all cgroup folders and use folder name as identifier

func GetStats added in v0.44.0

func GetStats(c Cgroup, stats *Stats) (allFailed bool, errs []error)

GetStats allows to extract all available stats from cgroup

func IdentiferFromCgroupReferences

func IdentiferFromCgroupReferences(procPath, pid, baseCgroupController string, filter ReaderFilter) (string, error)

IdentiferFromCgroupReferences returns cgroup identifier extracted from <proc>/<pid>/cgroup after applying the filter.

func IsProcessHostCgroupNamespace

func IsProcessHostCgroupNamespace(procPath string, namespaceID uint64) *bool

IsProcessHostCgroupNamespace compares namespaceID with known, harcoded host PID Namespace inode Keeps same signature as `IsProcessHostNetwork` as we may need to change implementation depending on Kernel evolution

func ParseCPUSetFormat

func ParseCPUSetFormat(line string) uint64

ParseCPUSetFormat counts CPUs in CPUSet specs like "0,1,5-8". These are comma-separated lists of processor IDs, with hyphenated ranges representing closed sets. So "0,1,5-8" represents processors 0, 1, 5, 6, 7, 8. The function returns the count of CPUs, in this case 6.

func SetReporter

func SetReporter(r Reporter)

SetReporter allows to set a Reporter (set to nil to disable)

Types

type CPUStats

type CPUStats struct {
	User   *uint64
	System *uint64
	Total  *uint64

	Shares           *uint64 // Raw share value (no unit). Available only in cgroups v1.
	Weight           *uint64 // Raw value (no unit). Available only in cgroups v2. Similar concept as shares but the default value and the range of valid values are different.
	ElapsedPeriods   *uint64 // Number (no unit)
	ThrottledPeriods *uint64 // Number (no unit)
	ThrottledTime    *uint64
	CPUCount         *uint64 // Number of accessible logical CPU (from cpuset.cpus)

	SchedulerPeriod *uint64
	SchedulerQuota  *uint64

	PSISome PSIStats
}

CPUStats - all metrics are in nanoseconds execept if otherwise specified cgroupv1: cpu/cpuacct/cpuset cgroupv2: cpu/cpuset

type Cgroup

type Cgroup interface {
	// Identifier returns the cgroup identifier that was generated by the selected `Filter` (default: folder name)
	Identifier() string
	// Inode returns the cgroup node inode
	Inode() uint64
	// GetParent returns parent Cgroup (will fail if used on root cgroup)
	GetParent() (Cgroup, error)
	// GetCPUStats returns all cgroup statistics at once. Each call triggers a read from filesystem (no cache)
	// The given CPUStats object is filled with new values. If re-using object, old values are not cleared on read failure.
	GetCPUStats(*CPUStats) error
	// GetMemoryStats returns all cgroup statistics at once. Each call triggers a read from filesystem (no cache)
	// The given MemoryStats object is filled with new values. If re-using object, old values are not cleared on read failure.
	GetMemoryStats(*MemoryStats) error
	// GetIOStats returns all cgroup statistics at once. Each call triggers a read from filesystem (no cache)
	// The given IOStats object is filled with new values. If re-using object, old values are not cleared on read failure.
	GetIOStats(*IOStats) error
	// GetPIDStats returns all cgroup statistics at once. Each call triggers a read from filesystem (no cache)
	// The given PIDStats object is filled with new values. If re-using object, old values are not cleared on read failure.
	GetPIDStats(*PIDStats) error
	// GetPIDs returns the list of pids in this cgroup. This call MAY have a caching layer as retrieving PIDs may be costly.
	// - When running in host PID namespace, no cache is used (cacheValidity is discarded)
	// - When running in a different PID namespace, cache is used
	GetPIDs(cacheValidity time.Duration) ([]int, error)
}

Cgroup interface abstracts actual Cgroup implementation (v1/v2)

type ControllerNotFoundError

type ControllerNotFoundError struct {
	Controller string
}

ControllerNotFoundError is returned when trying to access a cgroup controller that's not visible in /proc/mount (cgroup v1 only)

func (*ControllerNotFoundError) Error

func (e *ControllerNotFoundError) Error() string

func (*ControllerNotFoundError) Is

func (e *ControllerNotFoundError) Is(target error) bool

Is returns whether two ControllerNotFoundError targets the same controller

type DeviceIOStats

type DeviceIOStats struct {
	ReadBytes       *uint64
	WriteBytes      *uint64
	ReadOperations  *uint64
	WriteOperations *uint64

	ReadBytesLimit       *uint64 // cgroupv2 only (bytes/s)
	WriteBytesLimit      *uint64 // cgroupv2 only (bytes/s)
	ReadOperationsLimit  *uint64 // cgroupv2 only (ops/s)
	WriteOperationsLimit *uint64 // cgroupv2 only (ops/s)
}

DeviceIOStats is a sub-structure to store stats per device

type FileSystemError

type FileSystemError struct {
	FilePath string
	Err      error
}

FileSystemError is returned when an error occurs when reading cgroup filesystem

func (*FileSystemError) Error

func (e *FileSystemError) Error() string

func (*FileSystemError) Unwrap

func (e *FileSystemError) Unwrap() error

type IOStats

type IOStats struct {
	ReadBytes       *uint64
	WriteBytes      *uint64
	ReadOperations  *uint64
	WriteOperations *uint64
	Devices         map[string]DeviceIOStats

	PSISome PSIStats
	PSIFull PSIStats
}

IOStats store I/O statistics about a cgroup. Devices identifier in map is MAJOR:MINOR cgroupv1: blkio cgroupv2: io

type InvalidInputError

type InvalidInputError struct {
	Desc string
}

InvalidInputError is returned when an input parameter has an invalid value (typically, passing a nil pointer)

func (*InvalidInputError) Error

func (e *InvalidInputError) Error() string

type MemoryController

type MemoryController struct {
	// contains filtered or unexported fields
}

MemoryController describes a cgroup based memory controller

func NewMemoryController

func NewMemoryController(kind string, containerized bool, monitors ...MemoryMonitor) (*MemoryController, error)

NewMemoryController creates a new systemd cgroup based memory controller

func (*MemoryController) Start

func (mc *MemoryController) Start()

Start listening for events

func (*MemoryController) Stop

func (mc *MemoryController) Stop()

Stop the memory controller

type MemoryMonitor

type MemoryMonitor func(cgroup cgroupsv1.Cgroup) (cgroupsv1.MemoryEvent, func(), error)

MemoryMonitor creates a cgroup memory event

func MemoryPercentageThresholdMonitor

func MemoryPercentageThresholdMonitor(cb func(), percentage uint64, swap bool) MemoryMonitor

MemoryPercentageThresholdMonitor monitors memory usage above a specified percentage threshold

func MemoryPressureMonitor

func MemoryPressureMonitor(cb func(), level string) MemoryMonitor

MemoryPressureMonitor monitors memory pressure levels

func MemoryThresholdMonitor

func MemoryThresholdMonitor(cb func(), limit uint64, swap bool) MemoryMonitor

MemoryThresholdMonitor monitors memory usage above a specified threshold

type MemoryStats

type MemoryStats struct {
	UsageTotal   *uint64
	Cache        *uint64
	Swap         *uint64
	RSS          *uint64
	RSSHuge      *uint64
	MappedFile   *uint64
	Pgpgin       *uint64 // Number (no unit), cgroupv1 only
	Pgpgout      *uint64 // Number (no unit), cgroupv1 only
	Pgfault      *uint64 // Number (no unit)
	Pgmajfault   *uint64 // Number (no unit)
	InactiveAnon *uint64
	ActiveAnon   *uint64
	InactiveFile *uint64
	ActiveFile   *uint64
	Unevictable  *uint64

	KernelMemory *uint64

	// This field is mapped to `memory.failcnt` for cgroupv1 and to "oom" in `memory.event`, it does not mean an OOMKill event happened.
	OOMEvents     *uint64 // Number (no unit).
	OOMKiilEvents *uint64 // cgroupv2 only

	Limit             *uint64
	MinThreshold      *uint64 // cgroupv2 only
	LowThreshold      *uint64 // cgroupv1: mapped to soft_limit
	HighThreshold     *uint64 // cgroupv2 only
	SwapLimit         *uint64 // Memory+Swap (thus >= Limit)
	SwapHighThreshold *uint64 // cgroupv2 only

	Peak *uint64 // cgroupv1: mapped to max_usage_in_bytes. cgroupv2: peak.

	PSISome PSIStats
	PSIFull PSIStats
}

MemoryStats - all metrics in bytes except if otherwise specified All statistics are hierarchical (i.e. includes all descendants) Meaning for each value can be checked at: https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt or https://www.kernel.org/doc/Documentation/cgroup-v2.txt Source: cgroupv1: memory controller cgroupv2: memory controller

type MockCgroup

type MockCgroup struct {
	ID          string
	In          uint64
	Parent      Cgroup
	ParentError error
	CPU         *CPUStats
	CPUError    error
	Memory      *MemoryStats
	MemoryError error
	IOStats     *IOStats
	IOError     error
	PIDStats    *PIDStats
	PIDError    error
	PIDs        []int
	PIDsError   error
}

MockCgroup is a mock implementing the Cgroup interface

func (*MockCgroup) GetCPUStats

func (mc *MockCgroup) GetCPUStats(cpuStats *CPUStats) error

GetCPUStats mock

func (*MockCgroup) GetIOStats

func (mc *MockCgroup) GetIOStats(ioStats *IOStats) error

GetIOStats mock

func (*MockCgroup) GetMemoryStats

func (mc *MockCgroup) GetMemoryStats(memoryStats *MemoryStats) error

GetMemoryStats mock

func (*MockCgroup) GetPIDStats

func (mc *MockCgroup) GetPIDStats(pidStats *PIDStats) error

GetPIDStats mock

func (*MockCgroup) GetPIDs

func (mc *MockCgroup) GetPIDs(cacheValidity time.Duration) ([]int, error)

GetPIDs mock

func (*MockCgroup) GetParent

func (mc *MockCgroup) GetParent() (Cgroup, error)

GetParent mock

func (*MockCgroup) Identifier

func (mc *MockCgroup) Identifier() string

Identifier mock

func (*MockCgroup) Inode added in v0.51.0

func (mc *MockCgroup) Inode() uint64

Inode mock

type PIDStats

type PIDStats struct {
	HierarchicalThreadCount *uint64 // Number of threads in cgroups + all children
	HierarchicalThreadLimit *uint64 // Maximum number of threads in cgroups + all children
}

PIDStats store stats about running threads and processes cgroupv1: pid cgroupv2: pid

type PSIStats

type PSIStats struct {
	Avg10  *float64 // Percentage (0-100)
	Avg60  *float64 // Percentage (0-100)
	Avg300 *float64 // Percentage (0-100)
	Total  *uint64  // Nanoseconds
}

PSIStats represent the Pressure Stall Information data Source: cgroupv1: not present cgroupv2: *.pressure

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader is the main interface to scrape data from cgroups Calling RefreshCgroups() with your cache toleration is mandatory to retrieve accurate data All Reader methods support concurrent calls

func NewReader

func NewReader(opts ...ReaderOption) (*Reader, error)

NewReader returns a new cgroup reader with given options

func NewSelfReader

func NewSelfReader(selfProcPath string, inContainer bool, opts ...ReaderOption) (*Reader, error)

NewSelfReader allows to get current process cgroup stats selfProcPath should always be `/proc`, taken as parameter to allow unit testing

func (*Reader) CgroupVersion

func (r *Reader) CgroupVersion() int

CgroupVersion returns the detected cgroup version

func (*Reader) GetCgroup

func (r *Reader) GetCgroup(id string) Cgroup

GetCgroup returns cgroup for a given id, or nil if not found.

func (*Reader) GetCgroupByInode added in v0.51.0

func (r *Reader) GetCgroupByInode(inode uint64) Cgroup

GetCgroupByInode returns the cgroup for the given inode.

func (*Reader) ListCgroups

func (r *Reader) ListCgroups() []Cgroup

ListCgroups returns list of known cgroups

func (*Reader) RefreshCgroups

func (r *Reader) RefreshCgroups(cacheValidity time.Duration) error

RefreshCgroups triggers a refresh if data are older than cacheValidity. 0 to always refesh.

type ReaderFilter

type ReaderFilter func(path, name string) (string, error)

ReaderFilter allows to filter cgroups based on their path + folder name

type ReaderOption

type ReaderOption func(*Reader)

ReaderOption allows to customize reader behavior (Builder-style)

func WithCgroupV1BaseController

func WithCgroupV1BaseController(controller string) ReaderOption

WithCgroupV1BaseController sets which controller is used to select cgroups it then assumes that, if being, used other controllers uses the same relative path. Default to "memory" if not set.

func WithHostPrefix

func WithHostPrefix(hostPrefix string) ReaderOption

WithHostPrefix sets where hosts path are mounted (if not running on-host)

func WithProcPath

func WithProcPath(fullPath string) ReaderOption

WithProcPath sets where /proc is currently mounted. If set, hostPrefix is not added to this path. Default to `$hostPrefix/proc` if empty.

func WithReaderFilter

func WithReaderFilter(rf ReaderFilter) ReaderOption

WithReaderFilter sets the filter used to select interesting cgroup folders and provides an identifier for them.

type Reporter

type Reporter interface {
	// HandleError is called when a non-blocking error has been encountered.
	// e is the encountered error
	HandleError(e error)

	// FileAccessed is called everytime time a file is opened
	FileAccessed(path string)
}

Reporter defines some hooks that can be used to track and report on cgroup parsing. It's typically useful for logging and debugging. Reporter implementations should support concurrent calls.

type StandalonePIDMapper added in v0.50.0

type StandalonePIDMapper interface {
	GetPIDs(cgroupIdentifier string, cacheValidity time.Duration) []int
}

StandalonePIDMapper allows to get a PID Mapper that could work without cgroup objects. This is required when PID namespace is shared but cgroup namespace is not (typically in serverless-like scenarios)

func NewStandalonePIDMapper added in v0.50.0

func NewStandalonePIDMapper(procPath, cgroupController string, filter ReaderFilter) StandalonePIDMapper

NewStandalonePIDMapper returns a new instance

type Stats

type Stats struct {
	CPU    *CPUStats
	Memory *MemoryStats
	IO     *IOStats
	PID    *PIDStats
}

Stats wraps all container metrics

type ValueError

type ValueError struct {
	Data string
	Err  error
}

ValueError is reported when the parser encounters an unexpected content in a cgroup file. This error is not blocking and will only be retported through the reporter. Seeing this error means that there's either in bug in the parsing code (most likely), unsupported new cgroup feature, Kernel bug (less likely)

func (*ValueError) Error

func (e *ValueError) Error() string

func (*ValueError) Unwrap

func (e *ValueError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL