From 8abe57ffb6ad508a154fb5341dc51fe9695041e3 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 22 Jan 2019 08:50:18 +0100 Subject: [PATCH] admin: new API route to display local monitoring infos --- admin/api/monitor.go | 98 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 admin/api/monitor.go diff --git a/admin/api/monitor.go b/admin/api/monitor.go new file mode 100644 index 00000000..b8af548f --- /dev/null +++ b/admin/api/monitor.go @@ -0,0 +1,98 @@ +package api + +import ( + "bufio" + "io/ioutil" + "os" + "strconv" + "strings" + + "github.com/julienschmidt/httprouter" +) + +func init() { + router.GET("/api/monitor", apiHandler( + func(httprouter.Params, []byte) (interface{}, error) { + return map[string]interface{}{ + "localhost": genLocalConstants(), + }, nil + })) +} + +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 +}