//go:build linux // +build linux package state import ( "encoding/binary" "fmt" "os" "runtime" "syscall" "time" "ems.agt/lib/log" "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/disk" "github.com/shirou/gopsutil/mem" "github.com/shirou/gopsutil/process" ) type SysInfo struct { SysCpuPercent uint16 // x% MyCpuPercent uint16 // x%, CPU percent of current proccess SysTotalRam uint32 // KB MyUsedRam uint32 // RAM usage of current proccess, KB SysRamUsedPercent uint16 // x% PartitionNum byte PartitionInfo []PartitionInfo // usage of each partition } const MAX_PARTITION_NUM byte = 32 func GetSysStat() ([]byte, int) { // Get sys info var sysInfo SysInfo err := GetSysInfo(&sysInfo) if err != nil { return nil, 0 } //log.Tracef("current sys info: %v", sysInfo) // build ems buffer var data []byte = make([]byte, 1024) var len int var i byte binary.BigEndian.PutUint16(data[0:], sysInfo.MyCpuPercent) //x% * 100 binary.BigEndian.PutUint16(data[2:], sysInfo.SysCpuPercent) //x% * 100 binary.BigEndian.PutUint32(data[4:], sysInfo.SysTotalRam) // KB binary.BigEndian.PutUint32(data[8:], sysInfo.MyUsedRam) // KB binary.BigEndian.PutUint16(data[12:], sysInfo.SysRamUsedPercent) //x% * 100 data[14] = sysInfo.PartitionNum for i = 0; i < sysInfo.PartitionNum; i++ { binary.BigEndian.PutUint32(data[15+8*(i):], sysInfo.PartitionInfo[i].Total) // MB binary.BigEndian.PutUint32(data[15+8*(i)+4:], sysInfo.PartitionInfo[i].Used) // MB } len = int(15 + 8*sysInfo.PartitionNum) //log.Tracef("current sys stat buf: %v, len: %d", data, len) return data, len } var pProc *process.Process = nil func GetSYsCpuPercent() float64 { totalPercent, err := cpu.Percent(0, false) //(2*time.Second, false) if err != nil { return 0.0 } else { return totalPercent[0] } } func GetSysInfo(sysInfo *SysInfo) error { // sys cpu percent totalPercent, err := cpu.Percent(0, false) //(2*time.Second, false) if err != nil { sysInfo.SysCpuPercent = 0 } else { sysInfo.SysCpuPercent = uint16(totalPercent[0] * 100) } if pProc == nil { checkPid := os.Getpid() pProc, err = process.NewProcess(int32(checkPid)) if err != nil { log.Tracef("get process info error %v", err) return err } } // self cpu percent percent, err := pProc.Percent(0) //(2*time.Second) if err != nil { log.Tracef("get process cpu percent error %v", err) sysInfo.MyCpuPercent = 0 } else { sysInfo.MyCpuPercent = uint16(percent * 100) } // self RAM(KB) myRam, err := pProc.MemoryInfo() if err != nil { log.Tracef("get self memory info error %v", err) sysInfo.MyUsedRam = 0 } else { sysInfo.MyUsedRam = uint32(myRam.RSS / 1024) } // system RAM(KB) sysRam, err := mem.VirtualMemory() if err != nil { log.Tracef("gett sys memory info error %v", err) sysInfo.SysTotalRam = 0 sysInfo.SysRamUsedPercent = 0 } else { sysInfo.SysTotalRam = uint32(sysRam.Total / 1024) sysInfo.SysRamUsedPercent = uint16(sysRam.UsedPercent * 100) } // partition usage GetPartitions(sysInfo) return nil } func getProcess() process.Process { checkPid := os.Getpid() ret, _ := process.NewProcess(int32(checkPid)) return *ret } func GetSystemCpuInfo() { physicalCnt, _ := cpu.Counts(false) logicalCnt, _ := cpu.Counts(true) log.Tracef("physical count:%d logical count:%d", physicalCnt, logicalCnt) totalPercent, _ := cpu.Percent(3*time.Second, false) // per cpu is false perPercents, _ := cpu.Percent(3*time.Second, true) // per cpu is true log.Tracef("total percent:%v per percents:%v", totalPercent, perPercents) } func GetProcessCpuPercent() { p := getProcess() percent, err := p.Percent(0) if err != nil { log.Tracef("error %v", err) } numcpu := runtime.NumCPU() // if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO if percent < 0.0 { log.Tracef("Err CPU Percent of Process: %f, CPU num: %d", percent, numcpu) } else { log.Tracef("get process CPU percent: %f, CPU num: %d", percent, numcpu) } } func GetProcessMemoryInfo() { p := getProcess() v, err := p.MemoryInfo() if err != nil { log.Tracef("getting memory info error %v", err) } log.Tracef("get process memory info %v", v) info, _ := mem.VirtualMemory() fmt.Println(info) } func GetPartitions(sysInfo *SysInfo) { sysInfo.PartitionNum = 0 //sysInfo.PartitionInfo = make([]PartitionInfo, MAX_PARTITION_NUM, MAX_PARTITION_NUM) infos, _ := disk.Partitions(true) for _, info := range infos { GetOnePartitionUsage(info.Mountpoint, sysInfo) if sysInfo.PartitionNum >= MAX_PARTITION_NUM { break } } } func GetOnePartitionUsage(path string, sysInfo *SysInfo) int { info, err := disk.Usage(path) if err != nil { return -1 } if info.Total <= 0 { // info.Used/(1024 * 1024)MB return 0 } var partition PartitionInfo partition.Total = uint32(info.Total / 1024 / 1024) partition.Used = uint32(info.Used / 1024 / 1024) sysInfo.PartitionInfo = append(sysInfo.PartitionInfo, partition) sysInfo.PartitionNum++ /*data, err := json.MarshalIndent(info, "", " ") if err != nil { return -1 } fmt.Println(string(data))*/ return 1 } func getOS() string { var osname string if runtime.GOOS == "linux" { osname = "GNU/Linux" } return osname } func utsnameToString(unameArray [65]int8) string { var byteString [65]byte var indexLength int for ; unameArray[indexLength] != 0 && indexLength < 65; indexLength++ { byteString[indexLength] = uint8(unameArray[indexLength]) } return string(byteString[:indexLength]) } func getUnameStr() string { var utsname = syscall.Utsname{} err := syscall.Uname(&utsname) if err == nil { name := utsnameToString(utsname.Sysname) node := utsnameToString(utsname.Nodename) release := utsnameToString(utsname.Release) version := utsnameToString(utsname.Version) machine := utsnameToString(utsname.Machine) //domain:= utsnameToString(utsname.Domainname) osName := getOS() return fmt.Sprintf("%s %s %s %s %s %s", name, node, release, version, machine, osName) } return "" }