github.com/elastic/gosigar@v0.14.3/cgroup/cpu.go (about)

     1  package cgroup
     2  
     3  import (
     4  	"bufio"
     5  	"os"
     6  	"path/filepath"
     7  )
     8  
     9  // CPUSubsystem contains metrics and limits from the "cpu" subsystem. This
    10  // subsystem is used to guarantee a minimum number of cpu shares to the cgroup
    11  // when the system is busy. This subsystem does not track CPU usage, for that
    12  // information see the "cpuacct" subsystem.
    13  type CPUSubsystem struct {
    14  	Metadata
    15  	// Completely Fair Scheduler (CFS) settings.
    16  	CFS CFS `json:"cfs,omitempty"`
    17  	// Real-time (RT) Scheduler settings.
    18  	RT RT `json:"rt,omitempty"`
    19  	// CPU time statistics for tasks in this cgroup.
    20  	Stats ThrottleStats `json:"stats,omitempty"`
    21  }
    22  
    23  // RT contains the tunable parameters for the real-time scheduler.
    24  type RT struct {
    25  	// Period of time in microseconds for how regularly the cgroup's access to
    26  	// CPU resources should be reallocated.
    27  	PeriodMicros uint64 `json:"period_us"`
    28  	// Period of time in microseconds for the longest continuous period in which
    29  	// the tasks in the cgroup have access to CPU resources.
    30  	RuntimeMicros uint64 `json:"quota_us"`
    31  }
    32  
    33  // CFS contains the tunable parameters for the completely fair scheduler.
    34  type CFS struct {
    35  	// Period of time in microseconds for how regularly the cgroup's access to
    36  	// CPU resources should be reallocated.
    37  	PeriodMicros uint64 `json:"period_us"`
    38  	// Total amount of time in microseconds for which all tasks in the cgroup
    39  	// can run during one period.
    40  	QuotaMicros uint64 `json:"quota_us"`
    41  	// Relative share of CPU time available to tasks the cgroup. The value is
    42  	// an integer greater than or equal to 2.
    43  	Shares uint64 `json:"shares"`
    44  }
    45  
    46  // ThrottleStats contains stats that indicate the extent to which this cgroup's
    47  // CPU usage was throttled.
    48  type ThrottleStats struct {
    49  	// Number of periods with throttling active.
    50  	Periods uint64 `json:"periods,omitempty"`
    51  	// Number of periods when the cgroup hit its throttling limit.
    52  	ThrottledPeriods uint64 `json:"throttled_periods,omitempty"`
    53  	// Aggregate time the cgroup was throttled for in nanoseconds.
    54  	ThrottledTimeNanos uint64 `json:"throttled_nanos,omitempty"`
    55  }
    56  
    57  // get reads metrics from the "cpu" subsystem. path is the filepath to the
    58  // cgroup hierarchy to read.
    59  func (cpu *CPUSubsystem) get(path string) error {
    60  	if err := cpuCFS(path, cpu); err != nil {
    61  		return err
    62  	}
    63  
    64  	if err := cpuRT(path, cpu); err != nil {
    65  		return err
    66  	}
    67  
    68  	if err := cpuStat(path, cpu); err != nil {
    69  		return err
    70  	}
    71  
    72  	return nil
    73  }
    74  
    75  func cpuStat(path string, cpu *CPUSubsystem) error {
    76  	f, err := os.Open(filepath.Join(path, "cpu.stat"))
    77  	if err != nil {
    78  		if os.IsNotExist(err) {
    79  			return nil
    80  		}
    81  		return err
    82  	}
    83  	defer f.Close()
    84  
    85  	sc := bufio.NewScanner(f)
    86  	for sc.Scan() {
    87  		t, v, err := parseCgroupParamKeyValue(sc.Text())
    88  		if err != nil {
    89  			return err
    90  		}
    91  		switch t {
    92  		case "nr_periods":
    93  			cpu.Stats.Periods = v
    94  
    95  		case "nr_throttled":
    96  			cpu.Stats.ThrottledPeriods = v
    97  
    98  		case "throttled_time":
    99  			cpu.Stats.ThrottledTimeNanos = v
   100  		}
   101  	}
   102  
   103  	return sc.Err()
   104  }
   105  
   106  func cpuCFS(path string, cpu *CPUSubsystem) error {
   107  	var err error
   108  	cpu.CFS.PeriodMicros, err = parseUintFromFile(path, "cpu.cfs_period_us")
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	cpu.CFS.QuotaMicros, err = parseUintFromFile(path, "cpu.cfs_quota_us")
   114  	if err != nil {
   115  		return err
   116  	}
   117  
   118  	cpu.CFS.Shares, err = parseUintFromFile(path, "cpu.shares")
   119  	if err != nil {
   120  		return err
   121  	}
   122  
   123  	return nil
   124  }
   125  
   126  func cpuRT(path string, cpu *CPUSubsystem) error {
   127  	var err error
   128  	cpu.RT.PeriodMicros, err = parseUintFromFile(path, "cpu.rt_period_us")
   129  	if err != nil {
   130  		return err
   131  	}
   132  
   133  	cpu.RT.RuntimeMicros, err = parseUintFromFile(path, "cpu.rt_runtime_us")
   134  	if err != nil {
   135  		return err
   136  	}
   137  
   138  	return nil
   139  }