From 806f406ee0a2ff9dcd4651a74ab0b6e1f28f0599 Mon Sep 17 00:00:00 2001 From: insanity Date: Tue, 24 Oct 2017 16:09:17 +0900 Subject: [PATCH] ing --- crawler/crawler.go | 25 ++++++++--- main.go | 93 +++++++++++++++++++++++--------------- stat/cpu.go | 110 ++++++++++++++++++++++++++++++++------------- stat/disk_free.go | 24 +++++----- stat/disk_io.go | 48 ++++++++++---------- stat/loadavg.go | 12 ++--- stat/mem.go | 43 ++++++++++++++++-- stat/network.go | 68 ++++++++++++++-------------- stat/process.go | 24 +++++----- stat/uptime.go | 1 + util/util.go | 26 +++++++++++ 11 files changed, 311 insertions(+), 163 deletions(-) create mode 100644 stat/uptime.go create mode 100644 util/util.go diff --git a/crawler/crawler.go b/crawler/crawler.go index 6d41909..74508d0 100644 --- a/crawler/crawler.go +++ b/crawler/crawler.go @@ -2,6 +2,7 @@ package crawler import ( "bytes" + "encoding/json" "git.loafle.net/overflow/ssh_crawler/ssh" "git.loafle.net/overflow/ssh_crawler/stat" ) @@ -29,33 +30,43 @@ func (c *Crawler) connectSSH(ip, port, user, pw string) error { return nil } -func (c *Crawler) CPUStat(ch chan interface{}) { +func (c *Crawler) CPUStat(ch chan interface{}, keys []string) { go func() { cpu := &stat.CPUStat{} b, err := c.sshCli.RunCommand(cpu.Command()) if err != nil { ch <- err } - res, err := cpu.Parse(bytes.NewReader(b)) + res, err := cpu.Read(bytes.NewReader(b), keys) if err != nil { ch <- err } - ch <- res + jsonData, err := json.Marshal(res) + if err != nil { + ch <- err + } + ch <- string(jsonData) + close(ch) }() } -func (c *Crawler) MemStat(ch chan interface{}) { +func (c *Crawler) MemStat(ch chan interface{}, keys []string) { go func() { mem := &stat.MemStat{} b, err := c.sshCli.RunCommand(mem.Command()) if err != nil { ch <- err } - res, err := mem.Parse(bytes.NewReader(b)) + res, err := mem.Read(bytes.NewReader(b), keys) if err != nil { ch <- err } - ch <- res + jsonData, err := json.Marshal(res) + if err != nil { + ch <- err + } + ch <- string(jsonData) + close(ch) }() } @@ -73,6 +84,7 @@ func (c *Crawler) DiskIOStat(ch chan interface{}) { ch <- err } ch <- res + close(ch) }() } @@ -88,6 +100,7 @@ func (c *Crawler) DiskFreeStat(ch chan interface{}) { ch <- err } ch <- res + close(ch) }() } diff --git a/main.go b/main.go index e39c5a6..5e55c5b 100644 --- a/main.go +++ b/main.go @@ -3,11 +3,9 @@ package main import ( "fmt" "git.loafle.net/overflow/ssh_crawler/crawler" - "runtime" ) func main() { - runtime.GOMAXPROCS(4) const ip = "192.168.1.15" const port = "22" @@ -19,45 +17,70 @@ func main() { fmt.Println(err) } - //CPU + //사용자가 cpu.usage.total을 선택했을 때의 수집항목들 (..출력 항목도 포함시켜서 계산결과 리턴해야하나?) + cpukeys := []string{ + "cpu.usage.sum", + "cpu.usage.user", + "cpu.usage.system", + "cpu.usage.nice", + "cpu.usage.idle", + "cpu.usage.iowait", + "cpu.usage.irq", + "cpu.usage.softirq", + "cpu.usage.steal", + "cpu.usage.guest", + "cpu.usage.guestNice", + } cpuCh := make(chan interface{}) - cr.CPUStat(cpuCh) + cr.CPUStat(cpuCh, cpukeys) fmt.Println(<-cpuCh) - close(cpuCh) //Memory + memkeys := []string { + "mem.usage.total", + "mem.usage.free", + "mem.usage.available", + "mem.usage.buffers", + "mem.usage.cached", + "mem.swap.usage.total", + "mem.swap.usage.free", + "mem.swap.usage.cached", + } memCh := make(chan interface{}) - cr.MemStat(memCh) + cr.MemStat(memCh, memkeys) fmt.Println(<-memCh) - close(memCh) - //Disk IO - diskioCh := make(chan interface{}) - cr.DiskIOStat(diskioCh) - fmt.Println(<-diskioCh) - close(diskioCh) + //memCh := make(chan interface{}) + //cr.MemStat(memCh, keys) + //fmt.Println(<-memCh) - //Disk Free - diskFreeCh := make(chan interface{}) - cr.DiskFreeStat(diskFreeCh) - fmt.Println(<-diskFreeCh) - close(diskFreeCh) - - //Network - netCh := make(chan interface{}) - cr.NetworkStat(netCh) - fmt.Println(<-netCh) - close(netCh) - - //Load Avg. - loadCh := make(chan interface{}) - cr.LoadAvgStat(loadCh) - fmt.Println(<-loadCh) - close(loadCh) - - //Process - psCh := make(chan interface{}) - cr.ProcessStat(psCh) - fmt.Println(<-psCh) - close(psCh) + ////Memory + //memCh := make(chan interface{}) + //cr.MemStat(memCh) + //fmt.Println(<-memCh) + // + ////Disk IO + //diskioCh := make(chan interface{}) + //cr.DiskIOStat(diskioCh) + //fmt.Println(<-diskioCh) + // + ////Disk Free + //diskFreeCh := make(chan interface{}) + //cr.DiskFreeStat(diskFreeCh) + //fmt.Println(<-diskFreeCh) + // + ////Network + //netCh := make(chan interface{}) + //cr.NetworkStat(netCh) + //fmt.Println(<-netCh) + // + ////Load Avg. + //loadCh := make(chan interface{}) + //cr.LoadAvgStat(loadCh) + //fmt.Println(<-loadCh) + // + ////Process + //psCh := make(chan interface{}) + //cr.ProcessStat(psCh) + //fmt.Println(<-psCh) } diff --git a/stat/cpu.go b/stat/cpu.go index 0935d5f..aaf9fe8 100644 --- a/stat/cpu.go +++ b/stat/cpu.go @@ -4,29 +4,31 @@ import ( "bufio" "io" "strings" + "git.loafle.net/overflow/ssh_crawler/util" ) type CPUStat struct { - device, - user, - nice, - system, - idle, - iowait, - irq, - softIrq, - steal, // (over 2.6.11) - guest, // (over 2.6.24) - guestNice string //(over 2.6.33) + Device, + User, + Nice, + System, + Idle, + Iowait, + Irq, + SoftIrq, + Steal, // (over 2.6.11) + Guest, // (over 2.6.24) + GuestNice, //(over 2.6.33) + Sum float64 } func (cpu CPUStat) Command() string { return "cat /proc/stat" } -func (cpu CPUStat) Parse(r io.Reader) (*[]CPUStat, error) { +func (cpu CPUStat) Read(r io.Reader, keys []string) (*map[string]string, error) { var ( - CPUStats = []CPUStat{} + stats = []CPUStat{} scanner = bufio.NewScanner(r) ) @@ -37,31 +39,79 @@ func (cpu CPUStat) Parse(r io.Reader) (*[]CPUStat, error) { continue } - steal, guest, guestNice := "", "", "" + var steal, guest, guestNice float64 if len(parts) > 8 { - steal = parts[8] + steal = util.StringToFloat64(parts[8]) } if len(parts) > 9 { - guest = parts[9] + guest = util.StringToFloat64(parts[9]) } if len(parts) > 10 { - guestNice = parts[10] + guestNice = util.StringToFloat64(parts[10]) } - CPUStats = append(CPUStats, CPUStat{ - device: parts[0], - user: parts[1], - nice: parts[2], - system: parts[3], - idle: parts[4], - iowait: parts[5], - irq: parts[6], - softIrq: parts[7], - steal: steal, - guest: guest, - guestNice: guestNice, + stats = append(stats, CPUStat{ + Device: util.StringToFloat64(parts[0]), + User: util.StringToFloat64(parts[1]), + Nice: util.StringToFloat64(parts[2]), + System: util.StringToFloat64(parts[3]), + Idle: util.StringToFloat64(parts[4]), + Iowait: util.StringToFloat64(parts[5]), + Irq: util.StringToFloat64(parts[6]), + SoftIrq: util.StringToFloat64(parts[7]), + Steal: steal, + Guest: guest, + GuestNice: guestNice, }) } - return &CPUStats, scanner.Err() + res, err :=cpu.parse(keys, stats) + if err != nil { + return nil, err + } + + return &res, scanner.Err() +} + +func (cpu CPUStat) parse(keys []string, data []CPUStat) (map[string]string, error) { + resMap := make(map[string]string) + + for _, key := range keys { + resMap[key] = cpu.calc(key, data[0]) + } + + return resMap, nil +} + +func (cpu CPUStat) calc(key string, d CPUStat) string { + var value float64 = 0 + sum := d.User + d.Nice + d.System + d.Idle + d.Iowait + d.Irq + d.SoftIrq + d.Steal + d.Guest + d.GuestNice + switch key { + case "cpu.usage.sum": + value = sum + case "cpu.usage.user": + value = d.User / sum * 100 + case "cpu.usage.nice": + value = d.Nice / sum * 100 + case "cpu.usage.system": + value = d.System / sum * 100 + case "cpu.usage.idle": + value = d.Idle / sum * 100 + case "cpu.usage.iowait": + value = d.Iowait / sum * 100 + case "cpu.usage.irq": + value = d.Irq / sum * 100 + case "cpu.usage.softirq": + value = d.SoftIrq / sum * 100 + case "cpu.usage.steal": + value = d.Steal / sum * 100 + case "cpu.usage.guest": + value = d.Guest / sum * 100 + case "cpu.usage.gnice": + value = d.GuestNice / sum * 100 + default: + + } + + return util.Float64ToString(value) } diff --git a/stat/disk_free.go b/stat/disk_free.go index dbba71e..1ceaa57 100644 --- a/stat/disk_free.go +++ b/stat/disk_free.go @@ -7,12 +7,12 @@ import ( ) type DiskFreeStat struct { - filesystem, - size, - used, - available, - usePerc, - mountedOn string + Filesystem, + Size, + Used, + Available, + UsePerc, + MountedOn string } func (diskFree DiskFreeStat) Command() string { @@ -28,12 +28,12 @@ func (diskio DiskFreeStat) Parse(r io.Reader) (*[]DiskFreeStat, error) { for scanner.Scan() { parts := strings.Fields(scanner.Text()) stats = append(stats, DiskFreeStat{ - filesystem: parts[0], - size: parts[1], - used: parts[2], - available: parts[3], - usePerc: removePercUnit(parts[4]), - mountedOn: parts[5], + Filesystem: parts[0], + Size: parts[1], + Used: parts[2], + Available: parts[3], + UsePerc: removePercUnit(parts[4]), + MountedOn: parts[5], }) } diff --git a/stat/disk_io.go b/stat/disk_io.go index 1988e5f..4e8268c 100644 --- a/stat/disk_io.go +++ b/stat/disk_io.go @@ -8,18 +8,18 @@ import ( ) type DiskIOStat struct { - device, - readCompleted, - readMerged, - sectorRead, - timeSpentReading, - writesCompleted, - writesMerged, - sectorsWritten, - timeSpentWriting, - ioInProg, - timeSpentIO, - weightedTimeSpentIO string + Device, + ReadCompleted, + ReadMerged, + SectorRead, + TimeSpentReading, + WritesCompleted, + WritesMerged, + SectorsWritten, + TimeSpentWriting, + IoInProg, + TimeSpentIO, + WeightedTimeSpentIO string } func (diskio DiskIOStat) Command() string { @@ -42,18 +42,18 @@ func (diskio DiskIOStat) Parse(r io.Reader) (*[]DiskIOStat, error) { continue } stats = append(stats, DiskIOStat{ - device: deviceName, - readCompleted: parts[3], - readMerged: parts[4], - sectorRead: parts[5], - timeSpentReading: parts[6], - writesCompleted: parts[7], - writesMerged: parts[8], - sectorsWritten: parts[9], - timeSpentWriting: parts[10], - ioInProg: parts[11], - timeSpentIO: parts[12], - weightedTimeSpentIO: parts[13], + Device: deviceName, + ReadCompleted: parts[3], + ReadMerged: parts[4], + SectorRead: parts[5], + TimeSpentReading: parts[6], + WritesCompleted: parts[7], + WritesMerged: parts[8], + SectorsWritten: parts[9], + TimeSpentWriting: parts[10], + IoInProg: parts[11], + TimeSpentIO: parts[12], + WeightedTimeSpentIO: parts[13], }) } diff --git a/stat/loadavg.go b/stat/loadavg.go index 6319080..d415aff 100644 --- a/stat/loadavg.go +++ b/stat/loadavg.go @@ -7,9 +7,9 @@ import ( ) type LoadAvg struct { - min1, - min5, - min15 string + Min1, + Min5, + Min15 string } func (loadavg LoadAvg) Command() string { @@ -25,9 +25,9 @@ func (loadavg LoadAvg) Parse(r io.Reader) (*LoadAvg, error) { for scanner.Scan() { line := scanner.Text() parts := strings.Fields(line) - load.min1 = parts[0] - load.min5 = parts[1] - load.min15 = parts[2] + load.Min1 = parts[0] + load.Min5 = parts[1] + load.Min15 = parts[2] } return &load, scanner.Err() } diff --git a/stat/mem.go b/stat/mem.go index 84dba17..0a36f0a 100644 --- a/stat/mem.go +++ b/stat/mem.go @@ -13,9 +13,9 @@ func (mem MemStat) Command() string { return "cat /proc/meminfo" } -func (mem MemStat) Parse(r io.Reader) (*map[string]string, error) { +func (mem MemStat) Read(r io.Reader, keys []string) (*map[string]string, error) { var ( - memInfo = map[string]string{} + stats = map[string]string{} scanner = bufio.NewScanner(r) ) @@ -23,8 +23,43 @@ func (mem MemStat) Parse(r io.Reader) (*map[string]string, error) { line := scanner.Text() parts := strings.Fields(line) key := parts[0][:len(parts[0])-1] - memInfo[key] = parts[1] + + stats[key] = parts[1] } - return &memInfo, scanner.Err() + res, err := mem.parse(keys, stats) + if err != nil { + return nil, err + } + + return &res, scanner.Err() +} + +func (mem MemStat) parse(keys []string, data map[string]string) (map[string]string, error) { + resMap := make(map[string]string) + + for _, key := range keys { + switch key { + case "mem.usage.total": + resMap[key] = data["MemTotal"] + case "mem.usage.free": + resMap[key] = data["MemFree"] + case "mem.usage.available": + resMap[key] = data["MemAvailable"] + case "mem.usage.buffers": + resMap[key] = data["Buffers"] + case "mem.usage.cached": + resMap[key] = data["Cached"] + case "mem.swap.usage.total": + resMap[key] = data["SwapTotal"] + case "mem.swap.usage.free": + resMap[key] = data["SwapFree"] + case "mem.swap.usage.cached": + resMap[key] = data["SwapCached"] + default: + + } + } + + return resMap, nil } diff --git a/stat/network.go b/stat/network.go index f7055c8..7657a8a 100644 --- a/stat/network.go +++ b/stat/network.go @@ -9,23 +9,23 @@ import ( ) type NetDevStat struct { - iface, - recvByte, - recvPacket, - recvErr, - recvDrop, - recvFifo, - recvFrame, - recvCompressed, - recvMulticast, - transByte, - transPacket, - transErr, - transDrop, - transFifo, - transFrame, - transCompressed, - transMulticast string + Iface, + RecvByte, + RecvPacket, + RecvErr, + RecvDrop, + RecvFifo, + RecvFrame, + RecvCompressed, + RecvMulticast, + TransByte, + TransPacket, + TransErr, + TransDrop, + TransFifo, + TransFrame, + TransCompressed, + TransMulticast string } func (net *NetDevStat) Command() string { @@ -56,23 +56,23 @@ func (net *NetDevStat) Parse(r io.Reader) (*[]NetDevStat, error) { dev := parts[0][:len(parts[0])] netDevStats = append(netDevStats, NetDevStat{ - iface: dev, - recvByte: parts[1], - recvPacket: parts[2], - recvErr: parts[3], - recvDrop: parts[4], - recvFifo: parts[5], - recvFrame: parts[6], - recvCompressed: parts[7], - recvMulticast: parts[8], - transByte: parts[9], - transPacket: parts[10], - transErr: parts[11], - transDrop: parts[12], - transFifo: parts[13], - transFrame: parts[14], - transCompressed: parts[15], - transMulticast: parts[16], + Iface: dev, + RecvByte: parts[1], + RecvPacket: parts[2], + RecvErr: parts[3], + RecvDrop: parts[4], + RecvFifo: parts[5], + RecvFrame: parts[6], + RecvCompressed: parts[7], + RecvMulticast: parts[8], + TransByte: parts[9], + TransPacket: parts[10], + TransErr: parts[11], + TransDrop: parts[12], + TransFifo: parts[13], + TransFrame: parts[14], + TransCompressed: parts[15], + TransMulticast: parts[16], }) } return &netDevStats, scanner.Err() diff --git a/stat/process.go b/stat/process.go index a1c09cb..5ecb067 100644 --- a/stat/process.go +++ b/stat/process.go @@ -7,12 +7,12 @@ import ( ) type ProcessStat struct { - user, - pid, - size, - pcpu, - pmem, - cmd string + User, + Pid, + Size, + Pcpu, + Pmem, + Cmd string } func (ps *ProcessStat) Command() string { @@ -29,12 +29,12 @@ func (ps *ProcessStat) Parse(r io.Reader) (*[]ProcessStat, error) { line := scanner.Text() parts := strings.Fields(line) psStats = append(psStats, ProcessStat{ - user: parts[0], - pid: parts[1], - size: parts[2], - pcpu: parts[3], - pmem: parts[4], - cmd: parts[5], + User: parts[0], + Pid: parts[1], + Size: parts[2], + Pcpu: parts[3], + Pmem: parts[4], + Cmd: parts[5], }) } return &psStats, scanner.Err() diff --git a/stat/uptime.go b/stat/uptime.go new file mode 100644 index 0000000..a5ffb48 --- /dev/null +++ b/stat/uptime.go @@ -0,0 +1 @@ +package stat diff --git a/util/util.go b/util/util.go new file mode 100644 index 0000000..8441def --- /dev/null +++ b/util/util.go @@ -0,0 +1,26 @@ +package util + +import ( + "fmt" + "math" + "strconv" +) + +func StringToFloat64(str string) float64 { + n, _ := strconv.ParseFloat(str, 64) + return n +} + +func Float64ToString(num float64) string { + + return fmt.Sprintf("%v", toFixed(num, 2)) +} + +func round(num float64) int { + return int(num + math.Copysign(0.5, num)) +} + +func toFixed(num float64, precision int) float64 { + output := math.Pow(10, float64(precision)) + return float64(round(num*output)) / output +}