简介
gopsutilgopsutilgopsutilsyscallgopsutilcgo
快速使用
先安装:
$ go get github.com/shirou/gopsutil
gopsutilgolang.org/x/sys
cannot find package "golang.org/x/sys/windows"
golang.org/x/sys
$ git clone git@github.com:golang/sys.git $GOPATH/src/golang.org/x/sys
使用:
package main
import (
"fmt"
"github.com/shirou/gopsutil/mem"
)
func main() {
v, _ := mem.VirtualMemory()
fmt.Printf("Total: %v, Available: %v, UsedPercent:%f%%\n", v.Total, v.Available, v.UsedPercent)
fmt.Println(v)
}
gopsutil
cpudiskdockerhostmemnetprocesswinservices
memmem.VirtualMemory()mem.VirtualMemoryStatTotalAvailableUsedUsedPercentmem.VirtualMemoryStatfmt.Stringerfmt.Println(v)v.String()
Total: 8526921728, Available: 3768975360, UsedPercent:55.000000%
{"total":8526921728,"available":3768975360,"used":4757946368,"usedPercent":55,"free":0,"active":0,"inactive":0,"wired":0,"laundry":0,"buffers":0,"cached":0,"writeback":0,"dirty":0,"writebacktmp":0,"shared":0,"slab":0,"sreclaimable":0,"sunreclaim":0,"pagetables":0,"swapcached":0,"commitlimit":0,"committedas":0,"hightotal":0,"highfree":0,"lowtotal":0,"lowfree":0,"swaptotal":0,"swapfree":0,"mapped":0,"vmalloctotal":0,"vmallocused":0,"vmallocchunk":0,"hugepagestotal":0,"hugepagesfree":0,"hugepagesize":0}
单位为字节,我的电脑内存 8GB,当前使用百分比为 55%,可用内存 3768975360B(即 3.51GB)。
CPU
gopsutilcpucpu
Counts(logical bool)falsetruePercent(interval time.Duration, percpu bool)intervalpercpufalsepercputrue[]float64
例如:
func main() {
physicalCnt, _ := cpu.Counts(false)
logicalCnt, _ := cpu.Counts(true)
fmt.Printf("physical count:%d logical count:%d\n", physicalCnt, logicalCnt)
totalPercent, _ := cpu.Percent(3*time.Second, false)
perPercents, _ := cpu.Percent(3*time.Second, true)
fmt.Printf("total percent:%v per percents:%v", totalPercent, perPercents)
}
上面代码获取物理核数和逻辑核数,并获取 3s 内的总 CPU 使用率和每个 CPU 各自的使用率,程序输出(注意每次运行输出可能都不相同):
physical count:4 logical count:8
total percent:[30.729166666666668] per percents:[32.64248704663213 26.94300518134715 44.559585492227974 23.958333333333336 36.787564766839374 20.3125 38.54166666666667 28.125]
详细信息
cpu.Info()[]cpu.InfoStat
func main() {
infos, _ := cpu.Info()
for _, info := range infos {
data, _ := json.MarshalIndent(info, "", " ")
fmt.Print(string(data))
}
}
为了方便查看,我使用 JSON 输出结果:
{
"cpu": 0,
"vendorId": "GenuineIntel",
"family": "198",
"model": "",
"stepping": 0,
"physicalId": "BFEBFBFF000906E9",
"coreId": "",
"cores": 8,
"modelName": "Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz",
"mhz": 3601,
"cacheSize": 0,
"flags": [],
"microcode": ""
}
github.com/StackExchange/wmiInfoStat
时间占用
cpu.Times(percpu bool)percpu=falsepercpu=trueTimeStat
// src/github.com/shirou/gopsutil/cpu/cpu.go
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"`
}
CPUcpu-totalcpu0cpu1UserSystemIdle
例如:
func main() {
infos, _ := cpu.Times(true)
for _, info := range infos {
data, _ := json.MarshalIndent(info, "", " ")
fmt.Print(string(data))
}
}
为了方便查看,我用 JSON 输出结果,下面是其中一个输出:
{
"cpu": "cpu0",
"user": 674.46875,
"system": 1184.984375,
"idle": 7497.1875,
"nice": 0,
"iowait": 0,
"irq": 75.578125,
"softirq": 0,
"steal": 0,
"guest": 0,
"guestNice": 0
}
磁盘
diskdisk
IO 统计
disk.IOCounters()map[string]IOCountersStat
// src/github.com/shirou/gopsutil/disk/disk.go
type IOCountersStat struct {
ReadCount uint64 `json:"readCount"`
MergedReadCount uint64 `json:"mergedReadCount"`
WriteCount uint64 `json:"writeCount"`
MergedWriteCount uint64 `json:"mergedWriteCount"`
ReadBytes uint64 `json:"readBytes"`
WriteBytes uint64 `json:"writeBytes"`
ReadTime uint64 `json:"readTime"`
WriteTime uint64 `json:"writeTime"`
// ...
}
例如:
func main() {
mapStat, _ := disk.IOCounters()
for name, stat := range mapStat {
fmt.Println(name)
data, _ := json.MarshalIndent(stat, "", " ")
fmt.Println(string(data))
}
}
输出包括所有分区,我这里只展示一个:
C:
{
"readCount": 184372,
"mergedReadCount": 0,
"writeCount": 42252,
"mergedWriteCount": 0,
"readBytes": 5205152768,
"writeBytes": 701583872,
"readTime": 333,
"writeTime": 27,
"iopsInProgress": 0,
"ioTime": 0,
"weightedIO": 0,
"name": "C:",
"serialNumber": "",
"label": ""
}
disk.IOCounters()
分区
disk.PartitionStat(all bool)all = falseall = true[]PartitionStatPartitionStat
// src/github.com/shirou/gopsutil/disk/
type PartitionStat struct {
Device string `json:"device"`
Mountpoint string `json:"mountpoint"`
Fstype string `json:"fstype"`
Opts string `json:"opts"`
}
DeviceC:MountpointFstypeOpts
例如:
func main() {
infos, _ := disk.Partitions(false)
for _, info := range infos {
data, _ := json.MarshalIndent(info, "", " ")
fmt.Println(string(data))
}
}
我的 Windows 机器输出(只展示第一个分区):
{
"device": "C:",
"mountpoint": "C:",
"fstype": "NTFS",
"opts": "rw.compress"
}
C:NTFS
使用率
disk.Usage(path string)pathUsageStat
// src/github.com/shirou/gopsutil/disk.go
type UsageStat struct {
Path string `json:"path"`
Fstype string `json:"fstype"`
Total uint64 `json:"total"`
Free uint64 `json:"free"`
Used uint64 `json:"used"`
UsedPercent float64 `json:"usedPercent"`
InodesTotal uint64 `json:"inodesTotal"`
InodesUsed uint64 `json:"inodesUsed"`
InodesFree uint64 `json:"inodesFree"`
InodesUsedPercent float64 `json:"inodesUsedPercent"`
}
PathFstypeTotalFreeUsedUsedPercent
例如:
func main() {
info, _ := disk.Usage("D:/code/golang")
data, _ := json.MarshalIndent(info, "", " ")
fmt.Println(string(data))
}
D:/code/golangD:Path
{
"path": "D:/code/golang",
"fstype": "",
"total": 475779821568,
"free": 385225650176,
"used": 90554171392,
"usedPercent": 19.032789388496106,
"inodesTotal": 0,
"inodesUsed": 0,
"inodesFree": 0,
"inodesUsedPercent": 0
}
主机
host
开机时间
host.BootTime()
func main() {
timestamp, _ := host.BootTime()
t := time.Unix(int64(timestamp), 0)
fmt.Println(t.Local().Format("2006-01-02 15:04:05"))
}
time.Unix()time.Time2006-01-02 15:04:05
2020-04-06 20:25:32
内核版本和平台信息
func main() {
version, _ := host.KernelVersion()
fmt.Println(version)
platform, family, version, _ := host.PlatformInformation()
fmt.Println("platform:", platform)
fmt.Println("family:", family,
fmt.Println("version:", version)
}
在我的 Win10 上运行输出:
10.0.18362 Build 18362
platform: Microsoft Windows 10 Pro
family: Standalone Workstation
version: 10.0.18362 Build 18362
终端用户
host.Users()UserStat
// src/github.com/shirou/gopsutil/host/host.go
type UserStat struct {
User string `json:"user"`
Terminal string `json:"terminal"`
Host string `json:"host"`
Started int `json:"started"`
}
字段一目了然,看示例:
func main() {
users, _ := host.Users()
for _, user := range users {
data, _ := json.MarshalIndent(user, "", " ")
fmt.Println(string(data))
}
}
内存
mem.VirtualMemory()mem.SwapMemory()SwapMemoryStat
// src/github.com/shirou/gopsutil/mem/
type SwapMemoryStat struct {
Total uint64 `json:"total"`
Used uint64 `json:"used"`
Free uint64 `json:"free"`
UsedPercent float64 `json:"usedPercent"`
Sin uint64 `json:"sin"`
Sout uint64 `json:"sout"`
PgIn uint64 `json:"pgin"`
PgOut uint64 `json:"pgout"`
PgFault uint64 `json:"pgfault"`
}
PgIn/PgOut/PgFaultpage faultPgInPgOutPgFault
例如:
func main() {
swapMemory, _ := mem.SwapMemory()
data, _ := json.MarshalIndent(swapMemory, "", " ")
fmt.Println(string(data))
}
进程
process
func main() {
var rootProcess *process.Process
processes, _ := process.Processes()
for _, p := range processes {
if p.Pid == 0 {
rootProcess = p
break
}
}
fmt.Println(rootProcess)
fmt.Println("children:")
children, _ := rootProcess.Children()
for _, p := range children {
fmt.Println(p)
}
}
process.Processes()PidChildren()
Windows 服务
winservicesgolang.org/x/syswinservicesService
// src/github.com/shirou/gopsutil/winservices/winservices.go
type Service struct {
Name string
Config mgr.Config
Status ServiceStatus
// contains filtered or unexported fields
}
mgr.Configgolang.org/x/sys
// src/golang.org/x/sys/windows/svc/mgr/config.go
type Config struct {
ServiceType uint32
StartType uint32
ErrorControl uint32
BinaryPathName string
LoadOrderGroup string
TagId uint32
Dependencies []string
ServiceStartName string
DisplayName string
Password string
Description string
SidType uint32
DelayedAutoStart bool
}
ServiceStatus
// src/github.com/shirou/gopsutil/winservices/winservices.go
type ServiceStatus struct {
State svc.State
Accepts svc.Accepted
Pid uint32
Win32ExitCode uint32
}
StateAcceptsPidWin32ExitCode
下面程序中,我将系统中所有服务的名称、二进制文件路径和状态输出到控制台:
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)
}
}
winservices.ListServices()ServiceNewService()GetServiceDetail()service.GetServiceDetail()ListService()GetServiceDetail()panic
错误和超时
由于大部分函数都涉及到底层的系统调用,所以发生错误和超时是在所难免的。几乎所有的接口都有两个返回值,第二个作为错误。在前面的例子中,我们为了简化代码都忽略了错误,在实际使用中,建议对错误进行处理。
context.Contextcontext.Contextcontext.Background()context.Context
// src/github.com/shirou/gopsutil/cpu_windows.go
func Times(percpu bool) ([]TimesStat, error) {
return TimesWithContext(context.Background(), percpu)
}
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
// ...
}
总结
gopsutilnet/docker
大家如果发现好玩、好用的 Go 语言库,欢迎到 Go 每日一库 GitHub 上提交 issue
参考
我
我的博客:
欢迎关注我的微信公众号【GoUpUp】,共同学习,一起进步~