示例#1
0
// Collect reads cpu.stat for cgroups and per process cpu.stat
// entries for all processes in the cgroup
func (s *PerCgroupStat) Collect() {
	file, err := os.Open(s.path + "/" + "cpu.stat")
	defer file.Close()
	if err != nil {
		return
	}

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		f := regexp.MustCompile("\\s+").Split(scanner.Text(), 2)

		if f[0] == "nr_periods" {
			s.NrPeriods.Set(misc.ParseUint(f[1]))
		}

		if f[0] == "nr_throttled" {
			s.NrThrottled.Set(misc.ParseUint(f[1]))
		}

		if f[0] == "throttled_time" {
			s.ThrottledTime.Set(misc.ParseUint(f[1]))
		}
	}

	s.CfsPeriodUs.Set(
		float64(misc.ReadUintFromFile(
			s.path + "/" + "cpu.cfs_period_us")))
	// negative values of quota indicate no quota.
	// it is not possible for this variable to be zero
	s.CfsQuotaUs.Set(
		float64(misc.ReadUintFromFile(
			s.path + "/" + "cpu.cfs_quota_us")))

	// Calculate approximate cumulative CPU usage for all
	// processes within this cgroup by calculating difference
	// between sum number of ticks.
	// We reset between loops because PIDs within cgroup can
	// change and sum-counter from previous run can be
	// unreliable
	s.getCgroupCPUTimes()
	time.Sleep(time.Millisecond * 1000)
	s.getCgroupCPUTimes()
	// Expose summary metrics for easy json access
	s.UsageCount.Set(s.usage())
	s.UserspaceCount.Set(s.userspace())
	s.KernelCount.Set(s.kernel())
	s.TotalCount.Set(s.Quota())
	s.ThrottleCount.Set(s.Throttle())
	// Reset counters
	s.Utime.Reset()
	s.Stime.Reset()
}
示例#2
0
// Unexported functions
func parseCPUline(s *PerCPU, f []string) {
	s.User.Set(misc.ParseUint(f[1]))
	s.UserLowPrio.Set(misc.ParseUint(f[2]))
	s.System.Set(misc.ParseUint(f[3]))
	s.Idle.Set(misc.ParseUint(f[4]))
	s.Iowait.Set(misc.ParseUint(f[5]))
	s.Irq.Set(misc.ParseUint(f[6]))
	s.Softirq.Set(misc.ParseUint(f[7]))
	s.Steal.Set(misc.ParseUint(f[8]))
	s.Guest.Set(misc.ParseUint(f[9]))
	s.Total.Set(s.User.Get() + s.UserLowPrio.Get() + s.System.Get() + s.Idle.Get())
}
示例#3
0
func getCPUTimes(pid string) (uint64, uint64) {
	file, err := os.Open("/proc/" + pid + "/stat")
	defer file.Close()
	if err != nil {
		return 0, 0
	}

	var user, system uint64
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		f := strings.Split(scanner.Text(), " ")
		user = misc.ParseUint(f[13])
		system = misc.ParseUint(f[14])
	}
	return user, system
}
示例#4
0
// Collect collects per process CPU/Memory/IO metrics
func (s *PerProcessStatMetrics) Collect() {

	file, err := os.Open(root + "proc/" + s.Pid + "/stat")
	defer file.Close()

	if err != nil {
		return
	}

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		f := strings.Split(scanner.Text(), " ")
		s.Utime.Set(misc.ParseUint(f[13]))
		s.Stime.Set(misc.ParseUint(f[14]))
		s.Rss.Set(float64(misc.ParseUint(f[23])))
	}

	// collect IO metrics
	// only works if we are superuser on Linux
	file, err = os.Open(root + "proc/" + s.Pid + "/io")
	defer file.Close()

	if err != nil {
		return
	}

	scanner = bufio.NewScanner(file)
	for scanner.Scan() {
		f := strings.Split(scanner.Text(), " ")
		switch f[0] {
		case "read_bytes:":
			s.IOReadBytes.Set(misc.ParseUint(f[1]))
		case "write_bytes:":
			s.IOWriteBytes.Set(misc.ParseUint(f[1]))
		}
	}
}
示例#5
0
// Unexported functions
func parseCgroupMemLine(g *metrics.Gauge, f []string) {
	length := len(f)
	val := math.NaN()

	if length < 2 {
		goto fail
	}

	val = float64(misc.ParseUint(f[1]))
	g.Set(val)
	return

fail:
	g.Set(math.NaN())
	return
}
示例#6
0
// Unexported functions
func parseMemLine(g *metrics.Gauge, f []string) {
	length := len(f)
	val := math.NaN()

	if length < 2 {
		goto fail
	}

	val = float64(misc.ParseUint(f[1]))
	if length > 2 && f[2] == "kB" {
		val *= 1024
	}

	g.Set(val)
	return

fail:
	g.Set(math.NaN())
	return
}