一直以来就想做一个可以显示服务器信息的集中式监控页面。经过两三天艰苦努力终于放弃(前端实现地图上展示信息太难了。

虽然对应的前端做不出来,但是对应的信息采集后端已经写好并且可以使用,为了不浪费我的成果,在这贴出来。你们谁要是写个对应的前端的话,请务必通知我。

package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/disk"
	"github.com/shirou/gopsutil/host"
	"github.com/shirou/gopsutil/load"
	"github.com/shirou/gopsutil/mem"
	"github.com/shirou/gopsutil/net"
	"log"
	"net/http"
	"time"
)

type StatusServer struct {
	Percent  StatusPercent
	CPU      []CPUInfo
	Mem      MemInfo
	Swap     SwapInfo
	Load     *load.AvgStat
	Network  map[string]InterfaceInfo
	BootTime uint64
	Uptime   uint64
}
type StatusPercent struct {
	CPU  float64
	Disk float64
	Mem  float64
	Swap float64
}
type CPUInfo struct {
	ModelName string
	Cores     int32
}
type MemInfo struct {
	Total     uint64
	Used      uint64
	Available uint64
}
type SwapInfo struct {
	Total     uint64
	Used      uint64
	Available uint64
}
type InterfaceInfo struct {
	Addrs    []string
	ByteSent uint64
	ByteRecv uint64
}

func main() {
	port := flag.String("port", ":58000", "HTTP listen port")
	flag.Parse()
	http.HandleFunc("/", getInfo)
	err := http.ListenAndServe(*port, nil)
	if err != nil {
		log.Fatalln("ListenAndServe: ", err)
	}
}

func getInfo(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Content-Type")
	w.Header().Set("Content-Type", "application/json")
	fmt.Fprintf(w, infoMiniJSON())
}

func infoMiniJSON() string {
	v, _ := mem.VirtualMemory()
	s, _ := mem.SwapMemory()
	c, _ := cpu.Info()
	cc, _ := cpu.Percent(time.Second, false)
	d, _ := disk.Usage("/")
	n, _ := host.Info()
	nv, _ := net.IOCounters(true)
	l, _ := load.Avg()
	i, _ := net.Interfaces()

	ss := new(StatusServer)
	ss.Load = l
	ss.Uptime = n.Uptime
	ss.BootTime = n.BootTime
	ss.Percent.Mem = v.UsedPercent
	ss.Percent.CPU = cc[0]
	ss.Percent.Swap = s.UsedPercent
	ss.Percent.Disk = d.UsedPercent
	ss.CPU = make([]CPUInfo, len(c))
	for i, ci := range c {
		ss.CPU[i].ModelName = ci.ModelName
		ss.CPU[i].Cores = ci.Cores
	}
	ss.Mem.Total = v.Total
	ss.Mem.Available = v.Available
	ss.Mem.Used = v.Used
	ss.Swap.Total = s.Total
	ss.Swap.Available = s.Free
	ss.Swap.Used = s.Used
	ss.Network = make(map[string]InterfaceInfo)
	for _, v := range nv {
		var ii InterfaceInfo
		ii.ByteSent = v.BytesSent
		ii.ByteRecv = v.BytesRecv
		ss.Network[v.Name] = ii
	}
	for _, v := range i {
		if ii, ok := ss.Network[v.Name]; ok {
			ii.Addrs = make([]string, len(v.Addrs))
			for i, vv := range v.Addrs {
				ii.Addrs[i] = vv.Addr
			}
			ss.Network[v.Name] = ii
		}
	}
	b, err := json.Marshal(ss)
	if err != nil {
		return ""
	} else {
		return string(b)
	}
}

运行起来后,用浏览器访问被采集机器的58000端口就可以看到机器的信息了。

{
	"Percent": {
		"CPU": 0,
		"Disk": 11.68627166041493,
		"Mem": 21.34952360680132,
		"Swap": 1.498353300558446
	},
	"CPU": [{
		"ModelName": "Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz",
		"Cores": 1
	}],
	"Mem": {
		"Total": 2097467392,
		"Used": 447799296,
		"Available": 1649668096
	},
	"Swap": {
		"Total": 2145382400,
		"Used": 32145408,
		"Available": 2113236992
	},
	"Load": {
		"load1": 0,
		"load5": 0,
		"load15": 0
	},
	"Network": {
		"ens32": {
			"Addrs": ["192.168.1.68/24", "fe80::20c:29ff:fed6:1bea/64"],
			"ByteSent": 10643267063,
			"ByteRecv": 3625202751
		},
		"lo": {
			"Addrs": ["127.0.0.1/8", "::1/128"],
			"ByteSent": 8310060,
			"ByteRecv": 8310060
		}
	},
	"BootTime": 1512095971,
	"Uptime": 5290007
}

gopsutil可以获取更多信息,具体可以去看gopsutil文档