github.com/songzhibin97/gkit@v1.2.13/sys/cpu/cgroup.go (about)

     1  package cpu
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  // cGroupRootDir 目录位置
    14  const cGroupRootDir = "/sys/fs/cGroup"
    15  
    16  // cGroup LinuxCGroup
    17  type cGroup struct {
    18  	cGroupSet map[string]string
    19  }
    20  
    21  // CPUCFSQuotaUs 获取 cpu.cfs_quota_us 调度周期控制组被允许运行的时间
    22  func (c *cGroup) CPUCFSQuotaUs() (int64, error) {
    23  	data, err := readFile(path.Join(c.cGroupSet["cpu"], "cpu.cfs_quota_us"))
    24  	if err != nil {
    25  		return 0, err
    26  	}
    27  	return strconv.ParseInt(data, 10, 64)
    28  }
    29  
    30  // CPUCFSPeriodUs 获取 cpu.cfs_period_us 调度周期
    31  func (c *cGroup) CPUCFSPeriodUs() (uint64, error) {
    32  	data, err := readFile(path.Join(c.cGroupSet["cpu"], "cpu.cfs_period_us"))
    33  	if err != nil {
    34  		return 0, err
    35  	}
    36  	return parseUint(data)
    37  }
    38  
    39  // CPUAcctUsage cpuacct.usage CPU使用率
    40  func (c *cGroup) CPUAcctUsage() (uint64, error) {
    41  	data, err := readFile(path.Join(c.cGroupSet["cpuacct"], "cpuacct.usage"))
    42  	if err != nil {
    43  		return 0, err
    44  	}
    45  	return parseUint(data)
    46  }
    47  
    48  // CPUAcctUsagePerCPU cpuacct.usage_percpu cGroup中所有任务消耗的cpu时间
    49  func (c *cGroup) CPUAcctUsagePerCPU() ([]uint64, error) {
    50  	data, err := readFile(path.Join(c.cGroupSet["cpuacct"], "cpuacct.usage_percpu"))
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	var usage []uint64
    55  	for _, v := range strings.Fields(string(data)) {
    56  		var u uint64
    57  		if u, err = parseUint(v); err != nil {
    58  			return nil, err
    59  		}
    60  		if u != 0 {
    61  			usage = append(usage, u)
    62  		}
    63  	}
    64  	return usage, nil
    65  }
    66  
    67  // CPUSetCPUs cpuset.cpus 获取核心数
    68  func (c *cGroup) CPUSetCPUs() ([]uint64, error) {
    69  	data, err := readFile(path.Join(c.cGroupSet["cpuset"], "cpuset.cpus"))
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	cpus, err := ParseUintList(data)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	var sets []uint64
    78  	for k := range cpus {
    79  		sets = append(sets, uint64(k))
    80  	}
    81  	return sets, nil
    82  }
    83  
    84  // currentcGroup 获取当当前进程的 cGroup
    85  func currentcGroup() (*cGroup, error) {
    86  	pid := os.Getpid()
    87  	cgroupFile := fmt.Sprintf("/proc/%d/cGroup", pid)
    88  	cgroupSet := make(map[string]string)
    89  	fp, err := os.Open(cgroupFile)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	defer fp.Close()
    94  	buf := bufio.NewReader(fp)
    95  	for {
    96  		line, err := buf.ReadString('\n')
    97  		if err != nil {
    98  			if err == io.EOF {
    99  				break
   100  			}
   101  			return nil, err
   102  		}
   103  		col := strings.Split(strings.TrimSpace(line), ":")
   104  		if len(col) != 3 {
   105  			return nil, fmt.Errorf("invalid cGroup format %s", line)
   106  		}
   107  		dir := col[2]
   108  		// 如果dir不是 "/" 则必须在docker中
   109  		if dir != "/" {
   110  			cgroupSet[col[1]] = path.Join(cGroupRootDir, col[1])
   111  			if strings.Contains(col[1], ",") {
   112  				for _, k := range strings.Split(col[1], ",") {
   113  					cgroupSet[k] = path.Join(cGroupRootDir, k)
   114  				}
   115  			}
   116  		} else {
   117  			cgroupSet[col[1]] = path.Join(cGroupRootDir, col[1], col[2])
   118  			if strings.Contains(col[1], ",") {
   119  				for _, k := range strings.Split(col[1], ",") {
   120  					cgroupSet[k] = path.Join(cGroupRootDir, k, col[2])
   121  				}
   122  			}
   123  		}
   124  	}
   125  	return &cGroup{cGroupSet: cgroupSet}, nil
   126  }