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 上可以有多个核心,这些核心被称为逻辑核。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))
}
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)
}
}