package gupta import ( "encoding/json" "fmt" "strconv" "strings" "time" ) const version = "0.0.1" func Hello() string { return fmt.Sprintf("Welcome to gupta version %s", version) } func Run(load, cpu, memory bool, partition, networkInterface string) (cpuLoad, cpuUsage, memoryUsage float64) { cpuLoad = 0.2 cpuUsage = 0.2 memoryUsage = 70.0 return cpuLoad, cpuUsage, memoryUsage } type GuptaReport struct { LoadAvarage float64 CPUUsage *CPUStat `json:"cpu usage, omitempty"` MemoryUsage *Memory `json:"memory,omitempty"` } // usually you'd want a g GuptaReport reciever here ... // but than you could now check for the object properties ... func (g *GuptaReport) MarshalJSON() ([]byte, error) { t := time.Now() report := []byte(fmt.Sprintf("{\"timestamp\": \"%d\", \"metrics\": [", t.Unix())) if g.CPUUsage != nil { usage, _ := json.Marshal(g.CPUUsage) report = append(report, usage...) } if g.MemoryUsage != nil { if g.CPUUsage != nil { report = append(report, []byte(",")...) } usage, _ := json.Marshal(g.MemoryUsage) report = append(report, usage...) } report = append(report, []byte("]}")...) return report, nil } // collect all CPU stat from /proc/cpustat type CPUStat struct { totalTime float64 idleTime float64 totalTimeNew float64 idleTimeNew float64 } func (c *CPUStat) ReadInfoNew(statline string) { rawInfo := strings.Fields(statline) idleNew, _ := strconv.ParseFloat(rawInfo[4], 10) iowaitNew, _ := strconv.ParseFloat(rawInfo[5], 10) c.idleTimeNew = idleNew + iowaitNew for _, s := range rawInfo { u, _ := strconv.ParseFloat(s, 10) c.totalTimeNew += u } } func (c *CPUStat) ReadInfo(statline string) { rawInfo := strings.Fields(statline) for _, s := range rawInfo[1:] { u, _ := strconv.ParseFloat(s, 10) c.totalTime += u } idle, _ := strconv.ParseFloat(rawInfo[4], 10) iowait, _ := strconv.ParseFloat(rawInfo[5], 10) c.idleTime = idle + iowait } func (c *CPUStat) CPUUsage() float64 { deltaIdleTime := c.idleTimeNew - c.idleTime deltaTotalTime := c.totalTimeNew - c.totalTime cpuUsage := (1.0 - float64(deltaIdleTime)/float64(deltaTotalTime)) * 100 return cpuUsage } func NewCPUStat(procstatline, procstatlineNew string) CPUStat { cpustat := CPUStat{} cpustat.ReadInfo(procstatline) cpustat.ReadInfoNew(procstatlineNew) return cpustat } func (c CPUStat) MarshalJSON() ([]byte, error) { jsonData := []byte( fmt.Sprintf("{\"cpu usage\": \"%.2f%%\"}", c.CPUUsage())) return jsonData, nil }