github.com/bloxroute-labs/bor@v0.1.4/dashboard/system.go (about)

     1  // Copyright 2018 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/maticnetwork/bor/metrics"
    25  	"github.com/maticnetwork/bor/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  }