psutil
是一个跨平台进程和系统监控的Python库,gopsutil
是其Go版本的实现。
- 仓库地址 https://github.com/shirou/gopsutil
-
gopsutil
库会使用到golang.org/x/sys
库
安装
$ go get github.com/shirou/gopsutil
gopsutil
将不同的功能划分到不同的子包中,想要使用对应功能需要导入对应的子包。
子包 | 描述 |
---|---|
cpu | 中央处理器 |
disk | 磁盘 |
docker | Docker |
host | 主机 |
mem | 内存 |
net | 网关 |
process | 进程 |
winservices | Windows服务 |
$ go mod tidy
CPU
CPU核心分为物理核和逻辑核两种,物理核数是主板上实际安装的CPU数量,一个物理核心上可划分成多个逻辑核心后供使用。
CPU详细信息 cpu.Info
-
cpu.Info()
可获取CPU的详细信息,返回cpu.InfoStat
类型的切片。 - Windows上运行时会内部会使用
github.com/StackExchange/wmi
库获取CPU信息
package cpu
func Info() ([]InfoStat, error)
例如:获取本机CPU详细信息
info, err := cpu.Info()
fmt.Printf("%+v\n", info)
[
{
"cpu":0,
"vendorId":"GenuineIntel",
"family":"205",
"model":"",
"stepping":0,
"physicalId":"BFEBFBFF000906EA",
"coreId":"",
"cores":6,
"modelName":"Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz",
"mhz":2808,
"cacheSize":0,
"flags":[],
"microcode":""
}
]
cpu.InfoStat
字段信息
字段 | 描述 |
---|---|
modelName | 型号 |
mhz | 主频赫兹 |
cores | 逻辑核数 |
CPU时间占用 cpu.Times
cpu.Times()
用于获取时间占用数据,可以获取从开机开始总的CPU和每个单独CPU时间占用情况。若入参percpu = false
则会返回总CPU的时间占用情况。若percpu=true
获取每个核心的时间占用情况。返回值是一个cpu.TimeStat
的结构。
package cpu
func Times(percpu bool) ([]TimesStat, error)
cpu.TimeStat
结构
package cpu
type TimesStat struct {
CPU string `json:"cpu"`
User float64 `json:"user"`
System float64 `json:"system"`
Idle float64 `json:"idle"`
Nice float64 `json:"nice"`
Iowait float64 `json:"iowait"`
Irq float64 `json:"irq"`
Softirq float64 `json:"softirq"`
Steal float64 `json:"steal"`
Guest float64 `json:"guest"`
GuestNice float64 `json:"guestNice"`
}
字段 | 描述 |
---|---|
Cpu | CPU标识,percpu=false 时为cpu-total ,percpu=true 时为cpu-num 。 |
User | 用户态,用户时间占用,CPU耗费多少时间运行在用户态空间。比如Shells、数据库、Web服务器... |
System | 内核态,系统时间占用,CPU耗费多少时间在内核空间运行。分配内存、IO操作、进程操作...都需要在内核空间上操作。当IO操作频繁时,System参数值也会很高。 |
Idle | 空闲时间,表示CPU处于空闲状态时间。 |
Nice | 用户空间进程的CPU的调度优先级,范围[-20, 19]。 |
Iowait | IO读写操作导致CPU处于等待状态的时间 |
例如:获取物理核上时间占用数据
res, _ := cpu.Times(false)
fmt.Printf("%+v\n", res)
[{"cpu":"cpu-total","user":17140.5,"system":13495.3,"idle":611280.5,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}]
例如:获取每个逻辑核上的时间占用数据
res, _ := cpu.Times(true)
fmt.Printf("%+v\n", res)
[
{"cpu":"cpu0","user":2521.9,"system":3930.8,"idle":99937.7,"nice":0.0,"iowait":0.0,"irq":1897.6,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}
{"cpu":"cpu1","user":4099.9,"system":2489.4,"idle":99800.7,"nice":0.0,"iowait":0.0,"irq":71.4,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}
{"cpu":"cpu2","user":2848.0,"system":1787.0,"idle":101754.9,"nice":0.0,"iowait":0.0,"irq":36.7,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}
{"cpu":"cpu3","user":2357.5,"system":1454.8,"idle":102577.7,"nice":0.0,"iowait":0.0,"irq":33.8,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}
{"cpu":"cpu4","user":2177.8,"system":1553.2,"idle":102659.0,"nice":0.0,"iowait":0.0,"irq":62.8,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}
{"cpu":"cpu5","user":3014.4,"system":2179.7,"idle":101195.9,"nice":0.0,"iowait":0.0,"irq":83.7,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}
]
CPU核心数 cpu.Counts
cpu.Counts(logical bool)
用于获取CPU核心的数量,CPU分为两种物理核心和逻辑核心,物理核心指代主板上实际安装的CPU,一个物理CPU上会被划分为多个逻辑核心。当入参logical=true
时会获取逻辑核心数量,当入参logical=false
时则会获取物理核心数量。
获取逻辑核数
lcnt, err := cpu.Counts(true)
if err != nil {
return
}
fmt.Printf("logical core count: %d\n", lcnt) // logical core count: 6
获取物理核数
pcnt, err := cpu.Counts(false)
if err != nil {
return
}
fmt.Printf("physical core count: %d\n", pcnt) // physical core count: 6
CPU使用率 cpu.Percent
cpu.Percent()
用于获取指定时间间隔内的当前CPU的使用率,CPU使用率指的是程序在运行期间实时占用的CPU百分比,这是对一个时间段内CPU使用状态的统计,通过它可以看出在某一个时间段内CPU被占用的情况。
package cpu
func Percent(interval time.Duration, percpu bool) ([]float64, error)
当percpu = false
时获取的是总的CPU使用率,当percpu = true
时获取的是每个CPU的使用率,返回的是一个[]float64
类型的切皮值。
例如:获取1秒内当前CPU的使用率
per, err := cpu.Percent(time.Second*time.Duration(1), false)
fmt.Printf("%+v\n", per, err) // [3.90625]
per, _ := cpu.Percent(time.Second*time.Duration(1), true)
fmt.Printf("%+v\n", per)//[13.432835820895523 3.076923076923077 1.5384615384615385 3.076923076923077 0 7.6923076923076925]
CPU负载 load.Avg
load.Avg()
可获取CPU负载信息
理解CPU负载(load-average)首先需要理解多任务,Linux能同时处理多个不同名称的任务,当同时运行多个任务时,CPU和磁盘这些优先的硬件资源会被多个任务程序共享,因此存在在多任务之间进行切换的动作。当运行中的任务较少的情况时,系统不会等待切换动作的发生。当任务增多,切换动作就需要等待CPU空闲,这种等待状态表现为程序运行延迟。
使用Linux命令uptime
查看系统平均负载的输出
$ uptime
18:40:55 up 459 days, 15:29, 1 user, load average: 0.00, 0.02, 0.05
CPU负载分为三种分别是过去1分钟、过去5分钟、过去15分钟内,单位时间的等待任务数量,CPU负载总体表示平均有多少个任务正处于等待状态。当CPU较高时说明等待运行的任务较多,由于等待时间较多就会出现较大的延迟,即反映此时负载较高。
load
func Avg() (*AvgStat, error)
type AvgStat struct {
Load1 float64 `json:"load1"`
Load5 float64 `json:"load5"`
Load15 float64 `json:"load15"`
}
字段 | 描述 |
---|---|
Load1 | 过去1分钟内,处于等待状态的任务的平均负载。 |
Load5 | 过去5分钟内,处于等待状态的任务的平均负载。 |
Load15 | 过去15分钟内,处于等待状态的任务的平均负载。 |
例如:获取当前CPU的负载数据
stat, err := load.Avg()
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%+v\n", stat) // {"load1":0,"load5":0,"load15":0}