博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用 golang 收集系统指标
阅读量:6828 次
发布时间:2019-06-26

本文共 6743 字,大约阅读时间需要 22 分钟。

  hot3.png

common.go

// copy code from github.com/shirou/gopsutilpackage sysimport (	"bufio"	"os"	"strings")// ReadLines reads contents from file and splits them by new line.// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).func readLines(filename string) ([]string, error) {	return readLinesOffsetN(filename, 0, -1)}// ReadLines reads contents from file and splits them by new line.// The offset tells at which line number to start.// The count determines the number of lines to read (starting from offset)://   n >= 0: at most n lines//   n < 0: whole filefunc readLinesOffsetN(filename string, offset uint, n int) ([]string, error) {	f, err := os.Open(filename)	if err != nil {		return []string{""}, err	}	defer f.Close()	var ret []string	r := bufio.NewReader(f)	for i := 0; i < n+int(offset) || n < 0; i++ {		line, err := r.ReadString('\n')		if err != nil {			break		}		if i < int(offset) {			continue		}		ret = append(ret, strings.Trim(line, "\n"))	}	return ret, nil}

sys.go

// copy code from github.com/shirou/gopsutil// almost the same, but change a lot, especially the returned structpackage sysimport (	"errors"	"io/ioutil"	"strconv"	"strings")type SysStat struct {	// /proc/loadavg	Load1  float64	Load5  float64	Load15 float64	// /proc/meminfo	Total       uint64	Available   uint64	Used        uint64	UsedPercent float64	Free        uint64	Active      uint64	Inactive    uint64	Buffers     uint64	Cached      uint64	Wired       uint64	Shared      uint64	// /proc/net/dev	// sum of all interfaces	Name        string	BytesSent   uint64	BytesRecv   uint64	PacketsSent uint64	PacketsRecv uint64	// /proc/stat	CPU       string	User      float64	System    float64	Idle      float64	Nice      float64	Iowait    float64	Irq       float64	Softirq   float64	Steal     float64	Guest     float64	GuestNice float64	Stolen    float64}func GetSysStat() *SysStat {	stat := new(SysStat)	stat.cPUTimes()	stat.netIOCounters()	stat.virtualMemory()	stat.loadAvg()	return stat}func (stat *SysStat) cPUTimes() error {	filename := "/proc/stat"	var lines = []string{}	lines, _ = readLinesOffsetN(filename, 0, 1)	err := stat.parseStatLine(lines[0])	if err != nil {		return err	}	return nil}func (stat *SysStat) parseStatLine(line string) error {	fields := strings.Fields(line)	if strings.HasPrefix(fields[0], "cpu") == false {		return errors.New("not contain cpu")	}	cpu := fields[0]	if cpu == "cpu" {		cpu = "cpu-total"	}	user, err := strconv.ParseFloat(fields[1], 64)	if err != nil {		return err	}	nice, err := strconv.ParseFloat(fields[2], 64)	if err != nil {		return err	}	system, err := strconv.ParseFloat(fields[3], 64)	if err != nil {		return err	}	idle, err := strconv.ParseFloat(fields[4], 64)	if err != nil {		return err	}	iowait, err := strconv.ParseFloat(fields[5], 64)	if err != nil {		return err	}	irq, err := strconv.ParseFloat(fields[6], 64)	if err != nil {		return err	}	softirq, err := strconv.ParseFloat(fields[7], 64)	if err != nil {		return err	}	stolen, err := strconv.ParseFloat(fields[8], 64)	if err != nil {		return err	}	cpu_tick := float64(100) // TODO: how to get _SC_CLK_TCK ?	stat.CPU = cpu	stat.User = float64(user) / cpu_tick	stat.Nice = float64(nice) / cpu_tick	stat.System = float64(system) / cpu_tick	stat.Idle = float64(idle) / cpu_tick	stat.Iowait = float64(iowait) / cpu_tick	stat.Irq = float64(irq) / cpu_tick	stat.Softirq = float64(softirq) / cpu_tick	stat.Stolen = float64(stolen) / cpu_tick	if len(fields) > 9 { // Linux >= 2.6.11		steal, err := strconv.ParseFloat(fields[9], 64)		if err != nil {			return err		}		stat.Steal = float64(steal)	}	if len(fields) > 10 { // Linux >= 2.6.24		guest, err := strconv.ParseFloat(fields[10], 64)		if err != nil {			return err		}		stat.Guest = float64(guest)	}	if len(fields) > 11 { // Linux >= 3.2.0		guestNice, err := strconv.ParseFloat(fields[11], 64)		if err != nil {			return err		}		stat.GuestNice = float64(guestNice)	}	return nil}type netIOCountersStat struct {	Name        string	BytesSent   uint64	BytesRecv   uint64	PacketsSent uint64	PacketsRecv uint64}func (stat *SysStat) netIOCounters() error {	filename := "/proc/net/dev"	lines, err := readLines(filename)	if err != nil {		return err	}	statlen := len(lines) - 1	all := make([]netIOCountersStat, 0, statlen)	for _, line := range lines[2:] {		parts := strings.SplitN(line, ":", 2)		if len(parts) != 2 {			continue		}		interfaceName := strings.TrimSpace(parts[0])		if interfaceName == "" {			continue		}		fields := strings.Fields(strings.TrimSpace(parts[1]))		bytesRecv, err := strconv.ParseUint(fields[0], 10, 64)		if err != nil {			return err		}		packetsRecv, err := strconv.ParseUint(fields[1], 10, 64)		if err != nil {			return err		}		bytesSent, err := strconv.ParseUint(fields[8], 10, 64)		if err != nil {			return err		}		packetsSent, err := strconv.ParseUint(fields[9], 10, 64)		if err != nil {			return err		}		nic := netIOCountersStat{			Name:        interfaceName,			BytesRecv:   bytesRecv,			PacketsRecv: packetsRecv,			BytesSent:   bytesSent,			PacketsSent: packetsSent}		all = append(all, nic)	}	return stat.getNetIOCountersAll(all)}func (stat *SysStat) getNetIOCountersAll(n []netIOCountersStat) error {	stat.Name = "all-interfaces"	for _, nic := range n {		stat.BytesRecv += nic.BytesRecv		stat.PacketsRecv += nic.PacketsRecv		stat.BytesSent += nic.BytesSent		stat.PacketsSent += nic.PacketsSent	}	return nil}func (stat *SysStat) virtualMemory() error {	filename := "/proc/meminfo"	lines, _ := readLines(filename)	for _, line := range lines {		fields := strings.Split(line, ":")		if len(fields) != 2 {			continue		}		key := strings.TrimSpace(fields[0])		value := strings.TrimSpace(fields[1])		value = strings.Replace(value, " kB", "", -1)		t, err := strconv.ParseUint(value, 10, 64)		if err != nil {			return err		}		switch key {		case "MemTotal":			stat.Total = t * 1000		case "MemFree":			stat.Free = t * 1000		case "Buffers":			stat.Buffers = t * 1000		case "Cached":			stat.Cached = t * 1000		case "Active":			stat.Active = t * 1000		case "Inactive":			stat.Inactive = t * 1000		}	}	stat.Available = stat.Free + stat.Buffers + stat.Cached	stat.Used = stat.Total - stat.Free	stat.UsedPercent = float64(stat.Total-stat.Available) / float64(stat.Total) * 100.0	return nil}func (stat *SysStat) loadAvg() error {	filename := "/proc/loadavg"	line, err := ioutil.ReadFile(filename)	if err != nil {		return err	}	values := strings.Fields(string(line))	load1, err := strconv.ParseFloat(values[0], 64)	if err != nil {		return err	}	load5, err := strconv.ParseFloat(values[1], 64)	if err != nil {		return err	}	load15, err := strconv.ParseFloat(values[2], 64)	if err != nil {		return err	}	stat.Load1 = load1	stat.Load5 = load5	stat.Load15 = load15	return nil}

转载于:https://my.oschina.net/astute/blog/417480

你可能感兴趣的文章
deepin15.7 更新升级之后,sogou 浏览器chrome,firfox 中无法使用中文输入
查看>>
Quartz集群原理及配置应用
查看>>
路由网关转发配置
查看>>
java读取配置文件的几种方法
查看>>
Hadoop上路_03-伪分布式集群配置
查看>>
1.3 top 动态查看负载
查看>>
基于CentOS 5.6的应用服务器精简定制版出来了,ISO文件下载
查看>>
centos7 添加阿里云源
查看>>
SyntaxHighlighter行号显示错误及代码太长无法换行解决办法
查看>>
HTML5 canvas drawImage() 方法
查看>>
Python练习【7】【文件对比并输出可读性较强的html文件】
查看>>
python实现跳板机
查看>>
19个非常有用的 jQuery 图片滑动插件和教程
查看>>
Android XML shape 标签使用详解
查看>>
android 成长日记 4.BaseActivity的实现和ActivityCollectio实现
查看>>
linux64位编译php遇到configure: error: GD build test failed. Please check the config.log for details...
查看>>
oracle 启动 命令
查看>>
使用python写糗事百科的爬虫
查看>>
$MFTMirr does not match $MFT (record 0)问题解决
查看>>
oracle 修改列
查看>>