gopsutil是 Python 工具库psutil 的 Golang 移植版,可以帮助我们方便地获取各种系统和硬件信息。gopsutil为我们屏蔽了各个系统之间的差异,具有非常强悍的可移植性。有了gopsutil,我们不再需要针对不同的系统使用syscall调用对应的系统方法。更棒的是gopsutil的实现中没有任何cgo的代码,使得交叉编译成为可能。
安装 #
go get github.com/shirou/gopsutil
gopsutil将不同的功能划分到不同的子包中,想要使用对应的功能,要导入对应的子包。
cpu:CPU 相关;disk:磁盘相关;docker:docker 相关;host:主机相关;mem:内存相关;net:网络相关;process:进程相关;winservices:Windows 服务相关。
CPU #
CPU 的核数有两种,一种是物理核数,一种是逻辑核数。物理核数就是主板上实际有多少个 CPU,一个物理 CPU 上可以有多个核心,这些核心被称为逻辑核。gopsutil中 CPU 相关功能在cpu子包中,cpu子包提供了获取物理和逻辑核数、CPU 使用率的接口。
Counts(logical bool):传入false,返回物理核数,传入true,返回逻辑核数;Percent(interval time.Duration, percpu bool):表示获取interval时间间隔内的 CPU 使用率,percpu为false时,获取总的 CPU 使用率,percpu为true时,分别获取每个 CPU 的使用率,返回一个[]float64类型的值。Info():获取cpu详细信息Times(percpu bool):获取从开机算起,总 CPU 和 每个单独的 CPU 时间占用情况,函数返回一个TimeStat结构
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 统计、分区和使用率信息。
IOCounters():返回的 IO 统计信息用map[string]IOCountersStat类型表示。每个分区一个结构,键为分区名,值为统计信息。disk.Usage(path string):即可获得路径path所在磁盘的使用情况,返回一个UsageStat结构
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)
}
}