github.com/anthdm/go-ethereum@v1.8.4-0.20180412101906-60516c83b011/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 bool = false 23 24 // MetricsEnabledFlag is the CLI flag name to use to enable metrics collections. 25 const MetricsEnabledFlag = "metrics" 26 const DashboardEnabledFlag = "dashboard" 27 28 // Init enables or disables the metrics system. Since we need this to run before 29 // any other code gets to create meters and timers, we'll actually do an ugly hack 30 // and peek into the command line args for the metrics flag. 31 func init() { 32 for _, arg := range os.Args { 33 if flag := strings.TrimLeft(arg, "-"); flag == MetricsEnabledFlag || flag == DashboardEnabledFlag { 34 log.Info("Enabling metrics collection") 35 Enabled = true 36 } 37 } 38 } 39 40 // CollectProcessMetrics periodically collects various metrics about the running 41 // process. 42 func CollectProcessMetrics(refresh time.Duration) { 43 // Short circuit if the metrics system is disabled 44 if !Enabled { 45 return 46 } 47 // Create the various data collectors 48 memstats := make([]*runtime.MemStats, 2) 49 diskstats := make([]*DiskStats, 2) 50 for i := 0; i < len(memstats); i++ { 51 memstats[i] = new(runtime.MemStats) 52 diskstats[i] = new(DiskStats) 53 } 54 // Define the various metrics to collect 55 memAllocs := GetOrRegisterMeter("system/memory/allocs", DefaultRegistry) 56 memFrees := GetOrRegisterMeter("system/memory/frees", DefaultRegistry) 57 memInuse := GetOrRegisterMeter("system/memory/inuse", DefaultRegistry) 58 memPauses := GetOrRegisterMeter("system/memory/pauses", DefaultRegistry) 59 60 var diskReads, diskReadBytes, diskWrites, diskWriteBytes Meter 61 if err := ReadDiskStats(diskstats[0]); err == nil { 62 diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry) 63 diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry) 64 diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry) 65 diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry) 66 } else { 67 log.Debug("Failed to read disk metrics", "err", err) 68 } 69 // Iterate loading the different stats and updating the meters 70 for i := 1; ; i++ { 71 runtime.ReadMemStats(memstats[i%2]) 72 memAllocs.Mark(int64(memstats[i%2].Mallocs - memstats[(i-1)%2].Mallocs)) 73 memFrees.Mark(int64(memstats[i%2].Frees - memstats[(i-1)%2].Frees)) 74 memInuse.Mark(int64(memstats[i%2].Alloc - memstats[(i-1)%2].Alloc)) 75 memPauses.Mark(int64(memstats[i%2].PauseTotalNs - memstats[(i-1)%2].PauseTotalNs)) 76 77 if ReadDiskStats(diskstats[i%2]) == nil { 78 diskReads.Mark(diskstats[i%2].ReadCount - diskstats[(i-1)%2].ReadCount) 79 diskReadBytes.Mark(diskstats[i%2].ReadBytes - diskstats[(i-1)%2].ReadBytes) 80 diskWrites.Mark(diskstats[i%2].WriteCount - diskstats[(i-1)%2].WriteCount) 81 diskWriteBytes.Mark(diskstats[i%2].WriteBytes - diskstats[(i-1)%2].WriteBytes) 82 } 83 time.Sleep(refresh) 84 } 85 }