func (p *Performance) retrieveCpuAndMem() error { m := new(snmp.Message) m.Version = 1 m.Community = p.Community var done = true // retrieve cpu objs := [][]int{snmp.CPU_RAW_IDLE, snmp.CPU_RAW_USER, snmp.CPU_RAW_NICE, snmp.CPU_RAW_SYSTEM, snmp.CPU_RAW_WAIT, []int{}, snmp.MEM_TOTAL, snmp.MEM_AVAIL, []int{}, snmp.SWAP_TOTAL, snmp.SWAP_AVAIL} vals := make([]int64, 9) // 9 items func() { j := -1 for _, v := range objs { if len(v) == 0 { done = true continue } j++ if !done { continue } m.RequestObjId = v err := p.ses.Get(m) if err != nil { done = false } if m.ErrIndex == 0 { if ret, ok := m.Value.(int64); ok { vals[j] = ret done = true } } } }() if !done { p.CPU = 0.0 p.MemoryTtl = 0 p.MemoryAvail = 0 p.SwapTtl = 0 p.SwapAvail = 0 } else { ttl := int64(0) for _, v := range vals[0:5] { ttl += v } p.CPU = 1.0 - float32(vals[0])/float32(ttl) p.MemoryTtl = int(vals[5]) / 1000 // KB -> MB p.MemoryAvail = int(vals[6]) / 1000 p.SwapTtl = int(vals[7]) / 1000 // KB -> MB p.SwapAvail = int(vals[8]) / 1000 } return nil }
// retrieve ifOctets except "lo" func (p *Performance) retrieveOctets() error { m := new(snmp.Message) m.Version = 1 m.Community = p.Community m.RequestObjId = snmp.IF_DESCR rets, err := p.ses.Walk(m) if err != nil { return err } var devs []string var lo int for i, v := range rets { var dev string switch v.(type) { case []byte: d := v.([]byte) dev = string(d) default: log.Fatal("Uanble to decode value: ", v) } if dev != "" { if dev == "lo" { lo = i } else { devs = append(devs, dev) } } } var objs = [][]int{snmp.IF_INOCTETS, snmp.IF_OUTOCTETS} var vals = make([][]int64, len(objs)) for i, v := range objs { m.RequestObjId = v vs, err := p.ses.Walk(m) if err != nil { return err } var tmp = make([]int64, len(devs)) if m.ErrIndex == 0 { var j = 0 for i2, v2 := range vs { if i2 != lo { // doesn't check if j will be out of range here to expose potential error in advance /* if j >= len(devs) { break } */ if val, ok := v2.(int64); ok { tmp[j] = val } else { tmp[j] = 0 } j++ } } } vals[i] = tmp } p.IfOctets = make([]IfOctet, len(devs)) for i, v := range devs { p.IfOctets[i].IfDescr = v p.IfOctets[i].IfInOctet = vals[0][i] / 1000000 // B -> MB p.IfOctets[i].IfOutOctet = vals[1][i] / 1000000 } return nil }
func (p *Performance) retrieveDisk() error { m := new(snmp.Message) m.Version = 1 m.Community = p.Community // retrieve device paths m.RequestObjId = snmp.DISK_DEVICE rets, err := p.ses.Walk(m) if err != nil { return err } // retrieve device mount point m.RequestObjId = snmp.DISK_PATH rets2, err := p.ses.Walk(m) if err != nil { return err } var paths []string var done = make([]int, len(rets)) for i, v := range rets { var dev string switch v.(type) { case []byte: d := v.([]byte) dev = string(d) default: log.Fatal("Uanble to decode value: ", v) // to expose error } if dev != "" && strings.HasPrefix(dev, "/dev/") { var path string switch rets2[i].(type) { case []byte: p := rets2[i].([]byte) path = string(p) default: log.Fatal("Uanble to decode value: ", v) // to expose error } if path != "" { paths = append(paths, path) done[i] = 1 } } } var objs = [][]int{snmp.DISK_TOTAL, snmp.DISK_AVAIL} var vals = make([][]int64, len(objs)) // each element of vals is []int, relating to the paths for i, v := range objs { m.RequestObjId = v vs, err := p.ses.Walk(m) // walk the obj if err != nil { return err } var tmp = make([]int64, len(paths)) if m.ErrIndex == 0 { var j = 0 for i2 := range done { if done[i2] == 1 { // corresponding values to /dev/sd* if val, ok := vs[i2].(int64); ok { tmp[j] = val } else { tmp[j] = 0 // failed to transfer to int } j++ } } } vals[i] = tmp } p.Disks = make([]Disk, len(paths)) for i := range paths { p.Disks[i].Path = paths[i] p.Disks[i].Total = vals[0][i] / 1024 // file: KB -> MB p.Disks[i].Avail = vals[1][i] / 1024 // file: KB -> MB } return nil }