func ListeningPorts() ([]int64, error) { ports := []int64{} bs, err := sys.CmdOutBytes("ss", "-t", "-l", "-n") if err != nil { return ports, err } reader := bufio.NewReader(bytes.NewBuffer(bs)) // ignore the first line line, err := file.ReadLine(reader) if err != nil { return ports, err } for { line, err = file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return ports, err } fields := strings.Fields(string(line)) fieldsLen := len(fields) if fieldsLen != 4 && fieldsLen != 5 { return ports, fmt.Errorf("output of [ss -t -l -n] format not supported") } portColumnIndex := 2 if fieldsLen == 5 { portColumnIndex = 3 } location := strings.LastIndex(fields[portColumnIndex], ":") port := fields[portColumnIndex][location+1:] if p, e := strconv.ParseInt(port, 10, 64); e != nil { return ports, fmt.Errorf("parse port to int64 fail: %s", e.Error()) } else { ports = append(ports, p) } } return slice.UniqueInt64(ports), nil }
// @param ext e.g. TcpExt or IpExt func Netstat(ext string) (ret map[string]uint64, err error) { ret = make(map[string]uint64) var contents []byte contents, err = ioutil.ReadFile("/proc/net/netstat") if err != nil { return } reader := bufio.NewReader(bytes.NewBuffer(contents)) for { var bs []byte bs, err = file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return } line := string(bs) idx := strings.Index(line, ":") if idx < 0 { continue } title := strings.TrimSpace(line[:idx]) if title == ext { ths := strings.Fields(strings.TrimSpace(line[idx+1:])) // the next line must be values bs, err = file.ReadLine(reader) if err != nil { return } valLine := string(bs) tds := strings.Fields(strings.TrimSpace(valLine[idx+1:])) for i := 0; i < len(ths); i++ { ret[ths[i]], err = strconv.ParseUint(tds[i], 10, 64) if err != nil { return } } return } } return }
func SocketStatSummary() (m map[string]uint64, err error) { m = make(map[string]uint64) var bs []byte bs, err = sys.CmdOutBytes("sh", "-c", "ss -s") if err != nil { return } reader := bufio.NewReader(bytes.NewBuffer(bs)) // ignore the first line line, e := file.ReadLine(reader) if e != nil { return m, e } for { line, err = file.ReadLine(reader) if err != nil { return } lineStr := string(line) if strings.HasPrefix(lineStr, "TCP") { left := strings.Index(lineStr, "(") right := strings.Index(lineStr, ")") if left < 0 || right < 0 { continue } content := lineStr[left+1 : right] arr := strings.Split(content, ", ") for _, val := range arr { fields := strings.Fields(val) if fields[0] == "timewait" { timewait_arr := strings.Split(fields[1], "/") m["timewait"], _ = strconv.ParseUint(timewait_arr[0], 10, 64) m["slabinfo.timewait"], _ = strconv.ParseUint(timewait_arr[1], 10, 64) continue } m[fields[0]], _ = strconv.ParseUint(fields[1], 10, 64) } return } } return }
func ReadName(path string) (name string, err error) { var content []byte content, err = ioutil.ReadFile(path) if err != nil { return } reader := bufio.NewReader(bytes.NewBuffer(content)) for { var bs []byte bs, err = file.ReadLine(reader) if err == io.EOF { return } line := string(bs) colonIndex := strings.Index(line, ":") if strings.TrimSpace(line[0:colonIndex]) == "Name" { return strings.TrimSpace(line[colonIndex+1:]), nil } } return }
func CpuMHz() (mhz string, err error) { f := "/proc/cpuinfo" var bs []byte bs, err = ioutil.ReadFile(f) if err != nil { return } reader := bufio.NewReader(bytes.NewBuffer(bs)) for { var lineBytes []byte lineBytes, err = file.ReadLine(reader) if err == io.EOF { return } line := string(lineBytes) if !strings.Contains(line, "MHz") { continue } arr := strings.Split(line, ":") if len(arr) != 2 { return "", fmt.Errorf("%s content format error", f) } return strings.TrimSpace(arr[1]), nil } return "", fmt.Errorf("no MHz in %s", f) }
func PingStatSummary(ip string, count, timeout int) (m map[string]string, err error) { m = make(map[string]string) var bs []byte bs, err = sys.CmdOutBytes("ping", "-c", strconv.Itoa(count), "-W", strconv.Itoa(timeout), ip) if err != nil { return m, err } reader := bufio.NewReader(bytes.NewBuffer(bs)) // ignore the first line line, e := file.ReadLine(reader) if e != nil { return m, e } for { line, err = file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return m, err } lineStr := string(line) if strings.Contains(lineStr, "packet loss") { arr := strings.Split(lineStr, ", ") for _, val := range arr { fields := strings.Fields(val) if fields[1] == "packet" { m["pkloss"] = fields[0] } } } if strings.Contains(lineStr, "min/avg/max") { fields := strings.Fields(lineStr) result := strings.Split(fields[3], "/") m["min"] = result[0] m["avg"] = result[1] m["max"] = result[2] } } return m, e }
func MemInfo() (*Mem, error) { contents, err := ioutil.ReadFile("/proc/meminfo") if err != nil { return nil, err } memInfo := &Mem{} reader := bufio.NewReader(bytes.NewBuffer(contents)) for { line, err := file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return nil, err } fields := strings.Fields(string(line)) fieldName := fields[0] _, ok := WANT[fieldName] if ok && len(fields) == 3 { val, numerr := strconv.ParseUint(fields[1], 10, 64) if numerr != nil { continue } switch fieldName { case "Buffers:": memInfo.Buffers = val * Multi case "Cached:": memInfo.Cached = val * Multi case "MemTotal:": memInfo.MemTotal = val * Multi case "MemFree:": memInfo.MemFree = val * Multi case "SwapTotal:": memInfo.SwapTotal = val * Multi case "SwapFree:": memInfo.SwapFree = val * Multi } } } memInfo.SwapUsed = memInfo.SwapTotal - memInfo.SwapFree return memInfo, nil }
func probeUrl(furl string, timeout string) (bool, error) { bs, err := sys.CmdOutBytes("curl", "--max-filesize", "102400", "-I", "-m", timeout, "-o", "/dev/null", "-s", "-w", "%{http_code}", furl) if err != nil { log.Printf("probe url [%v] failed.the err is: [%v]\n", furl, err) return false, err } reader := bufio.NewReader(bytes.NewBuffer(bs)) retcode, err := file.ReadLine(reader) if err != nil { log.Println("read retcode failed.err is:", err) return false, err } if strings.TrimSpace(string(retcode)) != "200" { log.Printf("return code [%v] is not 200.query url is [%v]", string(retcode), furl) return false, err } return true, err }
func CurrentProcStat() (*ProcStat, error) { f := "/proc/stat" bs, err := ioutil.ReadFile(f) if err != nil { return nil, err } ps := &ProcStat{Cpus: make([]*CpuUsage, NumCpu())} reader := bufio.NewReader(bytes.NewBuffer(bs)) for { line, err := file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return ps, err } parseLine(line, ps) } return ps, nil }
// return: [][$fs_spec, $fs_file, $fs_vfstype] func ListMountPoint() ([][3]string, error) { contents, err := ioutil.ReadFile("/proc/mounts") if err != nil { return nil, err } ret := make([][3]string, 0) reader := bufio.NewReader(bytes.NewBuffer(contents)) for { line, err := file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return nil, err } fields := strings.Fields(string(line)) // Docs come from the fstab(5) // fs_spec # Mounted block special device or remote filesystem e.g. /dev/sda1 // fs_file # Mount point e.g. /data // fs_vfstype # File system type e.g. ext4 // fs_mntops # Mount options // fs_freq # Dump(8) utility flags // fs_passno # Order in which filesystem checks are done at reboot time fs_spec := fields[0] fs_file := fields[1] fs_vfstype := fields[2] if _, exist := FSSPEC_IGNORE[fs_spec]; exist { continue } if _, exist := FSTYPE_IGNORE[fs_vfstype]; exist { continue } if strings.HasPrefix(fs_vfstype, "fuse") { continue } if IgnoreFsFile(fs_file) { continue } // keep /dev/xxx device with shorter fs_file (remove mount binds) if strings.HasPrefix(fs_spec, "/dev") { deviceFound := false for idx := range ret { if ret[idx][0] == fs_spec { deviceFound = true if len(fs_file) < len(ret[idx][1]) { ret[idx][1] = fs_file } break } } if !deviceFound { ret = append(ret, [3]string{fs_spec, fs_file, fs_vfstype}) } } else { ret = append(ret, [3]string{fs_spec, fs_file, fs_vfstype}) } } return ret, nil }
/* Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed eth0: 1990350 2838 0 0 0 0 0 0 401351 2218 0 0 0 0 0 0 lo: 26105 286 0 0 0 0 0 0 26105 286 0 0 0 0 0 0 */ func NetIfs(onlyPrefix []string) ([]*NetIf, error) { contents, err := ioutil.ReadFile("/proc/net/dev") if err != nil { return nil, err } ret := []*NetIf{} reader := bufio.NewReader(bytes.NewBuffer(contents)) for { lineBytes, err := file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return nil, err } line := string(lineBytes) idx := strings.Index(line, ":") if idx < 0 { continue } netIf := NetIf{} eth := strings.TrimSpace(line[0:idx]) if len(onlyPrefix) > 0 { found := false for _, prefix := range onlyPrefix { if strings.HasPrefix(eth, prefix) { found = true break } } if !found { continue } } netIf.Iface = eth fields := strings.Fields(line[idx+1:]) if len(fields) != 16 { continue } netIf.InBytes, _ = strconv.ParseInt(fields[0], 10, 64) netIf.InPackages, _ = strconv.ParseInt(fields[1], 10, 64) netIf.InErrors, _ = strconv.ParseInt(fields[2], 10, 64) netIf.InDropped, _ = strconv.ParseInt(fields[3], 10, 64) netIf.InFifoErrs, _ = strconv.ParseInt(fields[4], 10, 64) netIf.InFrameErrs, _ = strconv.ParseInt(fields[5], 10, 64) netIf.InCompressed, _ = strconv.ParseInt(fields[6], 10, 64) netIf.InMulticast, _ = strconv.ParseInt(fields[7], 10, 64) netIf.OutBytes, _ = strconv.ParseInt(fields[8], 10, 64) netIf.OutPackages, _ = strconv.ParseInt(fields[9], 10, 64) netIf.OutErrors, _ = strconv.ParseInt(fields[10], 10, 64) netIf.OutDropped, _ = strconv.ParseInt(fields[11], 10, 64) netIf.OutFifoErrs, _ = strconv.ParseInt(fields[12], 10, 64) netIf.OutCollisions, _ = strconv.ParseInt(fields[13], 10, 64) netIf.OutCarrierErrs, _ = strconv.ParseInt(fields[14], 10, 64) netIf.OutCompressed, _ = strconv.ParseInt(fields[15], 10, 64) netIf.TotalBytes = netIf.InBytes + netIf.OutBytes netIf.TotalPackages = netIf.InPackages + netIf.OutPackages netIf.TotalErrors = netIf.InErrors + netIf.OutErrors netIf.TotalDropped = netIf.InDropped + netIf.OutDropped speedFile := fmt.Sprintf("/sys/class/net/%s/speed", netIf.Iface) if content, err := ioutil.ReadFile(speedFile); err == nil { var speed int64 speed, err = strconv.ParseInt(strings.TrimSpace(string(content)), 10, 64) if err != nil { netIf.SpeedBits = int64(0) netIf.InPercent = float64(0) netIf.OutPercent = float64(0) } else if speed == 0 { netIf.SpeedBits = int64(0) netIf.InPercent = float64(0) netIf.OutPercent = float64(0) } else { netIf.SpeedBits = speed * MILLION_BIT netIf.InPercent = float64(netIf.InBytes*BITS_PER_BYTE) * 100.0 / float64(netIf.SpeedBits) netIf.OutPercent = float64(netIf.OutBytes*BITS_PER_BYTE) * 100.0 / float64(netIf.SpeedBits) } } else { netIf.SpeedBits = int64(0) netIf.InPercent = float64(0) netIf.OutPercent = float64(0) } ret = append(ret, &netIf) } return ret, nil }
/* Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed eth0: 1990350 2838 0 0 0 0 0 0 401351 2218 0 0 0 0 0 0 lo: 26105 286 0 0 0 0 0 0 26105 286 0 0 0 0 0 0 */ func NetIfs(onlyPrefix []string) ([]*NetIf, error) { contents, err := ioutil.ReadFile("/proc/net/dev") if err != nil { return nil, err } ret := []*NetIf{} reader := bufio.NewReader(bytes.NewBuffer(contents)) for { lineBytes, err := file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return nil, err } line := string(lineBytes) idx := strings.Index(line, ":") if idx < 0 { continue } netIf := NetIf{} eth := strings.TrimSpace(line[0:idx]) if len(onlyPrefix) > 0 { found := false for _, prefix := range onlyPrefix { if strings.HasPrefix(eth, prefix) { found = true break } } if !found { continue } } netIf.Iface = eth fields := strings.Fields(line[idx+1:]) if len(fields) != 16 { continue } netIf.InBytes, _ = strconv.ParseInt(fields[0], 10, 64) netIf.InPackages, _ = strconv.ParseInt(fields[1], 10, 64) netIf.InErrors, _ = strconv.ParseInt(fields[2], 10, 64) netIf.InDropped, _ = strconv.ParseInt(fields[3], 10, 64) netIf.InFifoErrs, _ = strconv.ParseInt(fields[4], 10, 64) netIf.InFrameErrs, _ = strconv.ParseInt(fields[5], 10, 64) netIf.InCompressed, _ = strconv.ParseInt(fields[6], 10, 64) netIf.InMulticast, _ = strconv.ParseInt(fields[7], 10, 64) netIf.OutBytes, _ = strconv.ParseInt(fields[8], 10, 64) netIf.OutPackages, _ = strconv.ParseInt(fields[9], 10, 64) netIf.OutErrors, _ = strconv.ParseInt(fields[10], 10, 64) netIf.OutDropped, _ = strconv.ParseInt(fields[11], 10, 64) netIf.OutFifoErrs, _ = strconv.ParseInt(fields[12], 10, 64) netIf.OutCollisions, _ = strconv.ParseInt(fields[13], 10, 64) netIf.OutCarrierErrs, _ = strconv.ParseInt(fields[14], 10, 64) netIf.OutCompressed, _ = strconv.ParseInt(fields[15], 10, 64) netIf.TotalBytes = netIf.InBytes + netIf.OutBytes netIf.TotalPackages = netIf.InPackages + netIf.OutPackages netIf.TotalErrors = netIf.InErrors + netIf.OutErrors netIf.TotalDropped = netIf.InDropped + netIf.OutDropped ret = append(ret, &netIf) } return ret, nil }
func ListDiskStats() ([]*DiskStats, error) { proc_diskstats := "/proc/diskstats" if !file.IsExist(proc_diskstats) { return nil, fmt.Errorf("%s not exists", proc_diskstats) } contents, err := ioutil.ReadFile(proc_diskstats) if err != nil { return nil, err } ret := make([]*DiskStats, 0) reader := bufio.NewReader(bytes.NewBuffer(contents)) for { line, err := file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return nil, err } fields := strings.Fields(string(line)) // shortcut the deduper and just skip disks that // haven't done a single read. This elimiates a bunch // of loopback, ramdisk, and cdrom devices but still // lets us report on the rare case that we actually use // a ramdisk. if fields[3] == "0" { continue } size := len(fields) // kernel version too low if size != 14 { continue } item := &DiskStats{} if item.Major, err = strconv.Atoi(fields[0]); err != nil { return nil, err } if item.Minor, err = strconv.Atoi(fields[1]); err != nil { return nil, err } item.Device = fields[2] if item.ReadRequests, err = strconv.ParseUint(fields[3], 10, 64); err != nil { return nil, err } if item.ReadMerged, err = strconv.ParseUint(fields[4], 10, 64); err != nil { return nil, err } if item.ReadSectors, err = strconv.ParseUint(fields[5], 10, 64); err != nil { return nil, err } if item.MsecRead, err = strconv.ParseUint(fields[6], 10, 64); err != nil { return nil, err } if item.WriteRequests, err = strconv.ParseUint(fields[7], 10, 64); err != nil { return nil, err } if item.WriteMerged, err = strconv.ParseUint(fields[8], 10, 64); err != nil { return nil, err } if item.WriteSectors, err = strconv.ParseUint(fields[9], 10, 64); err != nil { return nil, err } if item.MsecWrite, err = strconv.ParseUint(fields[10], 10, 64); err != nil { return nil, err } if item.IosInProgress, err = strconv.ParseUint(fields[11], 10, 64); err != nil { return nil, err } if item.MsecTotal, err = strconv.ParseUint(fields[12], 10, 64); err != nil { return nil, err } if item.MsecWeightedTotal, err = strconv.ParseUint(fields[13], 10, 64); err != nil { return nil, err } item.TS = time.Now() ret = append(ret, item) } return ret, nil }