// MemoryUsage - XXX func MemoryUsage() MemoryStruct { mem, _ := psmem.VirtualMemory() swap, _ := psmem.SwapMemory() TotalMB, _ := util.ConvertBytesTo(mem.Total, "mb", 0) FreeMB, _ := util.ConvertBytesTo(mem.Free, "mb", 0) UsedMB, _ := util.ConvertBytesTo(mem.Used, "mb", 0) UsedPercent, _ := util.FloatDecimalPoint(mem.UsedPercent, 0) SwapUsedMB, _ := util.ConvertBytesTo(swap.Used, "mb", 0) SwapTotalMB, _ := util.ConvertBytesTo(swap.Total, "mb", 0) SwapFreeMB, _ := util.ConvertBytesTo(swap.Free, "mb", 0) SwapUsedPercent, _ := util.FloatDecimalPoint(swap.UsedPercent, 0) m := MemoryStruct{ UsedMB: UsedMB, TotalMB: TotalMB, FreeMB: FreeMB, UsedPercent: UsedPercent, SwapUsedMB: SwapUsedMB, SwapTotalMB: SwapTotalMB, SwapFreeMB: SwapFreeMB, SwapUsedPercent: SwapUsedPercent, } return m }
// CPUUsage - return a map with CPU usage stats func CPUUsage() CPUUsageStruct { cpuTimes1, err := cpu.Times(false) if err != nil { log.Errorf("error getting CPU info: %s", err) } c := CPUUsageStruct{} for i, lastCts := range cpuTimes1 { lastTotal := totalCPUTime(lastCts) time.Sleep(1 * time.Second) cpuTimes2, _ := cpu.Times(false) cts := cpuTimes2[i] total := totalCPUTime(cts) totalDelta := total - lastTotal system := 100 * (cts.System - lastCts.System) / totalDelta nice := 100 * (cts.Nice - lastCts.Nice) / totalDelta user := 100 * (cts.User - lastCts.User) / totalDelta idle := 100 * (cts.Idle - lastCts.Idle) / totalDelta iowait := 100 * (cts.Iowait - lastCts.Iowait) / totalDelta steal := 100 * (cts.Steal - lastCts.Steal) / totalDelta systemPercent, _ := util.FloatDecimalPoint(system, 2) nicePercent, _ := util.FloatDecimalPoint(nice, 2) userPercent, _ := util.FloatDecimalPoint(user, 2) idlePercent, _ := util.FloatDecimalPoint(idle, 2) iowaitPercent, _ := util.FloatDecimalPoint(iowait, 2) stealPercent, _ := util.FloatDecimalPoint(steal, 2) c = CPUUsageStruct{ User: userPercent, Idle: idlePercent, Nice: nicePercent, Steal: stealPercent, System: systemPercent, IOWait: iowaitPercent, } } return c }
// Processes - get data from sysstat, format and return the result func Processes() (ProcessesList, error) { c1, _ := exec.Command("pidstat", "-ruhtd").Output() var ps ProcessesList v, _ := mem.VirtualMemory() memoryTotalMB, _ := util.ConvertBytesTo(float64(v.Total), "mb", 0) // Find header and ignore headerRegex, _ := regexp.Compile("d+") pidstatOutput := string(c1) pidstatLines := strings.Split(pidstatOutput, "\n") // Helper // Time(0) UID(1) TGID(2) TID(3) // %usr{4} %system{5} %guest{6} %CPU{7} CPU{8} // minflt/s{9} majflt/s{10} VSZ{11} RSS{12} // %MEM{13} kB_rd/s{14} kB_wr/s{15} kB_ccwr/s{16} Command{17} var headerData []string for _, processLine := range pidstatLines { // Get the header if strings.Contains(processLine, "%CPU") || strings.Contains(processLine, "%Command") { headerData = strings.Fields(processLine) if len(headerData) > 0 { // remove the first column, if it has the # sign if headerData[0] == "#" { headerData = append(headerData[:0], headerData[0+1:]...) } } break } } for _, processLine := range pidstatLines { if len(headerRegex.FindString(processLine)) == 0 { processData := strings.Fields(processLine) if len(processData) == len(headerData) { masterthreadIDIndex := SliceFindStringIndex(headerData, "TID") if masterthreadIDIndex != -1 { masterthreadID := processData[masterthreadIDIndex] masterthreadIDtoINT, _ := strconv.Atoi(masterthreadID) // It is a master thread, proceed with the actual data if masterthreadIDtoINT == 0 { CPUIndex := SliceFindStringIndex(headerData, "%CPU") MEMIndex := SliceFindStringIndex(headerData, "%MEM") if CPUIndex != -1 && MEMIndex != -1 { cpuPercent := processData[CPUIndex] cpuPercenttoINT, _ := strconv.ParseFloat(cpuPercent, 64) memPercent := processData[MEMIndex] memPercenttoINT, _ := strconv.ParseFloat(memPercent, 64) var processMemoryMB, _ = util.FloatDecimalPoint(memoryTotalMB/100*memPercenttoINT, 2) ReadKBIndex := SliceFindStringIndex(headerData, "kB_rd/s") WriteKBIndex := SliceFindStringIndex(headerData, "kB_wr/s") var ReadKBytes = 0.0 var WriteKBytes = 0.0 if ReadKBIndex != -1 && WriteKBIndex != -1 { ReadPerSecond := processData[ReadKBIndex] ReadKBytes, _ = strconv.ParseFloat(ReadPerSecond, 64) WritePerSecond := processData[WriteKBIndex] WriteKBytes, _ = strconv.ParseFloat(WritePerSecond, 64) if ReadKBytes == -1.0 && WriteKBytes == -1.0 { ReadKBytes = 0.0 WriteKBytes = 0.0 } } processNameIndex := SliceFindStringIndex(headerData, "command") // Everything is find up to this point, append if processNameIndex != -1 { processName := processData[processNameIndex] formattedprocessMemoryMB, _ := util.FloatToString(processMemoryMB) c := ProcessStruct{ CPU: cpuPercenttoINT, Memory: formattedprocessMemoryMB, Name: processName, KBRead: ReadKBytes, KBWrite: WriteKBytes, } ps = append(ps, c) } } else { log.Error("Can't find mem/cpu data") } } } } //fmt.Print(headerData) } } return ps, nil }