3、gopsutil

gopsutil是 Python 工具库psutil 的 Golang 移植版,可以帮助我们方便地获取各种系统和硬件信息。gopsutil为我们屏蔽了各个系统之间的差异,具有非常强悍的可移植性。有了gopsutil,我们不再需要针对不同的系统使用syscall调用对应的系统方法。更棒的是gopsutil的实现中没有任何cgo的代码,使得交叉编译成为可能。

安装

go get github.com/shirou/gopsutil

gopsutil将不同的功能划分到不同的子包中,想要使用对应的功能,要导入对应的子包。

CPU

CPU 的核数有两种,一种是物理核数,一种是逻辑核数。物理核数就是主板上实际有多少个 CPU,一个物理 CPU 上可以有多个核心,这些核心被称为逻辑核。gopsutil中 CPU 相关功能在cpu子包中,cpu子包提供了获取物理和逻辑核数、CPU 使用率的接口。

package main

import (
	"encoding/json"
	"fmt"
	"github.com/shirou/gopsutil/cpu"
	"time"
)

func main() {
	c, _ := cpu.Counts(false)
	fmt.Printf("cpu物理核心数:%d\n", c)
	lgc, _ := cpu.Counts(true)
	fmt.Printf("cpu逻辑核心数:%d\n", lgc)
	perUse, _ := cpu.Percent(3*time.Second, true)
	fmt.Printf("cpu3秒内使用率分别为:%v\n", perUse)
	use, _ := cpu.Percent(3*time.Second, false)
	fmt.Printf("cpu3秒内总使用率为:%f\n", use)
	info, _ := cpu.Info()
	j, _ := json.MarshalIndent(info, "", " ")
	fmt.Println(string(j))
	perU, _ := cpu.Times(true)
	fmt.Printf("从开机到现在,cpu占用时间分别为:%v\n", perU)
	u, _ := cpu.Times(false)
	fmt.Printf("从开机到现在,cpu总占用时间为:%v\n", u)
}

磁盘

子包disk用于获取磁盘信息。disk可获取 IO 统计、分区和使用率信息。

package main

import (
	"encoding/json"
	"fmt"
	"github.com/shirou/gopsutil/disk"
)

func main() {
	di, _ := disk.IOCounters()
	diJ, _ := json.MarshalIndent(di, "", " ")
	fmt.Println("每个盘的IO统计")
	fmt.Println(string(diJ))
	c, _ := disk.Usage("C:/")
	fmt.Printf("C盘的使用情况%v\n", c)
}

主机

子包host可以获取主机相关信息,如开机时间、内核版本号、平台信息等等。

BootTime():返回主机开机时间的时间戳

KernelVersion():返回主机内核版本

PlatformInformation():返回主机平台信息

Users():返回终端连接上来的用户信息,每个用户一个UserStat结构

package main

import (
	"fmt"
	"github.com/shirou/gopsutil/host"
	"time"
)

func main() {
	bt, _ := host.BootTime()
	t := time.Unix(int64(bt), 0)
	str := t.Local().Format("2006-01-02 15:04:05")
	fmt.Printf("主机开机时间为:%s\n", str)
	version, _ := host.KernelVersion()
	fmt.Printf("主机内核版本为:%s\n", version)
	platform, family, version, _ := host.PlatformInformation()
	fmt.Printf("平台:%s\n", platform)
	fmt.Printf("型号:%s\n", family)
	fmt.Printf("平台版本:%s\n", version)
	users, _ := host.Users()
	fmt.Printf("当前连接用户:%v\n", users)
}

内存

VirtualMemory():用来获取内存信息,该函数返回的只是物理内存信息。还可以使用mem.SwapMemory()获取交换内存的信息,信息存储在结构SwapMemoryStat

package main

import (
	"encoding/json"
	"fmt"
	"github.com/shirou/gopsutil/mem"
)

func main() {
	v, _ := mem.VirtualMemory()
	data, _ := json.MarshalIndent(v, "", " ")
	fmt.Println(string(data))
}

进程

process可用于获取系统当前运行的进程信息,创建新进程,对进程进行一些操作等。

package main

import (
	"encoding/json"
	"fmt"
	"github.com/shirou/gopsutil/process"
)

func main() {
	processes, _ := process.Processes()
	data, _ := json.MarshalIndent(processes, "", " ")
	fmt.Println(string(data))
}

Windows 服务

winservices子包可以获取 Windows 系统中的服务信息,内部使用了golang.org/x/sys包,在winservices中,一个服务对应一个Service结构。

注意,调用winservices.ListServices()返回的Service对象信息是不全的,我们通过NewService()以该服务名称创建一个服务,然后调用GetServiceDetail()方法获取该服务的详细信息。不能直接通过service.GetServiceDetail()来调用,因为ListService()返回的对象缺少必要的系统资源句柄(为了节约资源),调用GetServiceDetail()方法会panic!!!

package main

import (
	"fmt"
	"github.com/shirou/gopsutil/winservices"
)

func main() {
	services, _ := winservices.ListServices()
	for _, service := range services {
		newservice, _ := winservices.NewService(service.Name)
		newservice.GetServiceDetail()
		fmt.Println("Name:", newservice.Name, "Binary Path:", newservice.Config.BinaryPathName, "State: ", newservice.Status.State)
	}
}