135 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
| // +build freebsd
 | |
| 
 | |
| package cpu
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"regexp"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	common "github.com/influxdb/telegraf/plugins/system/ps/common"
 | |
| )
 | |
| 
 | |
| // sys/resource.h
 | |
| const (
 | |
| 	CPUser    = 0
 | |
| 	CPNice    = 1
 | |
| 	CPSys     = 2
 | |
| 	CPIntr    = 3
 | |
| 	CPIdle    = 4
 | |
| 	CPUStates = 5
 | |
| )
 | |
| 
 | |
| // time.h
 | |
| const (
 | |
| 	ClocksPerSec = 128
 | |
| )
 | |
| 
 | |
| func CPUTimes(percpu bool) ([]CPUTimesStat, error) {
 | |
| 	var ret []CPUTimesStat
 | |
| 
 | |
| 	var sysctlCall string
 | |
| 	var ncpu int
 | |
| 	if percpu {
 | |
| 		sysctlCall = "kern.cp_times"
 | |
| 		ncpu, _ = CPUCounts(true)
 | |
| 	} else {
 | |
| 		sysctlCall = "kern.cp_time"
 | |
| 		ncpu = 1
 | |
| 	}
 | |
| 
 | |
| 	cpuTimes, err := common.DoSysctrl(sysctlCall)
 | |
| 	if err != nil {
 | |
| 		return ret, err
 | |
| 	}
 | |
| 
 | |
| 	for i := 0; i < ncpu; i++ {
 | |
| 		offset := CPUStates * i
 | |
| 		user, err := strconv.ParseFloat(cpuTimes[CPUser+offset], 64)
 | |
| 		if err != nil {
 | |
| 			return ret, err
 | |
| 		}
 | |
| 		nice, err := strconv.ParseFloat(cpuTimes[CPNice+offset], 64)
 | |
| 		if err != nil {
 | |
| 			return ret, err
 | |
| 		}
 | |
| 		sys, err := strconv.ParseFloat(cpuTimes[CPSys+offset], 64)
 | |
| 		if err != nil {
 | |
| 			return ret, err
 | |
| 		}
 | |
| 		idle, err := strconv.ParseFloat(cpuTimes[CPIdle+offset], 64)
 | |
| 		if err != nil {
 | |
| 			return ret, err
 | |
| 		}
 | |
| 		intr, err := strconv.ParseFloat(cpuTimes[CPIntr+offset], 64)
 | |
| 		if err != nil {
 | |
| 			return ret, err
 | |
| 		}
 | |
| 
 | |
| 		c := CPUTimesStat{
 | |
| 			User:   float64(user / ClocksPerSec),
 | |
| 			Nice:   float64(nice / ClocksPerSec),
 | |
| 			System: float64(sys / ClocksPerSec),
 | |
| 			Idle:   float64(idle / ClocksPerSec),
 | |
| 			Irq:    float64(intr / ClocksPerSec),
 | |
| 		}
 | |
| 		if !percpu {
 | |
| 			c.CPU = "cpu-total"
 | |
| 		} else {
 | |
| 			c.CPU = fmt.Sprintf("cpu%d", i)
 | |
| 		}
 | |
| 
 | |
| 		ret = append(ret, c)
 | |
| 	}
 | |
| 
 | |
| 	return ret, nil
 | |
| }
 | |
| 
 | |
| // Returns only one CPUInfoStat on FreeBSD
 | |
| func CPUInfo() ([]CPUInfoStat, error) {
 | |
| 	filename := "/var/run/dmesg.boot"
 | |
| 	lines, _ := common.ReadLines(filename)
 | |
| 
 | |
| 	var ret []CPUInfoStat
 | |
| 
 | |
| 	c := CPUInfoStat{}
 | |
| 	for _, line := range lines {
 | |
| 		if matches := regexp.MustCompile(`CPU:\s+(.+) \(([\d.]+).+\)`).FindStringSubmatch(line); matches != nil {
 | |
| 			c.ModelName = matches[1]
 | |
| 			t, err := strconv.ParseFloat(matches[2], 64)
 | |
| 			if err != nil {
 | |
| 				return ret, nil
 | |
| 			}
 | |
| 			c.Mhz = t
 | |
| 		} else if matches := regexp.MustCompile(`Origin = "(.+)"  Id = (.+)  Family = (.+)  Model = (.+)  Stepping = (.+)`).FindStringSubmatch(line); matches != nil {
 | |
| 			c.VendorID = matches[1]
 | |
| 			c.Family = matches[3]
 | |
| 			c.Model = matches[4]
 | |
| 			t, err := strconv.ParseInt(matches[5], 10, 32)
 | |
| 			if err != nil {
 | |
| 				return ret, nil
 | |
| 			}
 | |
| 			c.Stepping = int32(t)
 | |
| 		} else if matches := regexp.MustCompile(`Features=.+<(.+)>`).FindStringSubmatch(line); matches != nil {
 | |
| 			for _, v := range strings.Split(matches[1], ",") {
 | |
| 				c.Flags = append(c.Flags, strings.ToLower(v))
 | |
| 			}
 | |
| 		} else if matches := regexp.MustCompile(`Features2=[a-f\dx]+<(.+)>`).FindStringSubmatch(line); matches != nil {
 | |
| 			for _, v := range strings.Split(matches[1], ",") {
 | |
| 				c.Flags = append(c.Flags, strings.ToLower(v))
 | |
| 			}
 | |
| 		} else if matches := regexp.MustCompile(`Logical CPUs per core: (\d+)`).FindStringSubmatch(line); matches != nil {
 | |
| 			// FIXME: no this line?
 | |
| 			t, err := strconv.ParseInt(matches[1], 10, 32)
 | |
| 			if err != nil {
 | |
| 				return ret, nil
 | |
| 			}
 | |
| 			c.Cores = int32(t)
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	return append(ret, c), nil
 | |
| }
 |