github.com/daeglee/go-ethereum@v0.0.0-20190504220456-cad3e8d18e9b/metrics/metrics.go (about) 1 // Go port of Coda Hale's Metrics library 2 // 3 // <https://github.com/rcrowley/go-metrics> 4 // 5 // Coda Hale's original work: <https://github.com/codahale/metrics> 6 package metrics 7 8 import ( 9 "os" 10 "runtime" 11 "strings" 12 "time" 13 14 "github.com/ethereum/go-ethereum/log" 15 ) 16 17 // Enabled is checked by the constructor functions for all of the 18 // standard metrics. If it is true, the metric returned is a stub. 19 // 20 // This global kill-switch helps quantify the observer effect and makes 21 // for less cluttered pprof profiles. 22 var Enabled = false 23 24 // EnabledExpensive is a soft-flag meant for external packages to check if costly 25 // metrics gathering is allowed or not. The goal is to separate standard metrics 26 // for health monitoring and debug metrics that might impact runtime performance. 27 var EnabledExpensive = false 28 29 // enablerFlags is the CLI flag names to use to enable metrics collections. 30 var enablerFlags = []string{"metrics", "dashboard"} 31 32 // expensiveEnablerFlags is the CLI flag names to use to enable metrics collections. 33 var expensiveEnablerFlags = []string{"metrics.expensive"} 34 35 // Init enables or disables the metrics system. Since we need this to run before 36 // any other code gets to create meters and timers, we'll actually do an ugly hack 37 // and peek into the command line args for the metrics flag. 38 func init() { 39 for _, arg := range os.Args { 40 flag := strings.TrimLeft(arg, "-") 41 42 for _, enabler := range enablerFlags { 43 if !Enabled && flag == enabler { 44 log.Info("Enabling metrics collection") 45 Enabled = true 46 } 47 } 48 for _, enabler := range expensiveEnablerFlags { 49 if !EnabledExpensive && flag == enabler { 50 log.Info("Enabling expensive metrics collection") 51 EnabledExpensive = true 52 } 53 } 54 } 55 } 56 57 // CollectProcessMetrics periodically collects various metrics about the running 58 // process. 59 func CollectProcessMetrics(refresh time.Duration) { 60 // Short circuit if the metrics system is disabled 61 if !Enabled { 62 return 63 } 64 // Create the various data collectors 65 memstats := make([]*runtime.MemStats, 2) 66 diskstats := make([]*DiskStats, 2) 67 for i := 0; i < len(memstats); i++ { 68 memstats[i] = new(runtime.MemStats) 69 diskstats[i] = new(DiskStats) 70 } 71 // Define the various metrics to collect 72 memAllocs := GetOrRegisterMeter("system/memory/allocs", DefaultRegistry) 73 memFrees := GetOrRegisterMeter("system/memory/frees", DefaultRegistry) 74 memInuse := GetOrRegisterMeter("system/memory/inuse", DefaultRegistry) 75 memPauses := GetOrRegisterMeter("system/memory/pauses", DefaultRegistry) 76 77 var diskReads, diskReadBytes, diskWrites, diskWriteBytes Meter 78 var diskReadBytesCounter, diskWriteBytesCounter Counter 79 if err := ReadDiskStats(diskstats[0]); err == nil { 80 diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry) 81 diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry) 82 diskReadBytesCounter = GetOrRegisterCounter("system/disk/readbytes", DefaultRegistry) 83 diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry) 84 diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry) 85 diskWriteBytesCounter = GetOrRegisterCounter("system/disk/writebytes", DefaultRegistry) 86 } else { 87 log.Debug("Failed to read disk metrics", "err", err) 88 } 89 // Iterate loading the different stats and updating the meters 90 for i := 1; ; i++ { 91 location1 := i % 2 92 location2 := (i - 1) % 2 93 94 runtime.ReadMemStats(memstats[location1]) 95 memAllocs.Mark(int64(memstats[location1].Mallocs - memstats[location2].Mallocs)) 96 memFrees.Mark(int64(memstats[location1].Frees - memstats[location2].Frees)) 97 memInuse.Mark(int64(memstats[location1].Alloc - memstats[location2].Alloc)) 98 memPauses.Mark(int64(memstats[location1].PauseTotalNs - memstats[location2].PauseTotalNs)) 99 100 if ReadDiskStats(diskstats[location1]) == nil { 101 diskReads.Mark(diskstats[location1].ReadCount - diskstats[location2].ReadCount) 102 diskReadBytes.Mark(diskstats[location1].ReadBytes - diskstats[location2].ReadBytes) 103 diskWrites.Mark(diskstats[location1].WriteCount - diskstats[location2].WriteCount) 104 diskWriteBytes.Mark(diskstats[location1].WriteBytes - diskstats[location2].WriteBytes) 105 106 diskReadBytesCounter.Inc(diskstats[location1].ReadBytes - diskstats[location2].ReadBytes) 107 diskWriteBytesCounter.Inc(diskstats[location1].WriteBytes - diskstats[location2].WriteBytes) 108 } 109 time.Sleep(refresh) 110 } 111 }