| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- // Copyright 2018 The go-ethereum Authors
- // This file is part of the go-ethereum library.
- //
- // The go-ethereum library is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Lesser General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // The go-ethereum library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public License
- // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
- package dashboard
- import (
- "runtime"
- "time"
- "github.com/elastic/gosigar"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/p2p"
- )
- // meterCollector returns a function, which retrieves the count of a specific meter.
- func meterCollector(name string) func() int64 {
- if meter := metrics.Get(name); meter != nil {
- m := meter.(metrics.Meter)
- return func() int64 {
- return m.Count()
- }
- }
- return func() int64 {
- return 0
- }
- }
- // collectSystemData gathers data about the system and sends it to the clients.
- func (db *Dashboard) collectSystemData() {
- defer db.wg.Done()
- systemCPUUsage := gosigar.Cpu{}
- systemCPUUsage.Get()
- var (
- mem runtime.MemStats
- collectNetworkIngress = meterCollector(p2p.MetricsInboundTraffic)
- collectNetworkEgress = meterCollector(p2p.MetricsOutboundTraffic)
- collectDiskRead = meterCollector("eth/db/chaindata/disk/read")
- collectDiskWrite = meterCollector("eth/db/chaindata/disk/write")
- prevNetworkIngress = collectNetworkIngress()
- prevNetworkEgress = collectNetworkEgress()
- prevProcessCPUTime = getProcessCPUTime()
- prevSystemCPUUsage = systemCPUUsage
- prevDiskRead = collectDiskRead()
- prevDiskWrite = collectDiskWrite()
- frequency = float64(db.config.Refresh / time.Second)
- numCPU = float64(runtime.NumCPU())
- )
- for {
- select {
- case errc := <-db.quit:
- errc <- nil
- return
- case <-time.After(db.config.Refresh):
- systemCPUUsage.Get()
- var (
- curNetworkIngress = collectNetworkIngress()
- curNetworkEgress = collectNetworkEgress()
- curProcessCPUTime = getProcessCPUTime()
- curSystemCPUUsage = systemCPUUsage
- curDiskRead = collectDiskRead()
- curDiskWrite = collectDiskWrite()
- deltaNetworkIngress = float64(curNetworkIngress - prevNetworkIngress)
- deltaNetworkEgress = float64(curNetworkEgress - prevNetworkEgress)
- deltaProcessCPUTime = curProcessCPUTime - prevProcessCPUTime
- deltaSystemCPUUsage = curSystemCPUUsage.Delta(prevSystemCPUUsage)
- deltaDiskRead = curDiskRead - prevDiskRead
- deltaDiskWrite = curDiskWrite - prevDiskWrite
- )
- prevNetworkIngress = curNetworkIngress
- prevNetworkEgress = curNetworkEgress
- prevProcessCPUTime = curProcessCPUTime
- prevSystemCPUUsage = curSystemCPUUsage
- prevDiskRead = curDiskRead
- prevDiskWrite = curDiskWrite
- runtime.ReadMemStats(&mem)
- activeMemory := &ChartEntry{
- Value: float64(mem.Alloc) / frequency,
- }
- virtualMemory := &ChartEntry{
- Value: float64(mem.Sys) / frequency,
- }
- networkIngress := &ChartEntry{
- Value: deltaNetworkIngress / frequency,
- }
- networkEgress := &ChartEntry{
- Value: deltaNetworkEgress / frequency,
- }
- processCPU := &ChartEntry{
- Value: deltaProcessCPUTime / frequency / numCPU * 100,
- }
- systemCPU := &ChartEntry{
- Value: float64(deltaSystemCPUUsage.Sys+deltaSystemCPUUsage.User) / frequency / numCPU,
- }
- diskRead := &ChartEntry{
- Value: float64(deltaDiskRead) / frequency,
- }
- diskWrite := &ChartEntry{
- Value: float64(deltaDiskWrite) / frequency,
- }
- db.sysLock.Lock()
- sys := db.history.System
- sys.ActiveMemory = append(sys.ActiveMemory[1:], activeMemory)
- sys.VirtualMemory = append(sys.VirtualMemory[1:], virtualMemory)
- sys.NetworkIngress = append(sys.NetworkIngress[1:], networkIngress)
- sys.NetworkEgress = append(sys.NetworkEgress[1:], networkEgress)
- sys.ProcessCPU = append(sys.ProcessCPU[1:], processCPU)
- sys.SystemCPU = append(sys.SystemCPU[1:], systemCPU)
- sys.DiskRead = append(sys.DiskRead[1:], diskRead)
- sys.DiskWrite = append(sys.DiskWrite[1:], diskWrite)
- db.sysLock.Unlock()
- db.sendToAll(&Message{
- System: &SystemMessage{
- ActiveMemory: ChartEntries{activeMemory},
- VirtualMemory: ChartEntries{virtualMemory},
- NetworkIngress: ChartEntries{networkIngress},
- NetworkEgress: ChartEntries{networkEgress},
- ProcessCPU: ChartEntries{processCPU},
- SystemCPU: ChartEntries{systemCPU},
- DiskRead: ChartEntries{diskRead},
- DiskWrite: ChartEntries{diskWrite},
- },
- })
- }
- }
- }
|