github.com/zjj1991/quorum@v0.0.0-20190524123704-ae4b0a1e1a19/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 var diskReadBytesCounter, diskWriteBytesCounter Counter 62 if err := ReadDiskStats(diskstats[0]); err == nil { 63 diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry) 64 diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry) 65 diskReadBytesCounter = GetOrRegisterCounter("system/disk/readbytes", DefaultRegistry) 66 diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry) 67 diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry) 68 diskWriteBytesCounter = GetOrRegisterCounter("system/disk/writebytes", DefaultRegistry) 69 } else { 70 log.Debug("Failed to read disk metrics", "err", err) 71 } 72 // Iterate loading the different stats and updating the meters 73 for i := 1; ; i++ { 74 location1 := i % 2 75 location2 := (i - 1) % 2 76 77 runtime.ReadMemStats(memstats[location1]) 78 memAllocs.Mark(int64(memstats[location1].Mallocs - memstats[location2].Mallocs)) 79 memFrees.Mark(int64(memstats[location1].Frees - memstats[location2].Frees)) 80 memInuse.Mark(int64(memstats[location1].Alloc - memstats[location2].Alloc)) 81 memPauses.Mark(int64(memstats[location1].PauseTotalNs - memstats[location2].PauseTotalNs)) 82 83 if ReadDiskStats(diskstats[location1]) == nil { 84 diskReads.Mark(diskstats[location1].ReadCount - diskstats[location2].ReadCount) 85 diskReadBytes.Mark(diskstats[location1].ReadBytes - diskstats[location2].ReadBytes) 86 diskWrites.Mark(diskstats[location1].WriteCount - diskstats[location2].WriteCount) 87 diskWriteBytes.Mark(diskstats[location1].WriteBytes - diskstats[location2].WriteBytes) 88 89 diskReadBytesCounter.Inc(diskstats[location1].ReadBytes - diskstats[location2].ReadBytes) 90 diskWriteBytesCounter.Inc(diskstats[location1].WriteBytes - diskstats[location2].WriteBytes) 91 } 92 time.Sleep(refresh) 93 } 94 }