Golang : Get hardware information such as disk, memory and CPU usage
For this tutorial, we will learn how to extract hardware level information with Golang. Accessing hardware level information such as CPU usage percentage and disk partition information can be useful in a situation such as when you need to query the hardware ID or serial numbers without physically opening up the casing or you need to use the hardware information for tracking and troubleshooting purposes.
For my own personal use, I need it to query couples of raspberry-Pi computers, Linux desktops and a Mac.
In this code example below, we will use the cross-platform github.com/shirou/gopsutil
package to find out the CPU utilization level and other system process statuses via Golang. The queried information will be exposed via web interface.
Before you start, please
$>go get github.com/shirou/gopsutil/...
Here you go!
package main
import (
"fmt"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/disk"
"github.com/shirou/gopsutil/host"
"github.com/shirou/gopsutil/mem"
"github.com/shirou/gopsutil/net"
"net/http"
"runtime"
"strconv"
)
func dealwithErr(err error) {
if err != nil {
fmt.Println(err)
//os.Exit(-1)
}
}
func GetHardwareData(w http.ResponseWriter, r *http.Request) {
runtimeOS := runtime.GOOS
// memory
vmStat, err := mem.VirtualMemory()
dealwithErr(err)
// disk - start from "/" mount point for Linux
// might have to change for Windows!!
// don't have a Window to test this out, if detect OS == windows
// then use "\" instead of "/"
diskStat, err := disk.Usage("/")
dealwithErr(err)
// cpu - get CPU number of cores and speed
cpuStat, err := cpu.Info()
dealwithErr(err)
percentage, err := cpu.Percent(0, true)
dealwithErr(err)
// host or machine kernel, uptime, platform Info
hostStat, err := host.Info()
dealwithErr(err)
// get interfaces MAC/hardware address
interfStat, err := net.Interfaces()
dealwithErr(err)
html := "<html>OS : " + runtimeOS + "<br>"
html = html + "Total memory: " + strconv.FormatUint(vmStat.Total, 10) + " bytes <br>"
html = html + "Free memory: " + strconv.FormatUint(vmStat.Free, 10) + " bytes<br>"
html = html + "Percentage used memory: " + strconv.FormatFloat(vmStat.UsedPercent, 'f', 2, 64) + "%<br>"
// get disk serial number.... strange... not available from disk package at compile time
// undefined: disk.GetDiskSerialNumber
//serial := disk.GetDiskSerialNumber("/dev/sda")
//html = html + "Disk serial number: " + serial + "<br>"
html = html + "Total disk space: " + strconv.FormatUint(diskStat.Total, 10) + " bytes <br>"
html = html + "Used disk space: " + strconv.FormatUint(diskStat.Used, 10) + " bytes<br>"
html = html + "Free disk space: " + strconv.FormatUint(diskStat.Free, 10) + " bytes<br>"
html = html + "Percentage disk space usage: " + strconv.FormatFloat(diskStat.UsedPercent, 'f', 2, 64) + "%<br>"
// since my machine has one CPU, I'll use the 0 index
// if your machine has more than 1 CPU, use the correct index
// to get the proper data
html = html + "CPU index number: " + strconv.FormatInt(int64(cpuStat[0].CPU), 10) + "<br>"
html = html + "VendorID: " + cpuStat[0].VendorID + "<br>"
html = html + "Family: " + cpuStat[0].Family + "<br>"
html = html + "Number of cores: " + strconv.FormatInt(int64(cpuStat[0].Cores), 10) + "<br>"
html = html + "Model Name: " + cpuStat[0].ModelName + "<br>"
html = html + "Speed: " + strconv.FormatFloat(cpuStat[0].Mhz, 'f', 2, 64) + " MHz <br>"
for idx, cpupercent := range percentage {
html = html + "Current CPU utilization: [" + strconv.Itoa(idx) + "] " + strconv.FormatFloat(cpupercent, 'f', 2, 64) + "%<br>"
}
html = html + "Hostname: " + hostStat.Hostname + "<br>"
html = html + "Uptime: " + strconv.FormatUint(hostStat.Uptime, 10) + "<br>"
html = html + "Number of processes running: " + strconv.FormatUint(hostStat.Procs, 10) + "<br>"
// another way to get the operating system name
// both darwin for Mac OSX, For Linux, can be ubuntu as platform
// and linux for OS
html = html + "OS: " + hostStat.OS + "<br>"
html = html + "Platform: " + hostStat.Platform + "<br>"
// the unique hardware id for this machine
html = html + "Host ID(uuid): " + hostStat.HostID + "<br>"
for _, interf := range interfStat {
html = html + "------------------------------------------------------<br>"
html = html + "Interface Name: " + interf.Name + "<br>"
if interf.HardwareAddr != "" {
html = html + "Hardware(MAC) Address: " + interf.HardwareAddr + "<br>"
}
for _, flag := range interf.Flags {
html = html + "Interface behavior or flags: " + flag + "<br>"
}
for _, addr := range interf.Addrs {
html = html + "IPv6 or IPv4 addresses: " + addr.String() + "<br>"
}
}
html = html + "</html>"
w.Write([]byte(html))
}
func SayName(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, I'm a machine and my name is [whatever]"))
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", SayName)
mux.HandleFunc("/gethwdata", GetHardwareData)
http.ListenAndServe(":8080", mux)
}
Sample output(point browser to http://localhost:8080/gethwdata) :
OS : darwin
Total memory: 4294967296 bytes
Free memory: 24223744 bytes
Percentage used memory: 76.96%
Total disk space: 119174365184 bytes
Used disk space: 109002297344 bytes
Free disk space: 9909923840 bytes
Percentage disk space usage: 91.46%
CPU index number: 0
VendorID: GenuineIntel
Family: 6
Number of cores: 2
Model Name: Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz
Speed: 3292.00 MHz
Current CPU utilization: [0] 55.49%
Current CPU utilization: 1 27.71%
Current CPU utilization: 2 55.33%
Current CPU utilization: 3 26.79%
Hostname: Sweets-Mac-Pro.local
Uptime: 9045
Number of processes running: 211
OS: darwin
Platform: darwin
Host ID(uuid): FE3619E6-270B-34A6-BBD7-BED74EC32693
------------------------------------------------------
Interface Name: lo0
Interface behavior or flags: up
Interface behavior or flags: loopback
Interface behavior or flags: multicast
IPv6 or IPv4 addresses: {"addr":"::1/128"}
IPv6 or IPv4 addresses: {"addr":"127.0.0.1/8"}
IPv6 or IPv4 addresses: {"addr":"fe80::1/64"}
------------------------------------------------------
Interface Name: gif0
Interface behavior or flags: pointtopoint
Interface behavior or flags: multicast
------------------------------------------------------
Interface Name: stf0
------------------------------------------------------
Interface Name: en3
Hardware(MAC) Address: 18:a6:f7:16:e8:0b
Interface behavior or flags: up
Interface behavior or flags: broadcast
Interface behavior or flags: multicast
IPv6 or IPv4 addresses: {"addr":"fe80::1aa6:f7ff:fe16:e80b/64"}
IPv6 or IPv4 addresses: {"addr":"192.168.1.65/24"}
Happy coding!
References:
https://www.socketloop.com/tutorials/golang-http-server-example
https://www.socketloop.com/tutorials/golang-detect-os-operating-system
http://stackoverflow.com/questions/11356330/getting-cpu-usage-with-golang?rq=1
See also : Golang : Get local IP and MAC address
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+7.2k Golang : Set horizontal, vertical scroll bars policies and disable interaction on Qt image
+8.2k Golang : Another camera capture GUI application with GTK and OpenCV
+13.5k Golang : How to check if a file is hidden?
+17.3k Golang : Upload/Receive file progress indicator
+4.7k Golang : Calculate a pip value and distance to target profit example
+7.2k Golang : How to handle file size larger than available memory panic issue
+19.4k Golang : Convert(cast) bytes.Buffer or bytes.NewBuffer type to io.Reader
+11.9k Golang : Flush and close file created by os.Create and bufio.NewWriter example
+18.1k Golang : Logging with logrus
+34.1k Golang : How to stream file to client(browser) or write to http.ResponseWriter?