package api import ( "bufio" "io/ioutil" "net/http" "os" "strconv" "strings" "github.com/gin-gonic/gin" ) func declareMonitorRoutes(router *gin.RouterGroup) { router.GET("/monitor", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "localhost": genLocalConstants(), }) }) } func readLoadAvg(fd *os.File) (ret map[string]float64) { if s, err := ioutil.ReadAll(fd); err == nil { f := strings.Fields(strings.TrimSpace(string(s))) if len(f) >= 3 { ret = map[string]float64{} ret["1m"], _ = strconv.ParseFloat(f[0], 64) ret["5m"], _ = strconv.ParseFloat(f[1], 64) ret["15m"], _ = strconv.ParseFloat(f[2], 64) } } return } func readMeminfo(fd *os.File) (ret map[string]uint64) { ret = map[string]uint64{} scanner := bufio.NewScanner(fd) for scanner.Scan() { f := strings.Fields(strings.TrimSpace(scanner.Text())) if len(f) >= 2 { if v, err := strconv.ParseUint(f[1], 10, 64); err == nil { ret[strings.ToLower(strings.TrimSuffix(f[0], ":"))] = v * 1024 } } } return } func readCPUStats(fd *os.File) (ret map[string]map[string]uint64) { ret = map[string]map[string]uint64{} scanner := bufio.NewScanner(fd) for scanner.Scan() { f := strings.Fields(strings.TrimSpace(scanner.Text())) if len(f[0]) >= 4 && f[0][0:3] == "cpu" && len(f) >= 8 { ret[f[0]] = map[string]uint64{} var total uint64 = 0 for i, k := range []string{"user", "nice", "system", "idle", "iowait", "irq", "softirq"} { if v, err := strconv.ParseUint(f[i+1], 10, 64); err == nil { ret[f[0]][k] = v total += v } } ret[f[0]]["total"] = total } } return } func genLocalConstants() interface{} { ret := map[string]interface{}{} fi, err := os.Open("/proc/loadavg") if err != nil { return err } defer fi.Close() ret["loadavg"] = readLoadAvg(fi) fi, err = os.Open("/proc/meminfo") if err != nil { return err } defer fi.Close() ret["meminfo"] = readMeminfo(fi) fi, err = os.Open("/proc/stat") if err != nil { return err } defer fi.Close() ret["cpustat"] = readCPUStats(fi) return ret }