還在自己寫 Go 系統監控函數嗎

如果有個 Go 開發需求:獲取主機的硬盤、CPU、內存、進程等使用情況,你會怎麼做?比較樸素的想法是通過 os/exec 去執行某些例如 ps、cd、top 命令,之後解析它們的執行結果。當然,基於 Linux 的一切皆文件思想,更直接地做法是去讀取相關文件內容,例如 /proc 目錄下的文件。

上面的方式能夠完成需求,但是我們大不必重複造輪子,因爲已經有相當完善的三方庫爲我們實現了這些採集需求,它就是 gopsutil。

gopsutil 簡介

psutil (process and system utilities,)是一個跨平臺庫,用於在 Python 中獲取進程和系統利用率(CPU、內存、磁盤、網絡、傳感器)的信息,而 gopsutil 是它的 Go 語言版本。

gopsutil 爲我們屏蔽了各系統差異,具有很好的移植性。

已支持列表

部分支持列表

另外,該項目通過將 C 結構移植到 Go 結構,它的實現中沒有 cgo 的代碼,這樣就更有利於交叉編譯了。

使用

gopsutil 現有 v3 和 v2 版本,且沒有向後兼容性保證,因此有兩種使用方式

import (
    // "github.com/shirou/gopsutil/v3/mem" // to use v3
    "github.com/shirou/gopsutil/mem"  
)

例如我們想查看系統內存使用信息,可以通過以下方式獲取

package main

import (
    "fmt"

    "github.com/shirou/gopsutil/v3/mem"
    // "github.com/shirou/gopsutil/mem"  // to use v2
)

func main() {
    v, _ := mem.VirtualMemory()

    // almost every return value is a struct
    fmt.Printf("Total: %v, Free:%v, UsedPercent:%f%%\n", v.Total, v.Free, v.UsedPercent)

    // convert to JSON. String() is also implemented
    fmt.Println(v)
}

其結果爲

Total: 8589934592, Free:138248192, UsedPercent:76.416254%
{"total":8589934592,"available":2025828352,"used":6564106240,"usedPercent":76.4162540435791,"free":138248192,"active":1949327360,"inactive":1887580160,"wired":2214510592,"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}

gopsutil 包有一點比較友好的是,絕大多數的採集函數返回的都是一個結構體對象,它們都實現了  fmt.Stringer 接口,因此在打印時它們將會以 json 格式進行輸出。

例如,上例中 mem.VirtualMemory 返回的是 VirtualMemoryStat 結構體,它在 String() 方法中調用了 json.Marshal() 函數。

type VirtualMemoryStat struct {
 Total uint64 `json:"total"`
 Available uint64 `json:"available"`
 Used uint64 `json:"used"`
 UsedPercent float64 `json:"usedPercent"`
 Free uint64 `json:"free"`
 Active   uint64 `json:"active"`
 Inactive uint64 `json:"inactive"`
 Wired    uint64 `json:"wired"`

func (m VirtualMemoryStat) String() string {
 s, _ := json.Marshal(m)
 return string(s)
}

gopsutil 通過不同採集單元劃分爲不同的子包,在使用中通過引入不同的子包,即可調用相關的方法。

import (
 "github.com/shirou/gopsutil/v3/mem"
 "github.com/shirou/gopsutil/v3/cpu"
 "github.com/shirou/gopsutil/v3/disk"
 "github.com/shirou/gopsutil/v3/docker"
 "github.com/shirou/gopsutil/v3/host"
 "github.com/shirou/gopsutil/v3/internal"
 "github.com/shirou/gopsutil/v3/load"
 "github.com/shirou/gopsutil/v3/mem"
 "github.com/shirou/gopsutil/v3/net"
 "github.com/shirou/gopsutil/v3/process"
 "github.com/shirou/gopsutil/v3/winservices"
)

例如我們想要獲取主機信息,就需要引入 github.com/shirou/gopsutil/v3/host 子包

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

func main() {
 hostInfo, _ := host.Info()
 fmt.Println(hostInfo)
}

輸出

{"hostname":"MacBook-Pro.local","uptime":1619284,"bootTime":1644332729,"procs":301,"os":"darwin","platform":"darwin","platformFamily":"Standalone Workstation","platformVersion":"10.15.5","kernelVersion":"19.5.0","kernelArch":"x86_64","virtualizationSystem":"","virtualizationRole":"","hostId":"7a1a74f2-30fc-4cc1-b439-6b7aef22e45d"}

總結

gopsutil 庫有非常全面的覆蓋單元,包括主機、磁盤、內存、CPU、網絡、進程、docker 等模塊,它能很好地幫助我們獲取系統信息。並且 gopsutil 處理了跨平臺兼容性問題,對外接口基本保持一致,使用起來比較友好。

在信息採集、系統監控、資源限制、進程管理等場景下,該庫將助你一臂之力。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/jGWbisa0Q56EQo_yBKGceQ