gopsutil的进阶使用(disk,net)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gopsutil的进阶使用(disk,net)相关的知识,希望对你有一定的参考价值。

gopsutil的进阶使用(disk,net)

1.disk

func getIOCount(cnt int) 
	//defer wg.Done()
	//var arr []test2
	for i := 0; i < cnt; i++ 
		st, err := disk.IOCounters()
		if err != nil 
			return
		
		for name, stat := range st 
			fmt.Println(name)
			data, _ := json.MarshalIndent(stat, "", "  ")
			fmt.Println(string(data))
		
		//val := strconv.FormatFloat(totalPercent[0], 'f', 2, 64)
		//key := time.Now().Unix()
		//*arr = append(*arr, test2key, val[0])
	

使用disk.IOCounters() 默认是返回磁盘所有分区的信息。

函数可以传分区名作为参数,获取某一个分区的st对应的map。

注意,disk.IOCounters()可传入可变数量的字符串参数用于标识分区,此参数在 Windows 上无效

st, err := disk.IOCounters("C")	//windows无效
		if err != nil 
			return
		
		fmt.Println(st["C"])
		fmt.Println(st)

每个st都是一个map <key,val> 对象,可以转成json。

结果如下:

C:

  "readCount": 524494,
  "mergedReadCount": 0,
  "writeCount": 113819,
  "mergedWriteCount": 0,
  "readBytes": 9716819968,
  "writeBytes": 2462403072,
  "readTime": 212,
  "writeTime": 46,
  "iopsInProgress": 0,
  "ioTime": 0,
  "weightedIO": 0,
  "name": "C:",
  "serialNumber": "",
  "label": ""

D:

  "readCount": 626816,
  "mergedReadCount": 0,
  "writeCount": 183627,
  "mergedWriteCount": 0,
  "readBytes": 10348119552,
  "writeBytes": 3206097408,
  "readTime": 152,
  "writeTime": 30,
  "iopsInProgress": 0,
  "ioTime": 0,
  "weightedIO": 0,
  "name": "D:",
  "serialNumber": "",
  "label": ""

可以得到每个分区的读写次数、字节大小、时间等信息。


上传到mongodb

type IOdata struct 
	Key int64  `json:"key" bson:"key"`
	Rc  uint64 `json:"rc" bson:"rc"`
	Wc  uint64 `json:"wc" bson:"wc"`



func getIOCount(cnt int, arr *[]IOdata) 
	defer wg.Done()
	name := "C:" //磁盘分区名
	for i := 0; i < cnt; i++ 
		st, err := disk.IOCounters()
		if err != nil 
			fmt.Print("getIOCount", err)
			return
		
		key := time.Now().Unix()
		*arr = append(*arr, IOdatakey, st[name].ReadCount, st[name].WriteCount)
		time.Sleep(5 * time.Second) //每隔1分钟计算一次IO_COUNT
	


2.net

监控网络带宽可以使用net包。

NetIOCounters returns network I/O statistics for every network interface installed on the system. If pernic argument is false, return only sum of all information (which name is ‘all’). If true, every network interface installed on the system is returned separately.

若参数pernic 为true,则返回每个接口对应的网络IO信息(是一个结构体数组),否则将所有接口汇总。

func getNetIO(cnt int) 
	st, err := net.IOCounters(true)
	if err != nil 
		return
	
	for k, v := range st 
		fmt.Println(k)
		fmt.Println(v)
	

结果

"name":"以太网 6","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0
1
"name":"WLAN","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0
2
"name":"本地连接* 9","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0
3
"name":"本地连接* 10","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0
4
"name":"以太网","bytesSent":15057867,"bytesRecv":89158774,"packetsSent":78166,"packetsRecv":90436,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0
5
"name":"以太网 4","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0   
6
"name":"Connect","bytesSent":13211954,"bytesRecv":88433445,"packetsSent":78129,"packetsRecv":90401,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0
7
"name":"蓝牙网络连接","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0
8
"name":"Loopback Pseudo-Interface 1","bytesSent":0,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0

参数改为false,返回的是汇总的信息,并且name=all

0
"name":"all","bytesSent":29565260,"bytesRecv":189888289,"packetsSent":167974,"packetsRecv":193188,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0

如何计算每秒的入网和出网速度 kbit/s呢?

func getNetIO(cnt int, arr *[]NetData) 
	defer wg.Done()
	st, err := net.IOCounters(false)
	lastSend, lastRecv := st[0].BytesSent, st[0].BytesRecv
	time.Sleep(5 * time.Second)
	for i := 0; i < cnt; i++ 
		st, err = net.IOCounters(false)
		if err != nil 
			fmt.Print("getNetIO", err)
			return
		
		key := time.Now().Unix()
		fmt.Println(st[0].BytesSent - lastSend)
		// (*8/1024/5 = /640)
		*arr = append(*arr, NetDatakey, float32(st[0].BytesSent-lastSend) / 640.0, float32(st[0].BytesRecv-lastRecv) / 640.0)
		lastSend, lastRecv = st[0].BytesSent, st[0].BytesRecv
		time.Sleep(5 * time.Second) //每隔5s计算一次IO_NET
	
	//fmt.Println("arr", arr)
	//st, err := net.IOCounters(false)
	//if err != nil 
	//	return
	//
	//fmt.Printf("BytesSent: %v  BytesRecv:%v\\n", st[0].BytesSent, st[0].BytesRecv)
	//BytesSent: 30063747  BytesRecv:191945075

我们保存上一次计算的BytesSent、BytesRecv记为lastSend, lastRecv。

然后隔一定的时间就重新调用st, err = net.IOCounters(false)

然后通过计算传输的数据大小除以时间,便可以得到传输的速度。

使用echarts 可视化结果如下图所示。

以上是关于gopsutil的进阶使用(disk,net)的主要内容,如果未能解决你的问题,请参考以下文章

GoCN酷Go推荐Go 系统监控利器-gopsutil

Go使用gopsutil 和 go-echarts 生成系统状态图表

kvm-virsh使用

golang CPU使用率

Mysql数据库--语句整理/提升/进阶/高级使用技巧

Golang利用第三方包获取本机cpu使用率以及内存使用情况