// +build linux darwin unix package staros import ( "bytes" "fmt" "io/ioutil" "os/user" "strconv" "strings" "syscall" "time" ) var clockTicks = 100 // default value // StartTime 开机时间 func StartTime() time.Time { tmp, _ := readAsString("/proc/stat") data := splitBy(ReplaceByte9(tmp), " ") btime, _ := strconv.ParseInt(strings.TrimSpace(data["btime"]), 10, 64) return time.Unix(btime, 0) } // IsRoot 当前是否是管理员用户 func IsRoot() bool { uid, _ := user.Current() if uid.Uid == "0" { return true } return false } func Whoami() (uid, gid int, uname, gname, home string, err error) { var me *user.User var gup *user.Group me, err = user.Current() if err != nil { return } uid, _ = strconv.Atoi(me.Uid) gid, _ = strconv.Atoi(me.Uid) home = me.HomeDir uname = me.Username gup, err = user.LookupGroupId(me.Gid) if err != nil { return } gname = gup.Name return } func getCPUSample() (idle, total uint64) { contents, err := ioutil.ReadFile("/proc/stat") if err != nil { return } lines := strings.Split(string(contents), "\n") for _, line := range lines { fields := strings.Fields(line) if fields[0] == "cpu" { numFields := len(fields) for i := 1; i < numFields; i++ { val, err := strconv.ParseUint(fields[i], 10, 64) if err != nil { fmt.Println("Error: ", i, fields[i], err) } total += val // tally up all the numbers to get total ticks if i == 4 || i == 5 { // idle is the 5th field in the cpu line idle += val } } return } } return } func splitProcStat(content []byte) []string { nameStart := bytes.IndexByte(content, '(') nameEnd := bytes.LastIndexByte(content, ')') restFields := strings.Fields(string(content[nameEnd+2:])) // +2 skip ') ' name := content[nameStart+1 : nameEnd] pid := strings.TrimSpace(string(content[:nameStart])) fields := make([]string, 3, len(restFields)+3) fields[1] = string(pid) fields[2] = string(name) fields = append(fields, restFields...) return fields } func getCPUSampleByPid(pid int) float64 { contents, err := ioutil.ReadFile("/proc/" + strconv.Itoa(pid) + "/stat") if err != nil { return 0 } fields := splitProcStat(contents) utime, err := strconv.ParseFloat(fields[14], 64) if err != nil { return 0 } stime, err := strconv.ParseFloat(fields[15], 64) if err != nil { return 0 } // There is no such thing as iotime in stat file. As an approximation, we // will use delayacct_blkio_ticks (aggregated block I/O delays, as per Linux // docs). Note: I am assuming at least Linux 2.6.18 var iotime float64 if len(fields) > 42 { iotime, err = strconv.ParseFloat(fields[42], 64) if err != nil { iotime = 0 // Ancient linux version, most likely } } else { iotime = 0 // e.g. SmartOS containers } return utime/float64(clockTicks) + stime/float64(clockTicks) + iotime/float64(clockTicks) } func CpuUsageByPid(pid int, sleep time.Duration) float64 { total1 := getCPUSampleByPid(pid) time.Sleep(sleep) total2 := getCPUSampleByPid(pid) return (total2 - total1) / sleep.Seconds() * 100 } // CpuUsage 获取CPU使用量 func CpuUsage(sleep time.Duration) float64 { idle0, total0 := getCPUSample() time.Sleep(sleep) idle1, total1 := getCPUSample() idleTicks := float64(idle1 - idle0) totalTicks := float64(total1 - total0) cpuUsage := 100 * (totalTicks - idleTicks) / totalTicks return cpuUsage //fmt.Printf("CPU usage is %f%% [busy: %f, total: %f]\n", cpuUsage, totalTicks-idleTicks, totalTicks) } func DiskUsage(path string) (disk DiskStatus) { fs := syscall.Statfs_t{} err := syscall.Statfs(path, &fs) if err != nil { return } disk.All = fs.Blocks * uint64(fs.Bsize) disk.Free = fs.Bfree * uint64(fs.Bsize) disk.Available = fs.Bavail * uint64(fs.Bsize) disk.Used = disk.All - disk.Free return }