github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/metrics/metrics.go (about) 1 // Go port of Coda Hale's Metrics library 2 // <https://github.com/rcrowley/go-metrics> 3 // Coda Hale's original work: <https://github.com/codahale/metrics> 4 package metrics 5 6 import ( 7 "os" 8 "runtime" 9 "strings" 10 "time" 11 12 "github.com/quickchainproject/quickchain/log" 13 ) 14 15 // Enabled is checked by the constructor functions for all of the 16 // standard metrics. If it is true, the metric returned is a stub. 17 // 18 // This global kill-switch helps quantify the observer effect and makes 19 // for less cluttered pprof profiles. 20 var Enabled bool = false 21 22 // MetricsEnabledFlag is the CLI flag name to use to enable metrics collections. 23 const MetricsEnabledFlag = "metrics" 24 const DashboardEnabledFlag = "dashboard" 25 26 // Init enables or disables the metrics system. Since we need this to run before 27 // any other code gets to create meters and timers, we'll actually do an ugly hack 28 // and peek into the command line args for the metrics flag. 29 func init() { 30 for _, arg := range os.Args { 31 if flag := strings.TrimLeft(arg, "-"); flag == MetricsEnabledFlag || flag == DashboardEnabledFlag { 32 log.Info("Enabling metrics collection") 33 Enabled = true 34 } 35 } 36 } 37 38 // CollectProcessMetrics periodically collects various metrics about the running 39 // process. 40 func CollectProcessMetrics(refresh time.Duration) { 41 // Short circuit if the metrics system is disabled 42 if !Enabled { 43 return 44 } 45 // Create the various data collectors 46 memstats := make([]*runtime.MemStats, 2) 47 diskstats := make([]*DiskStats, 2) 48 for i := 0; i < len(memstats); i++ { 49 memstats[i] = new(runtime.MemStats) 50 diskstats[i] = new(DiskStats) 51 } 52 // Define the various metrics to collect 53 memAllocs := GetOrRegisterMeter("system/memory/allocs", DefaultRegistry) 54 memFrees := GetOrRegisterMeter("system/memory/frees", DefaultRegistry) 55 memInuse := GetOrRegisterMeter("system/memory/inuse", DefaultRegistry) 56 memPauses := GetOrRegisterMeter("system/memory/pauses", DefaultRegistry) 57 58 var diskReads, diskReadBytes, diskWrites, diskWriteBytes Meter 59 if err := ReadDiskStats(diskstats[0]); err == nil { 60 diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry) 61 diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry) 62 diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry) 63 diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry) 64 } else { 65 log.Debug("Failed to read disk metrics", "err", err) 66 } 67 // Iterate loading the different stats and updating the meters 68 for i := 1; ; i++ { 69 runtime.ReadMemStats(memstats[i%2]) 70 memAllocs.Mark(int64(memstats[i%2].Mallocs - memstats[(i-1)%2].Mallocs)) 71 memFrees.Mark(int64(memstats[i%2].Frees - memstats[(i-1)%2].Frees)) 72 memInuse.Mark(int64(memstats[i%2].Alloc - memstats[(i-1)%2].Alloc)) 73 memPauses.Mark(int64(memstats[i%2].PauseTotalNs - memstats[(i-1)%2].PauseTotalNs)) 74 75 if ReadDiskStats(diskstats[i%2]) == nil { 76 diskReads.Mark(diskstats[i%2].ReadCount - diskstats[(i-1)%2].ReadCount) 77 diskReadBytes.Mark(diskstats[i%2].ReadBytes - diskstats[(i-1)%2].ReadBytes) 78 diskWrites.Mark(diskstats[i%2].WriteCount - diskstats[(i-1)%2].WriteCount) 79 diskWriteBytes.Mark(diskstats[i%2].WriteBytes - diskstats[(i-1)%2].WriteBytes) 80 } 81 time.Sleep(refresh) 82 } 83 }