github.com/Inphi/go-ethereum@v1.9.7/dashboard/system.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package dashboard 18 19 import ( 20 "runtime" 21 "time" 22 23 "github.com/elastic/gosigar" 24 "github.com/ethereum/go-ethereum/metrics" 25 "github.com/ethereum/go-ethereum/p2p" 26 ) 27 28 // meterCollector returns a function, which retrieves the count of a specific meter. 29 func meterCollector(name string) func() int64 { 30 if meter := metrics.Get(name); meter != nil { 31 m := meter.(metrics.Meter) 32 return func() int64 { 33 return m.Count() 34 } 35 } 36 return func() int64 { 37 return 0 38 } 39 } 40 41 // collectSystemData gathers data about the system and sends it to the clients. 42 func (db *Dashboard) collectSystemData() { 43 defer db.wg.Done() 44 45 systemCPUUsage := gosigar.Cpu{} 46 systemCPUUsage.Get() 47 var ( 48 mem runtime.MemStats 49 50 collectNetworkIngress = meterCollector(p2p.MetricsInboundTraffic) 51 collectNetworkEgress = meterCollector(p2p.MetricsOutboundTraffic) 52 collectDiskRead = meterCollector("eth/db/chaindata/disk/read") 53 collectDiskWrite = meterCollector("eth/db/chaindata/disk/write") 54 55 prevNetworkIngress = collectNetworkIngress() 56 prevNetworkEgress = collectNetworkEgress() 57 prevProcessCPUTime = getProcessCPUTime() 58 prevSystemCPUUsage = systemCPUUsage 59 prevDiskRead = collectDiskRead() 60 prevDiskWrite = collectDiskWrite() 61 62 frequency = float64(db.config.Refresh / time.Second) 63 numCPU = float64(runtime.NumCPU()) 64 ) 65 66 for { 67 select { 68 case errc := <-db.quit: 69 errc <- nil 70 return 71 case <-time.After(db.config.Refresh): 72 systemCPUUsage.Get() 73 var ( 74 curNetworkIngress = collectNetworkIngress() 75 curNetworkEgress = collectNetworkEgress() 76 curProcessCPUTime = getProcessCPUTime() 77 curSystemCPUUsage = systemCPUUsage 78 curDiskRead = collectDiskRead() 79 curDiskWrite = collectDiskWrite() 80 81 deltaNetworkIngress = float64(curNetworkIngress - prevNetworkIngress) 82 deltaNetworkEgress = float64(curNetworkEgress - prevNetworkEgress) 83 deltaProcessCPUTime = curProcessCPUTime - prevProcessCPUTime 84 deltaSystemCPUUsage = curSystemCPUUsage.Delta(prevSystemCPUUsage) 85 deltaDiskRead = curDiskRead - prevDiskRead 86 deltaDiskWrite = curDiskWrite - prevDiskWrite 87 ) 88 prevNetworkIngress = curNetworkIngress 89 prevNetworkEgress = curNetworkEgress 90 prevProcessCPUTime = curProcessCPUTime 91 prevSystemCPUUsage = curSystemCPUUsage 92 prevDiskRead = curDiskRead 93 prevDiskWrite = curDiskWrite 94 95 runtime.ReadMemStats(&mem) 96 activeMemory := &ChartEntry{ 97 Value: float64(mem.Alloc) / frequency, 98 } 99 virtualMemory := &ChartEntry{ 100 Value: float64(mem.Sys) / frequency, 101 } 102 networkIngress := &ChartEntry{ 103 Value: deltaNetworkIngress / frequency, 104 } 105 networkEgress := &ChartEntry{ 106 Value: deltaNetworkEgress / frequency, 107 } 108 processCPU := &ChartEntry{ 109 Value: deltaProcessCPUTime / frequency / numCPU * 100, 110 } 111 systemCPU := &ChartEntry{ 112 Value: float64(deltaSystemCPUUsage.Sys+deltaSystemCPUUsage.User) / frequency / numCPU, 113 } 114 diskRead := &ChartEntry{ 115 Value: float64(deltaDiskRead) / frequency, 116 } 117 diskWrite := &ChartEntry{ 118 Value: float64(deltaDiskWrite) / frequency, 119 } 120 db.sysLock.Lock() 121 sys := db.history.System 122 sys.ActiveMemory = append(sys.ActiveMemory[1:], activeMemory) 123 sys.VirtualMemory = append(sys.VirtualMemory[1:], virtualMemory) 124 sys.NetworkIngress = append(sys.NetworkIngress[1:], networkIngress) 125 sys.NetworkEgress = append(sys.NetworkEgress[1:], networkEgress) 126 sys.ProcessCPU = append(sys.ProcessCPU[1:], processCPU) 127 sys.SystemCPU = append(sys.SystemCPU[1:], systemCPU) 128 sys.DiskRead = append(sys.DiskRead[1:], diskRead) 129 sys.DiskWrite = append(sys.DiskWrite[1:], diskWrite) 130 db.sysLock.Unlock() 131 132 db.sendToAll(&Message{ 133 System: &SystemMessage{ 134 ActiveMemory: ChartEntries{activeMemory}, 135 VirtualMemory: ChartEntries{virtualMemory}, 136 NetworkIngress: ChartEntries{networkIngress}, 137 NetworkEgress: ChartEntries{networkEgress}, 138 ProcessCPU: ChartEntries{processCPU}, 139 SystemCPU: ChartEntries{systemCPU}, 140 DiskRead: ChartEntries{diskRead}, 141 DiskWrite: ChartEntries{diskWrite}, 142 }, 143 }) 144 } 145 } 146 }