本节重点介绍 :

  • 分析主流程源码
  • cpu使用时间采集源码查看
  • cpu使用时间和cpu利用率的关系

分析源码流程

创建ProcessCollector对象

  • 代码位置 D:\go_path\pkg\mod\github.com\ncabatoff\process-exporter@v0.7.5\cmd\process-exporter\main.go
pc, err := NewProcessCollector(
		ProcessCollectorOption{
			ProcFSPath:  *procfsPath,
			Children:    *children,
			Threads:     *threads,
			GatherSMaps: *smaps,
			Namer:       matchnamer,
			Recheck:     *recheck,
			Debug:       *debug,
		},
	)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • NewProcessCollector方法中 创建/proc文件系统对象,为采集最准备
fs, err := proc.NewFS(options.ProcFSPath, options.Debug)
  • 1.
  • p.start开启采集主流程
func (p *NamedProcessCollector) start() {
	for req := range p.scrapeChan {
		ch := req.results
		p.scrape(ch)
		req.done <- struct{}{}
	}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • p.scrapeChan 会在Collect中接受来自 Describe中的待采集的指标
func (p *NamedProcessCollector) Collect(ch chan<- prometheus.Metric) {
	req := scrapeRequest{results: ch, done: make(chan struct{})}
	p.scrapeChan <- req
	<-req.done
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 采集动作 p.scrape,通过p.Update拿到/proc文件系统中的结果
permErrs, groups, err := p.Update(p.source.AllProcs())
  • 1.
  • 然后遍历赋值即可
for gname, gcounts := range groups {
			ch <- prometheus.MustNewConstMetric(numprocsDesc,
				prometheus.GaugeValue, float64(gcounts.Procs), gname)
			ch <- prometheus.MustNewConstMetric(membytesDesc,
				prometheus.GaugeValue, float64(gcounts.Memory.ResidentBytes), gname, "resident")
			ch <- prometheus.MustNewConstMetric(membytesDesc,
        }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

cpu采集和利用率

  • p.scrape函数中 namedprocess_namegroup_cpu_seconds_total user对应 CPUUserTime,system对应CPUSystemTime
ch <- prometheus.MustNewConstMetric(cpuSecsDesc,
				prometheus.CounterValue, gcounts.CPUUserTime, gname, "user")
			ch <- prometheus.MustNewConstMetric(cpuSecsDesc,
				prometheus.CounterValue, gcounts.CPUSystemTime, gname, "system")
  • 1.
  • 2.
  • 3.
  • 4.
  • getStat通过读取 /proc/stat文件获取到对应的counter指标,代码位置D:\go_path\pkg\mod\github.com\ncabatoff\process-exporter@v0.7.5\proc\read.go
func (p *proccache) getStat() (procfs.ProcStat, error) {
	if p.stat == nil {
		stat, err := p.Proc.NewStat()
		if err != nil {
			return procfs.ProcStat{}, err
		}
		p.stat = &stat
	}

	return *p.stat, nil
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • GetCounts中对CPUUserTime计算方式为 /proc/stat文件中的第二列 cpu_user/userHZ ,userHZ=100
func (p proc) GetCounts() (Counts, int, error) {
    // 忽略一些细节
    	return Counts{
    		CPUUserTime:           float64(stat.UTime) / userHZ,
    		CPUSystemTime:         float64(stat.STime) / userHZ,}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 也就是cpu利用率可以用rate(namedprocess_namegroup_cpu_seconds_total)*100得到
sum by( groupname) (rate(namedprocess_namegroup_cpu_seconds_total{groupname=~"$processes", instance="$host"}[$interval])) * 100
  • 1.
  • 100毫秒对应1个核

本节重点介绍 :

  • 分析主流程源码
  • cpu使用时间采集源码查看
  • cpu使用时间和cpu利用率的关系